Service过往总结--后台服务,前台服务,扩展Binder,Messenger

Service过往总结


关于Service,相信都是用的熟的不能再熟了,也确实没什么好说的,那就总结一下Service的使用过往吧。

去google看了一下,介绍的非常好了,那就直接拿过来。

  • Service 是一个可以在后台执行长时间运行操作而不提供用户界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。 例如,服务可以处理网络事务、播放音乐,执行文件 I/O 或与ContentProvider交互,而所有这一切均可在后台进行。

  • 启动方式:

    1. startService(),一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响,所以要记得 stopService()或者stopSelf();
    2. bindService(), 仅当与另一个应用组件绑定时,绑定服务才会运行。 多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁,客户端通过 IBinder 接口与服务进行通信。客户端可以通过调用 unbindService() 关闭连接,当所有绑定全部取消后,系统即会销毁该服务。
    3. 除了上面单独使用之外,还允许组合使用,也就是说,它既可以是启动服务(以无限期运行),也允许绑定。问题只是在于是否实现了一组回调方法:onStartCommand()(允许组件启动服务)和 onBind()(允许绑定服务)。
  • 注意:Service是在UIThread中运行的,如果要执行一些耗时的工作,要在Service内新开thread来完成。

  • 自定义Service的时候,重点关注的几个方法

    1. onStartCommand(),如果通过startService()启动Service,将会执行此方法,也可以用来配置Service的策略(4种可选,START_STICKY_COMPATIBILITY,START_STICKY,START_NOT_STICKY,START_REDELIVER_INTENT,各自的效果请参考IntentService源码分析),一般startService()和StopService()(处理单个onStartCommand()请求时)或者stopSelf(int)(处理多个onStartCommand(int)请求时)成对使用。
    2. onBind(),通过调用 bindService() 与服务绑定(例如执行 RPC)时,系统将调用此方法。在此方法的实现中,您必须通过返回 IBinder 提供一个接口,供客户端用来与服务进行通信。请务必实现此方法,但如果您并不希望允许绑定,则应返回 null。
    3. onCreate(),不论是什么方式启动,如果Service没有运行都会调用一次
    4. onDestroy(),清理所有资源,如线程、注册的侦听器、接收器等
  • 清单文件声明:
 <!-- exported=false表示app私有此Service,true表示可以被其它app调用交互-->
        <!-- enabled=true表示Service能够被实例化,对于被启用的服务,
        <application>和<service>元素的enabled属性都必须是true(默认值都是true)-->
        <!-- android:process 这个属性用于设定服务所运行的进程名称,
            如果这个属性值用“:”开头,则在需要的时候系统会创建一个新的,应用程序私有的进程,并且该服务也会运行在这个进程中。
            如果这个属性值用小写字母开头,那该服务就会运行在以这个属性值命名的全局进程中,它提供了使其工作的权限。
            这样就允许不同的应用程序组件来共享这个进程,从而降低资源的使用。-->
        <service 
            android:name=".IntentSerivceDemo" 
            android:exported="false" 
            android:enabled="true"
            android:process="remote"/>

为了确保应用的安全性,请始终使用显式 Intent 启动或绑定 Service,且不要为服务声明 Intent 过滤器。 启动哪个服务存在一定的不确定性,而如果对这种不确定性的考量非常有必要,则可为服务提供 Intent 过滤器并从 Intent 中排除相应的组件名称,但随后必须使用 setPackage() 方法设置 Intent 的软件包,这样可以充分消除目标服务的不确定性(5.0以后有这个要求)。

注意:如果您希望同时执行多个请求,则可为每个请求创建一个新线程,然后立即运行这些线程,需要自定义Service,如果不是多个请求的情况,建议使用IntentService。

  • 前台Service
    前台服务被认为是用户主动意识到的一种服务因此在内存不足时,系统也不会考虑将其终止。前台服务必须为状态栏提供通知,放在“正在进行”标题下方,这意味着除非服务停止或从前台移除,否则不能清除通知。
    例如,应该将通过服务播放音乐的音乐播放器设置为在前台运行,这是因为用户明确意识到其操作。状态栏中的通知可能表示正在播放的歌曲,并允许用户启动 Activity来与音乐播放器进行交互。要请求让服务运行于前台,请调用 startForeground(),如下图中,最上面这个就是一个前台Service
    foreground.png-34.8kB

实现:要请求让服务运行于前台,请调用 startForeground()。此方法采用两个参数:唯一标识通知的整型数和状态栏的 Notification。看一下前台Service实现Demo:

