Android Service

2020-06-07  本文已影响0人  二旬一月

生命周期

service生命周期.png

默认情况下同进程使用

  1. 通过StartService启动Service
    startService() --> onCreate --> onStartCommand() --> stopService --> onDestroy()
  1. 通过bindService启动Service
    bindService() --> onCreate() --> onBind() --> unbindService() --> onUnbind() --> onDestroy()

注意事项

 <service android:name=".myservice"
            android:enabled="true"
            android:exported="true"
            android:icon="@drawable/background_blue"
            android:label="string"
            android:process="string"
            android:permission="string">
 </service>

android:exported 表示是否允许除了当前程序之外的其他程序访问这个服务
android:enabled 表示是否启用这个服务
android:permission 是权限声明
android:process 是否需要在单独的进程中运行,当设置为android:process=”:remote”时,代表Service在单独的进程中运行。
android:isolatedProcess 设置 true 意味着,服务会在一个特殊的进程下运行,这个进程与系统其他进程分开且没有自己的权限。与其通信的唯一途径是通过服务的API(bind and start)。

代码示例

startService 模式

public class StartService extends Service {

    private static final String TAG = "StartService";
    private boolean running = false;

    public StartService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG,"==StartService is start with onCreate==");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG,"==StartService is onStart with onStartCommand==");
        running = true;
        new Thread(){
            @Override
            public void run() {
                super.run();
                while (running){
                    Log.e(TAG,"StartService is running");
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG,"==StartService is stop with onDestroy==");
        running = false;
    }
}

启动和停止服务

findViewById(R.id.buttonstart).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //启动服务
                startService(new Intent(MainActivity.this,StartService.class));
            }
        });

findViewById(R.id.buttonstop).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //关闭服务
                stopService(new Intent(MainActivity.this,StartService.class));
            }
        });

bindService模式

public class BindService extends Service {

    private static  final String TAG = "BindService";
    private long beginTime;

    //2.初始化Binder对象
    private MyBinder binder = new MyBinder();

    //1.创建Binder类,并且提供返回该服务的方法,client 可以通过Binder获取Service实例
    public class MyBinder extends Binder{
        public BindService getService(){
            return BindService.this;
        }
    }
    //3.将binder返回给client
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG,"BindService is onBind");
        return binder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG,"BindService is onUnbind");
        return super.onUnbind(intent);
    }

    public BindService() {
    }


    @Override
    public void onCreate() {
        super.onCreate();
        beginTime = System.currentTimeMillis();
        Log.e(TAG,"BindService is onCreate");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG,"BindService is onDestroy");
//        beginTime = 0;
    }

    public long getRunningTime() throws Exception {
        if (beginTime == 0){
            throw new Exception("BindService is not bind!!");
        }
        return System.currentTimeMillis() - beginTime;
    }

}

绑定和解绑

    private BindService bindService;
    //1. 创建ServiceConnection,用于接收service返回的Binder对象
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e("MainActivity","onServiceConnected");
            //得到Binder对象,并且通过getService()方法获取到service
            BindService.MyBinder myBinder = (BindService.MyBinder)service;
            bindService = myBinder.getService();
        }
        //Android 系统会在与服务的连接意外中断时调用该方法,当客户端取消绑定时不会调用该方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e("MainActivity","onServiceDisconnected");
        }
    };

 findViewById(R.id.buttonbind).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,BindService.class);
                intent.putExtra("name","MainActivity");
                //绑定服务
                bindService(intent,connection,BIND_AUTO_CREATE);
            }
        });

findViewById(R.id.buttonunbind).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //解除绑定
                unbindService(connection);
            }
        });
//完成绑定后,便可以在client中使用服务中的方法了。
long getServiceRunningTime() throws Exception {
        return bindService.getRunningTime();
    }

跨进程使用

简单的使用方式Message

  1. 服务实现一个 Handler,由其接收来自客户端的每个调用的回调
  2. Handler 用于创建 Messenger 对象(对 Handler 的引用)
  3. Messenger 创建一个 IBinder,服务通过 onBind() 使其返回客户端
  4. 客户端使用 IBinder 将 Messenger(引用服务的 Handler)实例化,然后使用Messenger将 Message 对象发送给服务
  5. 服务在其 Handler 中(在 handleMessage() 方法中)接收每个 Message

代码示例

