Android Service总结

Service

概念

后台组件,没有界面,进行一些耗时操作

生命周期

startService

startService()--->onCreate()--->onStartCommand()--->stopService()--->onDestory()

bindService

bindService()--->onCreate()--->onBind()--->connection--->onUnbind()--->onDestory()

方法

onBind()

启动状态和绑定状态下都要重写的方法,但是在启动状态下,直接返回null值
当一个组件调用bindService()与服务绑定,系统就调用此方法,在这个方法中,必须返回一个IBinder接口的实现类,供客户端用来与服务进行通信

onStartCommand()

使用startService()请求启动服务时,调用此方法,一旦执行,服务即会启动并可在后台无限期运行,如果自己实现,则需要在工作完成后,通过调用stopSelf()或stopService()来停止

启动方式

startService

Intent intent = new Intent(MainActivity.this,MyService.class);
startService(intent);
stopService(intent);

bindService

拓展Binder类
概念

应用和服务处于同一应用和进程中,不执行任何跨进程编组

实现

bindService()—>onBind()返回binder实例—>onServiceConnected()获取Service实例—>可调用其公共方法

步骤

1.创建BindService服务端(MyService.java),继承自Service并在类中创建一个实现IBinder接口的实例对象(内部类MyBinder),创建公共方法(getCount)以便给客户端调用
2.从onBind()回调方法中返回Binder实例
3.在客户端中,绑定服务bindService(),从onServiceConnected()回调方法接收Binder,即可调用其公共方法(myServie.getCount())

客户端
private ServiceConnection connection = new ServiceConnection(){
    @Override
    public void onServiceConnected(ComponentName name,IBinder service){
        MyService.MyBinder binder = (MyServie.MyBinder) service;
        myService = binder.getService();    
    }
    @Override
    public void onServiceDisconnected(ComponentName name){
        myService = null;    
    }
};

Intent intent = new Intent(MainActivity.this,MyService.class);
case R.id.bind_service:
    bindService(intent);
    break;
case R.id.unbind_service:
    if(myService!=null){
        myService = null;
        unbindService(intent);    
    }
    break;
case R.id.get_data:
    if(myService != null){
        Log.i(TAG,"count is: " + myService.getCount());    
    }else{
        Log.i(TAG,"no connection with service");    
    }
服务端
public MyBinder extends Binder{
    MyService getService(){
        return MyService.this;    
    }
}
private MyBinder binder = new MyBinder();
public IBinder onBind(Intent intent){
    return binder;
}
public int getCount(){
    return count;
}
Messenger

不同进程间通信,使用Messenger服务提供通信接口,使用handler进行消息处理
Context.BIND_AUTO_CREATE与Service.BIND_AUTO_CREATE的区别
没有区别,因为Service.BIND_AUTO_CREATE调用的其实是Context.BIND_AUTO_CREATE

步骤
服务端发送给客户端

1.客户端bindService()绑定服务

bindService(intent,connection,Context.BIND_AUTO_CREATE);

2.创建服务端(MessengerService.java),构建内部类(IncomingHandler)继承自Handler,用来处理客户端发送的消息

class IncomingHandler extends Handler{
    @Override
    public void handleMessage(@NonNUll Message msg){
        switch(msg.what){
            case MSG_SAY_HELLO:
                Log.i(TAG,"Service had received message!");
                break;
            default:
                super.handleMessage(msg);                        
        }    
    }
}

2.实例化Messenger对象,并在onBind()方法中返回给客户端一个Messenger底层的Binder

final Messenger mMessenger = new Messenger(new IncomingHandler());
@Override
@Nullable
public IBinder onBind(Intent intent){
    return mMessenger.getBinder();
}

3.客户端onServiceConnected()回调方法构造出与服务端进行交互的Messenger对象

connection = new ServiceConnection(){
    @Override
    public void onServiceConnected(ComponentName name,IBinder service){
        mService = new Messenger(service);
        mBound = true;    
    }
    @Override
    public void onServiceDisconnected(ComponentName name){
        mService = null;
        mBound = false;
    }
}

4.创建与服务端交互的消息实例Message

public void sayHello(View v){
    if(!mBound) return;
    Message msg = Message.obtain(null,MessengerService.MSG_SAY_HELLO,0,0);
    try{
        mService.send(msg);    
    }catch(RemoteException e){
        e.printStackTrace();    
    }
}

5.模拟不同进程之间通信

<service
    android:name=".Service.MessengerService"
    android:process=":remote"
    />
服务端回应客户端

1.在服务端新建Messenger对象,并采用对应消息的msg.replyTo初始化

Messenger client = msg.replyTo;

2.新建返回的消息Message对象

Message replayMsg = Message.obtain(null,MessengerService.MSG_SAY_HELLO);

3.新建返回的数据Bundle

Bundle bundle = new Bundle();
bundle.putString("replay","I have received message from you!");

4.将bundle和message绑定

replayMsg.setData(bundle);

5.发送消息

try{
    client.send(replayMsg);
}catch(RemoteException e){
    e.printStackTrace();
}

1.一个服务可以绑定多个客户端,但是,系统仅在第一个客户端绑定时调用服务的onBind()方法,此后的绑定,只会返回已存在的IBinder对象
2.不要在onResume和onPause方法中绑定服务和取消绑定,因为生命周期转换调用最频繁

启动状态和绑定状态的转换

先绑定后启动

以绑定状态运行,再以启动状态运行,就会转换为启动状态,即只有在收到停止服务命令(stopSelf/stopService)或内存不足时才会销毁该服务

先启动后绑定

仍然会以启动状态运行

结论

1.启动状态级别比绑定状态高
2.如果服务要执行耗时操作,需要另开线程来完成,因为服务是运行在主线程中,不会创建自己的线程,也不会创建新的进程(除非有指定)

AIDL

待定

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值