有关Service的startService与bindService在各种情形下生命周期的变化

Activity模版:

public class MainActivity extends AppCompatActivity{

    private ServiceConnection connection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            log("onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            log("onServiceDisconnected");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_main);
        log("onCreate");
    }

    public void click1(View view) {
        int id = view.getId();
        switch (id) {
            case R.id.bt_1_1:
                log("click -> startService");
                startService(new Intent(this,MyService.class));
                break;
            case R.id.bt_1_2:
                log("click -> stopService");
                stopService(new Intent(this,MyService.class));
                break;
            case R.id.bt_1_3:
                log("click -> bindService");
                bindService(new Intent(this,MyService.class),connection,BIND_AUTO_CREATE);
                break;
            case R.id.bt_1_4:
                log("click -> unbindService");
                unbindService(connection);
                break;
            case R.id.bt_1_5:
                log("click -> to next activity");
                startActivity(new Intent(this,Main2Activity.class));
                break;
            default:
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        log("onDestroy");
    }

    private void log(String msg) {
        Log.d("TAG-MainActivity", msg);
    }
}

Service设置:

public class MyService extends Service {
    private MyBinder binder = new MyBinder();

    @Override
    public void onCreate() {
        super.onCreate();
        log("onCreate");
    }

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

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        log("onBind");
        return binder;
    }

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

    @Override
    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
        log("bindService");
        return super.bindService(service, conn, flags);
    }

    @Override
    public void unbindService(ServiceConnection conn) {
        super.unbindService(conn);
        log("unbindService");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        log("onDestroy");
    }

    @Override
    public boolean stopService(Intent name) {
        log("onDestroy");
        return super.stopService(name);
    }

    private void log(String msg) {
        Log.d("TAG-MyService", msg);
    }

    static class MyBinder extends Binder {
    }
}

说明:有三个Activity,分别为MainActivity、Main2Activity、Main3Activity,这三个Activity 的实现完全复制于上述模版,只不过Main3Activity中跳转到下一个Activity的点击事件实际的实现。


####接下来,将会对各种情景进行实践,观察Service的生命周期变化。
(说明:红色框代表第一个Activity,即MainActivity,黄色的代表Main2Activity,蓝色代表Main3Activity,箭头向下表示从当前Activity跳转到下一个Activity,箭头向上则表示把当前Activity 推出栈回到上一个Activity,框内的表示当前Activity对同一个Service的操作,空白表示不做任何操作。当然最后都会把第一个Activity推出栈并回到桌面)

#情景:


###1、
有关Service的startService与bindService在各种情形下生命周期的变化_第1张图片

有关Service的startService与bindService在各种情形下生命周期的变化_第2张图片

先有一个Activity startService(跳转到后面当Activity时没有被销毁,只能被压到了栈底),之后有多个Activity bindService,然后跳转带最后一个Activity时,先bindService,然后直接stopService,之后再依次将Activity推出栈,从上面的运行截图可以看到,当Service被stopService,Service没有立即被销毁,然后一直等到了最初bindService的Activity被销毁之后(从日志可以看到先Main2Activity被onDestory然后才是Service被onDestory),Service才被销毁,此时也没有对startService的Activity做任何操作。


###2、
有关Service的startService与bindService在各种情形下生命周期的变化_第3张图片
有关Service的startService与bindService在各种情形下生命周期的变化_第4张图片
这次是在第一个Activity中bindService,在第二个中startService,再最后一个中bindService,然后回退Activity的时候在最后一个中unbindService,第二个不错操作,回到第一个unbindService,最后把第一个也推出栈,然后从运行日志中可以看到,在最后Service没有执行onDestory方法,也就是表明Service还存在,没有被销毁,这一点从日志画红圈的部分(重新进入第一个Activity并startService)也可以得以验证。


###3、
有关Service的startService与bindService在各种情形下生命周期的变化_第5张图片
有关Service的startService与bindService在各种情形下生命周期的变化_第6张图片
这一次只是单单在两个Activity中执行bindService以及unbindService操作,可以看到,此时在第一个Activity销毁前,Service已经在执行了unbindService操作后被销毁了,与(1)存在些许区别。


###4、
有关Service的startService与bindService在各种情形下生命周期的变化_第7张图片
有关Service的startService与bindService在各种情形下生命周期的变化_第8张图片
在这次的尝试中,从输出的日志可以看到,当在第二个Activity中stopService之后,Service没有被立即销毁,而是一直等到第一个Activity被onDestory之后(也就是最后一个与其绑定的Context销毁之后),它才自动被销毁,情况和(1)类似。


