Service: 生命周期与 startService

来源:互联网 发布:手机淘宝实名认证在哪 编辑:程序博客网 时间:2024/05/20 22:40

Service 经常被使用,结合开发过程中遇到的问题以及注意事项,总结一下 android service 组件。


Service: 小试 AIDL IPC 牛刀 是我年少轻狂之时写的一篇很糟糕的博文,那个时候学得东西不多,但是激情很高。


本来想删掉它,然后重新写一篇,以免毒害他人。后来,还是舍不得,略做修改,勉强一下吧!


本人觉得,it 就是一份扯淡的事业。只要你在 it 行业,就会永远发现新东西。没有尽头!


学会分享和总结,你会发现世界还是很美好地!


这篇博文,算是很简单的入门,高手或者你已经很清楚 service 生命周期的不妨试读一下,给点建议。


运行界面




点击 Button 会启动一个Service(PlayerService),Activity(PlayerActivity)代码示例如下

package mark.zhang;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;public class PlayerActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);}public void onService(View view) {    Intent intent = new Intent(PlayerActivity.this, PlayerService.class);    startService(intent);}}


PlayerService 代码示例如下

说明:onStart 方法已经过时了,所以使用 onStartCommand 方法。


package mark.zhang;import android.app.Service;import android.content.Intent;import android.os.Handler;import android.os.IBinder;import android.util.Log;public class PlayerService extends Service {private static final String TAG = "PlayerService";private static final long DELAY = 5000;private int mServiceStartId = -1;private Handler sWork = new Handler();private Runnable task = new Runnable() {    @Override    public void run() {        Log.d(TAG, DELAY / 1000 + "s after-----------");        stopSelf();        //stopSelf(mServiceStartId);    }};@Overridepublic IBinder onBind(Intent intent) {    Log.d(TAG, "onBind------");    return null;}@Overridepublic void onCreate() {    super.onCreate();    Log.d(TAG, "onCreate------");    sWork.postDelayed(task, 5000);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {    Log.d(TAG, "onStartCommand------and startId = " + startId);    mServiceStartId = startId;    return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {    Log.d(TAG, "onDestroy------");    super.onDestroy();}}


在 PlayerService 里面使用 Handler 在 5s 之后停止 PlayerService。


点击 Button 5 次,打印结果




5s 之后,调用 stopSelf(实际调用的是 stopSelf(-1) 这个方法),停止服务。


当然,你也可以在 PlayerActivity 里面调用 stopService 来停止服务。


从这里,可以看出通过 startService 启动服务,其生命周期是这样的。


                                                         



在 Service 的一个生命周期中,onCreate / onDestroy 方法只调用一次,onStartConmand 方法可以被调用多次。

在 onStartConmand 方法里面,可以看出,每调用一次这个方法,startId 就会加 1.


stopSelf() 与 stopSelf(int startId) 与 stopService 的s功效是一样的。

网上很多人说,stopSelf() 与 stopSelf(int startId) 是不会立即停止服务的,我觉得说法不科学。


调用 stopSelf() 或者 stopSelf(int startId),  这个时候 onDestroy 均会被调用,说明 service 的生命已经 over,哪来的服务没有停止?只能说应用程序没有停止,你写的代码如线程死循环一直在跑,虽然该线程也是在 service 里面启动的,但是记住 Service 是与 Activity 默认在一个进程(一个 application 就是一个进程),那麽应用程序没有挂掉,死循环的线程怎么会停止?!


下面举个例子:


在 PlayerService 的 onStartCommand 方法里面


isRunning 是成员变量,默认值为 false

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {    Log.d(TAG, "onStartCommand------and startId = " + startId);    mServiceStartId = startId;    isRunning = true;    new Thread(new Runnable() {        @Override        public void run() {            while(isRunning) {                Log.d(TAG, "running--------------------");            }        }       }).start();    return super.onStartCommand(intent, flags, startId);}

       

可见如果 isRunning 不设置为 false 或者该 Application 不停止,这个该死的线程永远也不会停下来。

所以,需要在合适的地方设置 isRunning 


如 onDestroy


@Overridepublic void onDestroy() {    Log.d("mark", "onDestroy------");    isRunning = false;    super.onDestroy();}





原创粉丝点击