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

本文详细介绍了Android Service的生命周期,包括startService和bindService两种启动模式下的生命周期变化。通过实例演示,展示了不同启动方式下Service的onCreate、onStartCommand、onBind、onUnbind和onDestroy等方法的调用情况,强调了启动服务与绑定服务可以同时使用及其相互影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

服务分类

这里写图片描述
这里写图片描述

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方法会被调用。

以上两种模式的流程如下图所示:
这里写图片描述

两种模式有以下几点不同之处: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.");
    }

}

运行图:
这里写图片描述

一、startService()方式

1、点击一次启动按钮:
这里写图片描述

2、当然我们觉得还不过瘾,再点击一次,我们会发现结果略有不同:
这里写图片描述

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

3、然后我们点击停止按钮,试图停止服务,我们发现如下现象:
这里写图片描述

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

二、bindService()方式

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

1、点击一下绑定按钮:
这里写图片描述
onServiceConnected方法被调用了,证明绑定连接已经成功了。onCreate方法和onBind方法被调用了,此时服务已进入运行阶段,如果再次点击绑定按钮,onCreate和onBinder并不会再次被调用,这个过程中它们仅被调用一次。

2、点击解除绑定按钮:
这里写图片描述
可以看到onUnbind方法和onDestroy方法被调用了,此时MyService已被销毁,整个生命周期结束。

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

三、startService和bindService同时使用

先启动后绑定:

1、首先按下启动服务的按钮:
这里写图片描述

2、再按下绑定服务的按钮:
这里写图片描述
此时,onCreate()方法不会重调,只有onBind被调用,两者就绑定成功。

3、再按下解除绑定的按钮:
这里写图片描述
此时,onUnbind方法方法被调用,注意,此时MyService并没有因解除绑定而终止,而是继续运行。

4、最后我们按下停止服务的按钮:
这里写图片描述
此时,onDestroy被调用了,此时MyService停止了运行,整个生命周期结束。

先绑定后启动:

1、首先按下绑定服务按钮:
这里写图片描述

2、再按下启动服务按钮:
这里写图片描述
此时,onCreate()方法不会重调,只有onStartCommand()和onStart()被调用。

3、再按下停止服务按钮:
这里写图片描述
按了好几次,发现没有日志输出,因为服务还处在绑定状态,无法停止服务。

3、再按下解除绑定按钮:
这里写图片描述
服务正常终止了。

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值