/**
 * 
 *主要实现: 
 * 1 在Service的onCreate()中调用startForeground() 
 * 2 在Service的onDestroy()中调用stopForeground() 
 * 3 一个Notification常驻在状态栏,当后台数据变化时需要 
 *   更新该通知中的显示内容.在该示例中只用了一个简单的 
 *   系统自带Notification来演示,实际项目中多半会用到 
 *   自定义的Notification涉及到RemoteView. 
 *  
 *  
 *前台服务的特点: 
 * 1 可尽量避免系统内容不足的时候被系统回收 
 * 2 它会有一个图标一直在状态栏显示(直到进程结束才会消失),拉下状态栏后可见更多信息. 
 *   比如有的天气App就采用了该前台服务来实现. 
 * 
 * */
@SuppressLint("NewApi")
public class BookService extends Service {

    private String[] names = new String[] { "小明", "小王", "小杨", "小李", "小强" };
    IQueryImpl mBinder ;
    private String result = null;
    private Context mContext;
    private Builder mBuilder;
    private PendingIntent mPendingIntent;
    private Notification mNotification;
    private NotificationManager mNotificationManager;
    private final int NOTIFICATION_ID = 9527;

    // 暴露给客户端
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("on bind....");
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mBinder = new IQueryImpl();
        mContext = this;
         //准备Notification  
        initNotification(mContext);  
        //开启前台服务  
        startForeground(NOTIFICATION_ID, mNotification);  
    }

    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("on unbind.....");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //终止前台服务
        stopForeground(true);
         System.out.println("在onDestroy()中---> stopForeground()");  
    }

    class IQueryImpl extends Binder implements IQueryInterface {

        @Override
        public String queryByNumber(int number) {

            return query(number);
        }

        // 服务内部的方法
        public String query(int i) {
            if (i > 0 && i < 6) {
                result = names[i - 1];
                // 更新通知
                updateNotification(result);
                return result;
            }
            return "查询错误,请再次输入";
        }

    }

     /** 
     * 发送通知 
     */  
    private void initNotification(Context context){  
        Intent intent=new Intent(mContext, BookActivity.class);  
        mPendingIntent=PendingIntent.getActivity(mContext, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);  
        mNotificationManager=(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);  
        mBuilder=new Builder(mContext);  
        //通知产生的时间  
        mBuilder.setWhen(System.currentTimeMillis());  
        //通知首次出现在通知栏时的提示文字  
        mBuilder.setTicker("Ticker");  
        mBuilder.setContentTitle("ContentTitle");  
        mBuilder.setContentInfo("ContentInfo");  
        mBuilder.setContentText("ContentText");  
        mBuilder.setContentIntent(mPendingIntent);  
        //通知的优先级  
        mBuilder.setPriority(Notification.PRIORITY_DEFAULT);  
        //设置通知的图标.必须要有这句否则通知不显示!!!  
        mBuilder.setSmallIcon(R.drawable.ic_launcher);  
        //为通知添加声音,闪灯和振动效果等效果  
        mBuilder.setDefaults(Notification.DEFAULT_VIBRATE);  
        //设置通知是否为一个正在进行的通知.后台任务时常使用true  
        mBuilder.setOngoing(false);  

        mNotification=mBuilder.build();  
        //通知被点击后自动消失  
        mNotification.flags = Notification.FLAG_AUTO_CANCEL;  
        mNotificationManager.notify(NOTIFICATION_ID, mNotification);  
    }  

    /** 
     * 更新通知 
     */  
    private void updateNotification(String result){  
        mBuilder.setContentTitle("Title");  
        mBuilder.setContentInfo("Info");  
        mBuilder.setContentText(result);  
        mNotification=mBuilder.build();  
        mNotification.flags = Notification.FLAG_AUTO_CANCEL;  
        mNotificationManager.notify(NOTIFICATION_ID, mNotification);  
    }  


}

//acitivity

public class BookActivity extends Activity {

    TextView mNumberTextView;
    TextView mResultTextView;
    Button mSearchButton;
    IQueryInterface mBinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setAction("com.example.aidl.BookService");
        intent.setPackage("com.example.aidl");
        bindService(intent, con, BIND_AUTO_CREATE);

        mNumberTextView = (TextView) findViewById(R.id.numberEditText);
        mResultTextView = (TextView) findViewById(R.id.resultTextView);
        mSearchButton = (Button) findViewById(R.id.searchButton);
        mSearchButton.setOnClickListener(new ButtonOnClickListener());

    }

    private class ButtonOnClickListener implements OnClickListener {
        public void onClick(View v) {
            String number = mNumberTextView.getText().toString();
            String result = mBinder.queryByNumber(Integer.valueOf(number));
            mResultTextView.setText(result);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(con);
    }

    ServiceConnection con = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            System.out.println("on disconneted....");
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBinder = (IQueryInterface) service;
        }
    };

}

