您的位置:首页 > 其它

Service: onStartCommand 诡异的返回值

2012-05-24 23:04 357 查看
通过 startService 启动的服务,一定会调用 service 的 onStartCommand 方法。

Service 源码里面,onStartCommand 方法的原型

 public int onStartCommand(Intent intent, int flags, int startId) {

        onStart(intent, startId);

        return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;

 }

而我们覆写该方法是这样的

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

该方法有返回值,类型为 int,而我们返回父类的 onStartCommand 结果,即:

START_STICKY_COMPATIBILITY 或者 START_STICKY。

那麽,到底返回哪个呢?还得看 mStartCompatibility 的值

 mStartCompatibility = 

            getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.ECLAIR;

可以看出,只要我们的应用程序 targetSdkVersion 小于 2.0

那麽就返回 START_STICKY_COMPATIBILITY,否则返回 START_STICKY。

当然我们可以自己返回指定的值,不返回父类的结果。但是究竟可以返回哪些?

查看 api 文档,关于 onStartCommand 的介绍



继续跟踪 START_CONTINUATION_MASK,会发现

START_STICKY

START_NOT_STICKY

START_REDELIVER_INTENT

START_STICKY_COMPATIBILITY

为了,解释这几个 int 值的含义,除了结合 api 文档(尼嘛,很难懂,有木有!),必须实践。

原理:PlayerService -- > Runnable -- > run 制造异常,模拟系统杀死该进程。

在实验之前,为了确保实验的准确性请做到 abcde

a. 将你的模拟器或者真机调整到 settings/application/running service 界面

                                                    


b. 在每个实验之前使用  adb  uninstall mark.zhang 卸载这个应用程序,并确保 success

c. 使用 eclipse 直接 run 该应用程序或者命令行 adb install ×××.apk

d. 第一次出现下面提示框,点击 Force close,稍等一会,再次看运行结果,打印信息

                                                             


e. 再次出现上面对话框直接关闭,不用再等,服务只会自动重启一次

------------------------------------------ start ---------------------------

1.  START_STICKY



可以看出,再次调用 onCreate、onStartCommand,并且 startId = 2, 但是 intent = null

2.  START_NOT_STICKY



这次并没有重启。

3.  START_STICKY_COMPATIBILITY



只调用了oncreate 方法,没有调用 onStartCommand 

4.  START_REDELIVER_INTENT



可以看出,再次调用 onCreate、onStartCommand,并且 startId = 1, 但是 intent 不为 null

说明该 int 可以保留上次的 startId 与 intent



------------------------------------------ end ---------------------------

-------------- 附录

PlayerActivity.java

package mark.zhang;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class PlayerActivity extends Activity {

@Override
public 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.java

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 = 2000;

private Handler sWork = new Handler();

private Runnable task = new Runnable() {

@Override
public void run() {
Log.d(TAG, DELAY / 1000 + "s after-----------");
// 故意制造异常,使该进程挂掉
Integer.parseInt("ok");
}
};

@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind------");
return null;
}

@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate------");
sWork.postDelayed(task, 5000);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand------and startId = " + startId);
Log.d(TAG, "onStartCommand------and intent = " + intent);
// 实验中,可轮换这几个值测试
return START_NOT_STICKY;// | START_STICKY | START_STICKY_COMPATIBILITY |
// START_REDELIVER_INTENT;
}

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: