Service被异常killed后的behave. ( onStartCommand )

来源:互联网 发布:淘宝全球购要身份证吗 编辑:程序博客网 时间:2024/05/26 12:54

通过 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

If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.



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


2. START_NOT_STICKY

If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver. This is the safest option to avoid running your service when not necessary and when your application can simply restart any unfinished jobs.



这次并没有重启。


3. START_STICKY_COMPATIBILITY

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


4. START_REDELIVER_INTENT


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

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





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





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



PlayerActivity.java



[java] view plaincopyprint?
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



[java] view plaincopyprint?
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();
}

}


转载自:http://blog.csdn.net/androidbluetooth/article/details/7600008

原创粉丝点击