看下效果图,前台服务的通知跟服务同生死
这里写图片描述

说了这么多,来张图,直观感受一下Service生命周期
此处输入图片的描述

  • bindService使用
    客户端可通过调用 bindService() 绑定到服务。调用时,它必须提供 ServiceConnection 的实现,后者会监控与服务的连接。bindService() 方法会立即无值返回,但当 Android 系统创建客户端与服务之间的连接时,会对 ServiceConnection 调用 onServiceConnected(),向客户端传递用来与服务通信的 IBinder。
    多个客户端可同时连接到一个服务。不过,只有在第一个客户端绑定时,系统才会调用服务的 onBind() 方法来检索 IBinder。系统随后无需再次调用 onBind(),便可将同一 IBinder 传递至任何其他绑定的客户端。
    当最后一个客户端取消与服务的绑定时,系统会将服务销毁(除非 startService() 也启动了该服务)。

  • 创建绑定服务
    创建提供绑定的服务时,您必须提供 IBinder,用以提供客户端用来与服务进行交互的编程接口。 您可以通过三种方法定义接口:

    1. 扩展 Binder 类
      如果服务是供您的自有应用专用,并且在与客户端相同的进程中运行(常见情况),则应通过扩展 Binder 类并从 onBind() 返回它的一个实例来创建接口。客户端收到 Binder 后,可利用它直接访问 Binder 实现中乃至 Service 中可用的公共方法。
      如果服务只是您的自有应用的后台工作线程(即不需要跨进程),则优先采用这种方法。 以这种方式创建接口的唯一原因是,您的服务不被其他应用或不同的进程占用。

    2. 使用 Messenger
      如需让接口跨不同的进程工作,则可使用 Messenger 为服务创建接口。服务可以这种方式定义对应于不同类型 Message 对象的 Handler。此 Handler 是 Messenger 的基础,后者随后可与客户端分享一个 IBinder,从而让客户端能利用 Message 对象向服务发送命令。此外,客户端还可定义自有 Messenger,以便服务回传消息。
      这是执行进程间通信 (IPC) 的最简单方法,因为 Messenger 会在单一线程中创建包含所有请求的队列,这样您就不必对服务进行线程安全设计。

    3. 使用 AIDL
      AIDL(Android 接口定义语言)执行所有将对象分解成原语的工作,操作系统可以识别这些原语并将它们编组到各进程中,以执行 IPC。 之前采用 Messenger 的方法实际上是以 AIDL 作为其底层结构。 如上所述,Messenger 会在单一线程中创建包含所有客户端请求的队列,以便服务一次接收一个请求。 不过,如果您想让服务同时处理多个请求,则可直接使用 AIDL。 在此情况下,您的服务必须具备多线程处理能力,并采用线程安全式设计。
      如需直接使用 AIDL,您必须创建一个定义编程接口的 .aidl 文件。Android SDK 工具利用该文件生成一个实现接口并处理 IPC 的抽象类,您随后可在服务内对其进行扩展。

    注:大多数应用“都不会”使用 AIDL 来创建绑定服务,因为它可能要求具备多线程处理能力,并可能导致实现的复杂性增加。因此,AIDL 并不适合大多数应用,本文也不会阐述如何将其用于您的服务。

那么多文字描述,是不是有点不想看,好,咱们上代码


//1,Binder类创建Service
/** 
* 服务端总结: 
* 1 自定义服务类ServiceSubclass继承自Service 
* 2 写一个自定义的内部类BinderSubclass实现了业务接口,且继承自Binder 
* 3 重写Service的public IBinder onBind(Intent intent)方法,返回一个IBinder对象. 
*   即这里的BinderSubclass类对象 
*   这里的Binder在连接建立后,会在ServiceConnection的onServiceConnected(ComponentName name, IBinder service)中返回
*/  

public interface QueryInterface {
    String queryByNumber(int number);
}

public class ServiceSubclass extends Service {

    private String[] names = {"小明", "小王", "小杨", "小李", "小强"};

    BinderSubclass mBinder;


