zoukankan      html  css  js  c++  java
  • 安卓开发 探究服务

    前言:

      关于安卓开发的笔记,其实基本都是我复现一行代码中的代码,并加上我自己的理解并解说的,也就是自己记录着玩玩的,有问题欢迎评论区指正。

    0x01 简介

    服务service是安卓里面的四大组件之一,它的作用就是可以在应用程序关闭时,还可以继续运行,比如我们平常电脑或手机听歌的时候,我们会先打开

    音乐软件,播放音乐后,切换别的应用,干活去了对吧,但是我们在切换应用的时候,按道理应用这时候是已经挂在后台了,但是音乐还是在正常播放的

    也就是服务是支持应用程序在后台正常运行的手段。

    0x02 安卓多线程编程

    至于为什么先写多线程,一个是书上是这顺序,还有一个原因就是在于服务的干事的地方,基本都在子线程里面干的,而服务并不是自己创建子进程的,

    这需要我们在服务内部代码中去实现的,管他呢,都得学2333

    安卓多线程和java的多线程差不多的,也都是三种方式

    1.继承Thread类,重写run方法,然后创建对应的线程对象,调用start()方法,启动线程

     class OneThread extends Thread{
            public void run()
            {
                Log.d("YenKoc", "重写");
            }
        }
    OneThread one=new OneThread();
    one.start();

    2.实现Runnable接口,重写run方法,创建对应的实例,然后再新建一个Thread对象,将上面的实例传入Thread的构造方法中去,再调用start()

     class OneThread implements Runnable{
            public void run()
            {
    
            }
        }
        OneThread one =new OneThread();
        new Thread(one).start();

    3.匿名类创建子线程的方式

    new Thread(new Runnable(){
            public void run()
            {
    
            }
        }).start()

    这种是是最简单省事的,也是用的多的

    然后在子线程中是无法更新UI的,这里书里也提供了一个简单的案例,我就不提出来了,就是新建一个布局,然后设置一个按钮,一点就新建子线程去改变文本框的内容

    由于子线程中无法更新ui,也就是会出现程序崩溃的情况,这里就提出另一种完美解决安卓子进程更新ui的操作,安卓提供了一套消息处理机制,其实之前在app启动的源码中

    也看到了消息机制looper等,通过发信号的模式去启动的,这是题外话,这块我也好久没看了,又忘了233

    这里通过实例来看

    package com.example.servicetest;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.net.IpSecManager;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import java.nio.BufferUnderflowException;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
        private TextView text;
        public static final int UPDATE_TEXT=1;
        private Handler handler=new Handler(){
            public void handleMessage(Message msg){
                switch (msg.what)
                {
                    case UPDATE_TEXT:
                        text.setText("Nice to meet you");
                        break;
                    default:
                        break;
                }
            }
        }
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Button changeText=(Button)findViewById(R.id.change_text);
            changeText.setOnClickListener(this);
    
        }
        public void onClick(View v)
        {
            switch (v.getId())
            {
                case R.id.change_text:
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Message message=new Message();
                            message.what=1;
                            handler.sendMessage(message);
                        }
                    }).start();
                default:
                    
                            
            }
    
    
        }
    }

    新建一个handler对象,并重写了handlerMessage方法,里面主要是根据消息中的what字段来选择不同的处理方式,

    然后在点击按钮后,实际上是通过创建子进程,然后在子进程中,发送了一个消息给主线程handler,然后由主线

    程来更新ui,这种异步消息处理机制,太酷了233,想当于领导在子线程里面指挥,小弟在主线程里面干活。

    至于原理也挺简单当,看图

     message:字面意思,作为通讯用的

    handler: 用来处理消息的,要重写handleMessage方法

    MessageQueue:消息队列,因为消息有先后顺序的,相当于消息容器,把消息都装到里面

    looper:消息队列的管家,一旦运行会轮询消息队列,看看里面是否有消息,如果有就发送,没有的话就阻塞

    之前使用的runOnUiThread其实就是上面那套的封装,所以很香,所以那里面是可以对ui操作的

    0x02 服务

    终于到服务了。。

    package com.example.servicetest;
    
            import android.app.Service;
            import android.content.Intent;
            import android.os.IBinder;
    
    public class MyService extends Service {
        public MyService() {
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            throw new UnsupportedOperationException("Not yet implemented");
        }
        //服务创建的时候调用
        public void onCreate()
        {
            super.onCreate();
        }
        //服务每次启动时被调用
        public int onStartCommand(Intent intent,int flags,int startId)
        {
            return super.onStartCommand(intent,flags,startId);
        }
        public void onDestroy()
        {
            super.onDestroy();
        }
    
    }

    新建一个service类,然后重写onCreate()方法,onStartCommand()方法(主要逻辑是写到这里),onDestroy()方法,

    2.服务的启动和停止,组件之间的启动都是通过intent对象来启动的

    package com.example.servicetest;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.net.IpSecManager;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    import java.nio.BufferUnderflowException;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
          Button startService=(Button)findViewById(R.id.start_service);
            Button stopService=(Button)findViewById(R.id.stop_service);
            startService.setOnClickListener(this);
            stopService.setOnClickListener(this);
        }
        public void onClick(View v)
        {
            switch (v.getId()) {
                case R.id.start_service:
                    Intent startIntent = new Intent(this, MyService.class);
                    startService(startIntent);
                    break;
                case R.id.stop_service:
                    Intent stopIntent=new Intent(this,MyService.class);
                    stopService(stopIntent);
                    break;
            }
        }
    
    }

    然后在MyService类改下代码

    package com.example.servicetest;
    
            import android.app.Service;
            import android.content.Intent;
            import android.os.IBinder;
            import android.util.Log;
    
    public class MyService extends Service {
        public MyService() {
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            throw new UnsupportedOperationException("Not yet implemented");
        }
        //服务创建的时候调用
        public void onCreate()
        {
            super.onCreate();
            Log.d("MyService", "onCreate executed");
        }
        //服务每次启动时被调用
        public int onStartCommand(Intent intent,int flags,int startId)
        {
            Log.d("MyService", "onStartCommand: executed");
            return super.onStartCommand(intent,flags,startId);
        }
        public void onDestroy()
        {
            super.onDestroy();
            Log.d("MyService", "onDestroy: executed");
        }
    
    }

    3.活动与服务之间的通信,因为之前这种方式都是活动启动完服务之后,就不管不顾了,无法知道服务具体逻辑是什么,也控制不了,所以安卓想让活动和服务紧密一点,所以提出了Binder机制

    未完待续

  • 相关阅读:
    安卓开发_求好评功能
    安卓开发_深入理解Content Provider
    安卓开发_数据存储技术_sqlite
    安卓开发_慕课网_Fragment实现Tab(App主界面)
    安卓开发_数据存储技术_外部存储
    Go语言基础之数组
    Go语言基础之结构体
    Go操作MySQL
    Go语言基础之文件操作
    Go第三方日志库logrus
  • 原文地址:https://www.cnblogs.com/YenKoc/p/13874155.html
Copyright © 2011-2022 走看看