这里 MessengerService 服务是运行在另一个进程的。
<service
            android:name=".MessengerService"
            android:enabled="true"
            android:exported="true"
            android:process=":another"/>
public class MessengerService extends Service {

    private static final String TAG ="MessengerService";

    public MessengerService() {
    }

    // 定义一个内部类集成Hanlder 用于接收client 发送过来的数据
    class MyHanlder extends Handler{
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 1:
                    Log.e(TAG,"message is "+msg.what);
                    break;

                case 2:

                    break;

                default:
                    super.handleMessage(msg);
            }
        }
    }

    // 创建 Messenger ,传入Hanlder 实例对象
    final Messenger mMessenger = new Messenger(new MyHanlder());

    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG,"MessengerService is bind");
        return mMessenger.getBinder();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG,"MessengerService is Create");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG,"MessengerService is Destroy");
    }
}

绑定和通讯代码

private boolean isBind = false;
    private Messenger mMessenger;
    private ServiceConnection connection_messenger = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //通过服务端传递的IBinder对象,创建相应的Messenger,
            //并且通过这个IBinder 进行通讯
            mMessenger = new Messenger(service);
            Log.e("MainActivity","connection_messenger --》 onServiceDisconnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
findViewById(R.id.messenger).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bindService(new Intent(MainActivity.this, MessengerService.class), connection_messenger,
                        BIND_AUTO_CREATE);
                isBind = true;
            }
        });

        findViewById(R.id.sendmsg).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isBind) return;
                // 创建与服务交互的消息实体Message
                Message msg = Message.obtain(null, 1, 0, 0);
                try {
                    //发送消息
                    mMessenger.send(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

        findViewById(R.id.messenger_unbind).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isBind){
                    unbindService(connection_messenger);
                    isBind = false;
                }
            }
        });

注意事项
在Messenger中进行数据传递必须将数据封装到Message中,Message可以传递的信息载体有,what,arg1,arg2,Bundle以及replyTo,至于object字段,对于同一进程中的数据传递确实很实用,但对于进程间的通信,则显得相当尴尬,在android2.2前,object不支持跨进程传输,但即便是android2.2之后也只能传递android系统提供的实现了Parcelable接口的对象,也就是说我们通过自定义实现Parcelable接口的对象无法通过object字段来传递,因此object字段的实用性在跨进程中也变得相当低了。不过所幸我们还有Bundle对象,Bundle可以支持大量的数据类型。

有时候我们可能还需要服务端能回应客户端,这时便需要提供双向消息传递了
示例

    //用于接收服务器返回的信息
    private Messenger mRecevierReplyMsg= new Messenger(new ReceiverReplyMsgHandler());
    private static class ReceiverReplyMsgHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                //接收服务端回复
                case 2:
                    Log.e("MainActivity", "MessengerService 返回数据:"+msg.getData().getString("msg"));
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

发送数据时的修改

findViewById(R.id.sendmsg).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isBind) return;
                //单向
                // 创建与服务交互的消息实体Message
//                Message msg = Message.obtain(null, 1, 0, 0);
//                try {
//                    //发送消息
//                    mMessenger.send(msg);
//                } catch (RemoteException e) {
//                    e.printStackTrace();
//                }

                //双向
                // 创建与服务交互的消息实体Message
                Message msg = Message.obtain(null, 2, 0, 0);
                //把接收服务器端的回复的Messenger通过Message的replyTo参数传递给服务端
                msg.replyTo=mRecevierReplyMsg;
                try {
                    //发送消息
                    mMessenger.send(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

MessengerService 做一下修改

// 定义一个内部类集成Hanlder 用于接收client 发送过来的数据
    class MyHanlder extends Handler{
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 1:
                    Log.e(TAG,"message is "+msg.what);
                    break;

                case 2:
                    Log.e(TAG,"message is "+msg.what);
                    //回复客户端信息,该对象由客户端传递过来
                    Messenger client=msg.replyTo;
                    //获取回复信息的消息实体
                    Message replyMsg=Message.obtain(null,2);
                    Bundle bundle=new Bundle();
                    bundle.putString("msg","返回数据");
                    replyMsg.setData(bundle);
                    //向客户端发送消息
                    try {
                        client.send(replyMsg);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;

                default:
                    super.handleMessage(msg);
            }
        }
    }

通过Messenger 实现服务之间通讯的图解


MessengerService.png
上一篇下一篇

猜你喜欢

热点阅读