    @Override
    public void onCreate() {
        super.onCreate();
        mBinder = new BinderSubclass();
        System.out.println("onCreate.....");
    }



    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("onDestroy.....");
    }



    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("onStartCommand.....");
        return super.onStartCommand(intent, flags, startId);
    }



    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("onUnbind.....");
        return super.onUnbind(intent);
    }



    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("onBind.....");
        return mBinder;
    }

    private final class BinderSubclass extends Binder implements QueryInterface{

        @Override
        public String queryByNumber(int number) {

            return query(number);
        }

         //服务内部的方法  
        public String query(int i) {  
            if (i > 0 && i < names.length) {  
                return names[i - 1];  
            }  
            return "查询错误,请再次输入";  
        }  

    }




}
//2,实现ServiceConnection接口,
public class ServiceConnectionImpl implements ServiceConnection {
    private QueryInterface mBinder;

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //接受Service传来的IBinder对象service
        setmBinder((QueryInterface) service);
        System.out.println("service connected....");
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        setmBinder(null);
        System.out.println("service disconnected....");
    }

    public QueryInterface getmBinder() {
        return mBinder;
    }

    public void setmBinder(QueryInterface mBinder) {
        this.mBinder = mBinder;
    }


}

//3,Activity绑定Service,调用Service方法
public class ServiceActivity extends Activity {
    ServiceConnectionImpl mServiceConnectionImpl;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mServiceConnectionImpl = new ServiceConnectionImpl();
        //绑定Service
        Intent intent = new Intent(this,ServiceSubclass.class);
        bindService(intent, mServiceConnectionImpl, BIND_AUTO_CREATE);
        findViewById(R.id.btn).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String name ="";
                if( mServiceConnectionImpl.getmBinder() != null){
                    name = mServiceConnectionImpl.getmBinder().queryByNumber(1);
                }

                System.out.println("name:"+name);
            }
        });
    }

    @Override
    protected void onDestroy() {
        //解除绑定
        unbindService(mServiceConnectionImpl);
        super.onDestroy();
    }
}

看一下打印结果

11-30 15:11:44.260 3110-3110/? I/System.out: onCreate.....
11-30 15:11:44.260 3110-3110/com.charles_lun.db I/System.out: onBind.....
11-30 15:11:44.452 3110-3110/com.charles_lun.db I/System.out: service connected....
11-30 15:12:06.908 3110-3110/com.charles_lun.db I/System.out: name:小明
11-30 15:12:13.200 3110-3110/com.charles_lun.db I/System.out: name:小王
11-30 15:12:28.120 3110-3110/com.charles_lun.db I/System.out: onUnbind.....
11-30 15:12:28.120 3110-3110/com.charles_lun.db I/System.out: onDestroy.....

onCreate(),onBind()都只执行一次,解绑回调onUnbind();

再来看一个Messenger创建服务的demo

/**
1. 服务实现一个 Handler,由其接收来自客户端的每个调用的回调
2. Handler 用于创建 Messenger 对象(对 Handler 的引用)
3. Messenger 创建一个 IBinder,服务通过 onBind() 使其返回客户端
客户端使用 IBinder 将 Messenger(引用服务的 Handler)实例化,然后使用后者将 Message 对象发送给服务
4. 服务在其 Handler 中(具体地讲,是在 handleMessage() 方法中)接收每个 Message。
这样,客户端并没有调用服务的“方法”。而客户端传递的“消息”(Message 对象)是服务在其 Handler 中接收的。
*/

public class MessengerService extends Service {

    static final int MSG_SAY_HELLO = 1;

    @SuppressLint("HandlerLeak")
    class InComingHandler extends Handler{

        @Override
        public void handleMessage(Message msg) {
            switch(msg.what){
            case MSG_SAY_HELLO:
                System.out.println(msg.getData().getString("key"));
                //然后给客户端回复一句话
                Message mess = Message.obtain();
                mess.what = MSG_SAY_HELLO;
                Bundle bundle = mess.getData();
                bundle.putString("key","我是服务")
                mess.setData(bundle);

                Messenger msger = msg.replyTo;

                try{
                msger.send(mess);
                }catch(Exception e){
                }

                break;

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

    }

    final Messenger mMessenger = new Messenger(new InComingHandler());

    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("on bind...");
        return mMessenger.getBinder();
    }

    @Override
    public void onCreate() {
        System.out.println("on create...");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("on start command...");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("on unbind...");
        return super.onUnbind(intent);
    }
}

//2,实现ServiceConnection接口,接受Service传来的IBinder
//3,绑定服务
public class MessengerActivity extends Activity {

    Messenger mMessenger;
    ServiceConnectionIm mServiceConnectionImpl;

        static class MessengerHandler extends Handler{
    @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            System.out.println(msg.what+","+msg.getData().getString("key"));
        }

    }

    Messenger getMessenger;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getMessenger = new Messenger(new MessengerHandler());
        mServiceConnectionImpl = new ServiceConnectionIm();
        Intent intent = new Intent(this,MessengerService.class);
        bindService(intent, mServiceConnectionImpl, BIND_AUTO_CREATE);


