Android基础总结——Service生命周期

Service在Android中和Activity是属于同一级别上的组件,我们可以将他们认为是两个好哥们,Activity仪表不凡,迷倒万千少女,经常做一些公众人物角色,而Service一副彪悍的长相,但却身强力壮,常常在后台做一些搬运工的力气活,虽然有些累,但大家都不能失去他。
下面我们就围绕Service对其进行全面讲解:

服务分类

Android基础总结——Service生命周期_第1张图片
Android基础总结——Service生命周期_第2张图片

Service生命周期

Service生命周期可以从两种启动Service的模式开始讲起,分别是context.startService()和context.bindService()。

(1)、startService的启动模式下的生命周期:
当我们首次使用startService启动一个服务时,系统会实例化一个Service实例,依次调用其onCreate和onStartCommand方法,然后进入运行状态,此后,如果再使用startService启动服务时,不再创建新的服务对象,系统会自动找到刚才创建的Service实例,调用其onStart方法;如果我们想要停掉一个服务,可使用stopService方法,此时onDestroy方法会被调用,需要注意的是,不管前面使用了多个次startService,只需一次stopService,即可停掉服务。

(2).bindService启动模式下的生命周期:
在这种模式下,当调用者首次使用bindService绑定一个服务时,系统会实例化一个Service实例,并一次调用其onCreate方法和onBind方法,然后调用者就可以和服务进行交互了,此后,如果再次使用bindService绑定服务,系统不会创建新的Service实例,也不会再调用onBind方法;如果我们需要解除与这个服务的绑定,可使用unbindService方法,此时onUnbind方法和onDestroy方法会被调用。

以上两种模式的流程如下图所示:
Android基础总结——Service生命周期_第3张图片

两种模式有以下几点不同之处:startService模式下调用者与服务无必然联系,即使调用者结束了自己的生命周期,只要没有使用stopService方法停止这个服务,服务仍会运行;通常情况下,bindService模式下服务是与调用者生死与共的,在绑定结束之后,一旦调用者被销毁,服务也就立即终止,就像江湖上的一句话:不求同生,但愿同死。

值得一提的是,以前我们在使用startService启动服务时都是习惯重写onStart方法,在Android2.0时系统引进了onStartCommand方法取代onStart方法,为了兼容以前的程序,在onStartCommand方法中其实调用了onStart方法,不过我们最好是重写onStartCommand方法。

生命周期实例演示

MainActivity.java:

public class MainActivity extends Activity implements View.OnClickListener {

    private static final String TAG = "MainActivity";
    private Button start;
    private Button stop;
    private Button bind;
    private Button unbind;
    private TextView textView;
    private boolean binded;

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            binded = true;
            Log.i(TAG, "onServiceConnected called.");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG, "onServiceDisconnected called.");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);
        start = (Button) findViewById(R.id.bt_start);
        stop = (Button) findViewById(R.id.bt_stop);
        bind = (Button) findViewById(R.id.bt_bind);
        unbind = (Button) findViewById(R.id.bt_unbind);
        start.setOnClickListener(this);
        stop.setOnClickListener(this);
        bind.setOnClickListener(this);
        unbind.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_start:
                start();
                break;
            case R.id.bt_stop:
                stop();
                break;
            case R.id.bt_bind:
                bind();
                break;
            case R.id.bt_unbind:
                unbind();
                break;
        }
    }

    /** * 启动服务 * * @param */
    public void start() {
        Intent intent = new Intent(this, MyService.class);
        startService(intent);
        textView.setText("服务运行中...");
    }

    /** * 停止服务 * * @param */
    public void stop() {
        Intent intent = new Intent(this, MyService.class);
        stopService(intent);
        textView.setText("服务已停止");
    }

    /** * 绑定服务 * * @param */
    public void bind() {
        Intent intent = new Intent(this, MyService.class);
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }

    /** * 解除绑定 * * @param */
    public void unbind() {
        if (binded) {
            unbindService(conn);
            binded = false;
        }
    }

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

}

MyService.java:

public class MyService extends Service {

    private static final String TAG = "MyService";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate called.");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand called.");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.i(TAG, "onStart called.");
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind called.");
        return new Binder() {};
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.i(TAG, "onUnbind called.");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy called.");
    }

}

