在安卓实际开发中,我们经常会遇到一些耗时操作,如请求网络,存储,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);