在安卓实际开发中,我们经常会遇到一些耗时操作,如请求网络,存储,android 提供了AsyncTask,可是这种不好的地方
有些同学可能认为一个在Activity中的AsyncTask会随着Activity的销毁而销毁。但AsyncTask会一直执行doInBackground()方法直到方法执行结束。一旦上述方法结束,会依据情况进 行不同的操作。
•如果cancel(boolean)调用了,则执行onCancelled(Result)方法
•如果cancel(boolean)没有调用,则执行onPostExecute(Result)方法
所以activity的ondestroy()必须cancle掉asyncTask的任务
private InitDataAsyncTask mInitDataAsyncTask;
private class InitDataAsyncTask extends AsyncTask<Void,Void,Void> {
@Override
protected Void doInBackground(Void... params) {
fetchDataFromDataBase();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
mTipView.hideView();
updateHealthLayout();
initAdapterForFragment();
}
}
public void ondestroy(){
super.ondestroy();
if(mInitDataAsyncTask != null) {
mInitDataAsyncTask.cancel(true);
}
}所以不需要执行回调的情况下使用intentService是非常合适的
IntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们手动去控制或stopSelf()。另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个。Intent服务开启后,执行完onHandleIntent里面的任务就自动销毁结束,通过打印的线程名称可以发现是新开了一个线程来处理耗时操作的,即是耗时操作也可以被这个线程管理和执行,同时不会产生ANR的情况。
那么如何写一个intentService呢:
public class PedometerIntentService extends IntentService {
private static final String SERVICE_NAME = "PedometerIntentService";
private static final String BOOLEAN_VALUE = "boolean_value";
private static final String INT_VALUE = "int_value";
private static final String TAG = PedometerIntentService.class.getSimpleName();
public PedometerIntentService() {
super(SERVICE_NAME);
}
public static void startService(Context context, String action) {
try{
Intent intent = new Intent(action);
intent.setClass(context,PedometerIntentService.class);
context.startpService(intent);
}catch (Exception ex) {
ex.printStackTrace();
MonitorUtil.reportError(context,ex);
}
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
if (intent == null) return;
int value = 0;
try{
switch (intent.getAction()) {
case PemometerConstant.PEDOMETER_EXECUTE_GET_RECOMMEND_SPORT_TARGET_ACTION:
LogUtil.d(TAG,"pedometer_execute_get_recommend_sport_target_action task execute");
getRecommendSportTask();
break;
case PemometerConstant.PEDOMETER_EXECUTE_GET_RED_PACKAGE_ACTION:
boolean shouldShowRedPackageInNotification = intent.getBooleanExtra(BOOLEAN_VALUE,false);
LogUtil.d(TAG,"pedometer_execute_get_red_package_target_action execute flag="+shouldShowRedPackageInNotification);
PedometerUtils.notifyredPackageChanged(this,shouldShowRedPackageInNotification ? 1 : 0);
break;
}
}catch (Exception ex) {
MonitorUtil.reportError(this,ex);
ex.printStackTrace();
}
}
private void getRecommendSportTask() {
}
}调用方法是
PedometerIntentService.startService(mContext, PemometerConstant.PEDOMETER_EXECUTE_GET_RECOMMEND_SPORT_TARGET_ACTION);