运行图:
Android基础总结——Service生命周期_第4张图片

一、startService()方式

1、点击一次启动按钮:
Android基础总结——Service生命周期_第5张图片

2、当然我们觉得还不过瘾,再点击一次,我们会发现结果略有不同:
Android基础总结——Service生命周期_第6张图片

我们看到第二次点击时onCreate方法就不再被调用了,而是直接调用了onStartCommand方法(onStartCommand中又调用了onStart方法)。我们选择“Settings->Application s->Running services”就会发现我们刚刚启动的服务。

3、然后我们点击停止按钮,试图停止服务,我们发现如下现象:
Android基础总结——Service生命周期_第7张图片

我们会发现onDestroy方法被调用了,此时服务就停止运行了。我们再次查看“Running services”,就会发现MyService这个服务已全无踪迹。

二、bindService()方式

注意:在使用bindService绑定服务时,我们需要一个ServiceConnection代表与服务的连接,它只有两个方法,onServiceConnected和onServiceDisconnected,前者是在操作者在连接一个服务成功时被调用,而后者是在服务崩溃或被杀死导致的连接中断时被调用,而如果我们自己解除绑定时则不会被调用,所以我们这里只研究onServiceConnected这个方法。
看样子是可以去绑定一个服务了,其实还不行,因为我们前面服务中的onBind方法返回值为null,这样是不行的,要想实现绑定操作,必须返回一个实现了IBinder接口类型的实例,该接口描述了与远程对象进行交互的抽象协议,有了它我们才能与服务进行交互。

1、点击一下绑定按钮:
Android基础总结——Service生命周期_第8张图片
onServiceConnected方法被调用了,证明绑定连接已经成功了。onCreate方法和onBind方法被调用了,此时服务已进入运行阶段,如果再次点击绑定按钮,onCreate和onBinder并不会再次被调用,这个过程中它们仅被调用一次。

2、点击解除绑定按钮:
Android基础总结——Service生命周期_第9张图片
可以看到onUnbind方法和onDestroy方法被调用了,此时MyService已被销毁,整个生命周期结束。

当我们退出MainActivity时,比如后退到主界面,onUnbind方法和onDestroy方法也会被调用,服务也会随之而结束,从这一点上看,MyService可以说是誓死追随着MainActivity。

三、startService和bindService同时使用

先启动后绑定:

1、首先按下启动服务的按钮:
Android基础总结——Service生命周期_第10张图片

2、再按下绑定服务的按钮:
Android基础总结——Service生命周期_第11张图片
此时,onCreate()方法不会重调,只有onBind被调用,两者就绑定成功。

3、再按下解除绑定的按钮:
Android基础总结——Service生命周期_第12张图片
此时,onUnbind方法方法被调用,注意,此时MyService并没有因解除绑定而终止,而是继续运行。

4、最后我们按下停止服务的按钮:
Android基础总结——Service生命周期_第13张图片
此时,onDestroy被调用了,此时MyService停止了运行,整个生命周期结束。

先绑定后启动:

1、首先按下绑定服务按钮:
Android基础总结——Service生命周期_第14张图片

2、再按下启动服务按钮:
Android基础总结——Service生命周期_第15张图片
此时,onCreate()方法不会重调,只有onStartCommand()和onStart()被调用。

3、再按下停止服务按钮:
Android基础总结——Service生命周期_第16张图片
按了好几次,发现没有日志输出,因为服务还处在绑定状态,无法停止服务。

3、再按下解除绑定按钮:
Android基础总结——Service生命周期_第17张图片
服务正常终止了。

总结:
由上可以看出,启动服务和绑定服务可以同时使用,不管哪个先执行,服务的onCreate()方法只会执行一次。 如果服务处于启动状态,单方面的解除绑定不会造成服务停止,同样,如果服务处于绑定状态,单方面的停止服务不会造成服务解除绑定。

以上就是关于MyService生命周期的讲解。

文章内容参考:http://blog.csdn.net/liuhe688/article/details/6874378
代码图片都是本人亲自实验抓取的。

你可能感兴趣的:(android)