        findViewById(R.id.btn).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                sendMsg(1,"wo qu ni mei");
            }
        });

findViewById(R.id.btn2).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                sendMsg(1, "what the fuck");
            }
        });

    }


    void sendMsg(int what,String msg){
        if(mMessenger==null){
            return;
        }
        Message m = Message.obtain();
        m.what = what;
        Bundle bundle = new Bundle();
        bundle.putString("key", msg);
        m.setData(bundle);
        //接受服务端的回复
        m.replyTo = getMessenger;
        try {
            mMessenger.send(m);
        } catch (RemoteException e) {
            e.printStackTrace();
            System.out.println(e.toString());
        }
    }


    @Override
    protected void onDestroy() {
        unbindService(mServiceConnectionImpl);
        System.out.println("on destory....");
        super.onDestroy();
    }


    private final class ServiceConnectionIm implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            System.out.println("on service connected...");
            mMessenger = new Messenger(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            System.out.println("on service disconnected...");
            mMessenger = null;
        }
    }
}

在看一下打印结果:

11-30 16:20:30.192 4855-4855/? I/System.out: on create...
11-30 16:20:30.192 4855-4855/? I/System.out: on bind...
11-30 16:20:30.288 4823-4823/? I/System.out: on service connected...
11-30 16:20:40.076 4855-4855/? I/System.out: wo qu ni mei
11-30 16:20:40.076 4855-4855/? I/System.out: 1,我是服务
11-30 16:20:43.208 4855-4855/? I/System.out: what the fuck
11-30 16:20:40.076 4855-4855/? I/System.out: 1,我是服务
11-30 16:20:47.532 4855-4855/? I/System.out: on unbind...
11-30 16:20:47.532 4823-4823/? I/System.out: on destory....

符合预期结果,客户端和服务实现了双向交互,

用一个图形来直观感受下Messenger工作原理,
这里写图片描述

使用bindService时,要注意一下几点:
- 您应该始终捕获 DeadObjectException 异常,它们是在连接中断时引发的。这是远程方法引发的唯一异常。
- 对象是跨进程计数的引用。
- 您通常应该在客户端生命周期的匹配引入 (bring-up) 和退出 (tear-down) 时刻期间配对绑定和取消绑定。 例如:
(1). 如果您只需要在 Activity 可见时与服务交互,则应在 onStart() 期间绑定,在 onStop() 期间取消绑定。
(2).如果您希望 Activity 在后台停止运行状态下仍可接收响应,则可在 onCreate() 期间绑定,在 onDestroy() 期间取消绑定。请注意,这意味着您的 Activity 在其整个运行过程中(甚至包括后台运行期间)都需要使用服务,因此如果服务位于其他进程内,那么当您提高该进程的权重时,系统终止该进程的可能性会增加。
注:通常情况下,切勿在 Activity 的 onResume() 和 onPause() 期间绑定和取消绑定,因为每一次生命周期转换都会发生这些回调,您应该使发生在这些转换期间的处理保持在最低水平。此外,如果您的应用内的多个 Activity 绑定到同一服务,并且其中两个 Activity 之间发生了转换,则如果当前 Activity 在下一个 Activity 绑定(恢复期间)之前取消绑定(暂停期间),系统可能会销毁服务并重建服务。

  • 我们来看一下混合启动绑定Service的生命周期管理:
    当服务与所有客户端之间的绑定全部取消时,Android 系统便会销毁服务(除非还使用 onStartCommand() 启动了该服务)。因此,如果您的服务是纯粹的绑定服务,则无需对其生命周期进行管理 — Android 系统会根据它是否绑定到任何客户端代您管理。
    不过,如果您选择实现 onStartCommand() 回调方法,则您必须显式停止服务,因为系统现在已将服务视为已启动。在此情况下,服务将一直运行到其通过 stopSelf() 自行停止,或其他组件调用 stopService() 为止,无论其是否绑定到任何客户端。

    此外,如果您的服务已启动并接受绑定,则当系统调用您的 onUnbind() 方法时,如果您想在客户端下一次绑定到服务时接收 onRebind() 调用,则可选择返回 true。onRebind() 返回空值,但客户端仍在其 onServiceConnected() 回调中接收 IBinder。下文图 1 说明了这种生命周期的逻辑。
    此处输入图片的描述

AIDL的demo就先不写了,抽空直接写一篇专门的AIDL,以上就是整理的Service过往,如果有错误的地方,欢迎大大们指正

参考:
goole Service

猜你喜欢

转载自blog.csdn.net/baidu_17508977/article/details/53410367
今日推荐