###5、
有关Service的startService与bindService在各种情形下生命周期的变化_第9张图片
有关Service的startService与bindService在各种情形下生命周期的变化_第10张图片
在这一次的尝试中,可以看到,最后在第一个Activity中执行完unbindService之后,Service正常的被销毁。


###6、
有关Service的startService与bindService在各种情形下生命周期的变化_第11张图片
有关Service的startService与bindService在各种情形下生命周期的变化_第12张图片
根据运行流程与输出的日志可以看到,虽然在第二个Activity中没有unbindService,但是当第二个Activity onDestory之后,其绑定到Service中的Context也就失效了,然后回到第一个Activity中执行unbindService之后,Service就立即被销毁了。


###7、
有关Service的startService与bindService在各种情形下生命周期的变化_第13张图片
有关Service的startService与bindService在各种情形下生命周期的变化_第14张图片
这次在第一个Activity中unbindService之后,Service也被正常销毁了。


###8、
有关Service的startService与bindService在各种情形下生命周期的变化_第15张图片
有关Service的startService与bindService在各种情形下生命周期的变化_第16张图片
这次,在第二个Activity中startService后没有进行stopService,在第三个Activity中bindService后也没有unbindService,只有在第一个Activity推出栈之前执行unbindService,从运行日志可以看出,Service没有被销毁,还处于运行状态(从画圈部分的日志可以得以验证,再次进入程序,在第一个Activity中startService并没有执行onCreate只执行了onStartCommand)。


###9、
这里写图片描述
有关Service的startService与bindService在各种情形下生命周期的变化_第17张图片


###10、
这里写图片描述
有关Service的startService与bindService在各种情形下生命周期的变化_第18张图片
如果只是在第一个Activity中bindService,然后在把Activity推出栈,在Activity执行onDestory之后,Service才自动执行unbindService然后被销毁。


###11、
这里写图片描述
有关Service的startService与bindService在各种情形下生命周期的变化_第19张图片


###根据上述的几个情景的验证,可以得出如下结论:


【1】当startService单独使用时,即使对应的startService时传入的Context被销毁,Service也还是会处于运行状态。


【2】无论多少个Activity绑定了Service,但是onBind()只会执行一次,也就是Service首次被绑定时会执行,onUnbind()也是如此,即最后一个Context失效后,才会执行onUnbind()(Activity主动调用unbindService或者被onDestory)。
**而如果由于Activity没有主动调用unbindService与Serivice解绑,这样会造成内存泄漏。**如截图:
有关Service的startService与bindService在各种情形下生命周期的变化_第20张图片
(这里需要说明的是,只要Activity在bindService后,如果在销毁前没有主动调用unbindService,就会引发内存泄漏。)

最后一个Context的意思是所有Context中最后一个失效的Context,假设有两个Activity,都绑定了Service,且在从第一个Activity跳转带第二个Activity,当在第二个Activity中bindService后,借助广播或者其他途径直接finish掉第一个Activity(可以在第一个Activity被销毁前先unbindService),这样,在第二个Activity与Service绑定时传入的Context就成了最后一个Context了。


【3】当只有一个Activity与Service进行bindService而没有startService,则Activity在onDestory前如果没有主动调用unbindService与Service解除绑定,或者只是直接调用stopService,则需要等到Activity被销毁,也就是与Service绑定的Context失效时,Service才会执行onUnbind(),之后会自动调用onDestory()进行销毁。


【4】
如果是多个Activity都绑定了同一个Service绑定,且没有执行过startService,当其中一个Activity onDestory或者进行unbindService之后,其与Service进行bindService时的Context就会失效,而当最后与Service绑定的Contxet失效后,Service才会执行onUnbind(),之后会自动调用onDestory()进行销毁。


【5】
如果是同时有多个Activity对Service进行了startServicebindService,如果没有显示调用过stopService,则当所有与Service绑定的Context失效后,Service不会被销毁,会一直在后台运行,因为有主动调用了startService,此时必须主动调用stopService或者在Service中调用stopSelf才能将其销毁;而如果在一个或者多个Context失效前主动调用了stopService或者在Service中调用stopSelf,则需要等到最后一个Context主动与Service进行unbindService或者失效后,才会能使Service执行onDestory

你可能感兴趣的:(找啊找啊找工作,Android相关)