IntentService的简介
IntentService是Service类的子类,用来处理异步请求。客户端可以通过startService(Intent)方法传递请求给IntentService。IntentService在onCreate()函数中通过HandlerThread单独开启一个线程来处理所有Intent请求对象(通过startService的方式发送过来的)所对应的任务,这样以免事务处理阻塞主线程。执行完所一个Intent请求对象所对应的工作之后,如果没有新的Intent请求达到,则自动停止Service;否则执行下一个Intent请求所对应的任务。
IntentService与Service的区别
Android的service是用于后台服务的,为了保证应用程序被挂到后台后某些组件仍然可以工作而引入的概念,需要注意的是service既不是独立的进程也不是独立的线程,是依赖于主线程的,所以是不建议在service里面做过多的耗时操作的,避免ANR。
即要编写耗时操作又不得不交于service管理的话,就需要引入IntentService,IntentService继承service,拥有service的全部生命周期,包含了service的全部特性,与service不同的是IntentService在onCreat被执行时内部会开启一个线程,执行耗时操作。
IntentService使用方法
使用IntentService需要两个步骤:
(1)写构造函数
(2)实现虚函数onHandleIntent,并在里面根据Intent的不同进行不同的事务处理就可以了。
启动MyIntentServic的代码片段
Intent intent=new Intent(this,MyIntentService.class);
startService(intent);
权限"<service Android:name=".MyIntentService/>""
IntentService源码解读
这里我适当在源码的每个方法上加了容易解读的注释
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;//消息队列
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
//接收handler发送的消息 消息值为int型相当于一个请求的唯一标识。每发送一个请求,会生成一个唯一的标识,然后将请求放入队列,当全部执行完成(最后一个请求也就相当于getLastStartId == startId),
或者当前发送的标识是最近发出的那一个(getLastStartId == startId),则会销毁我们的Service.
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
//构造方法 传入我们创建的Intentservice的名字
public IntentService(String name) {
super();
mName = name;
}
//设置该方法的布尔值(具体用途在onStartCommand中体现)
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
//创建一个服务并开启线程得到消息队列并通过handller发送
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
//由onStartCommand中回调onstart通过mServiceHandler发送消息到该handler的handleMessage中去。
//最后handleMessage中回调onHandleIntent(intent)。
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
//mRedelivery会根据setIntentRedelivery设置的布尔值返回START_REDELIVER_INTENT or START_NOT_STICKY
//START_NOT_STICKY型服务会直接被关闭
//START_REDELIVER_INTENT 型服务会在可用资源不再吃紧的时候尝试再次启动服务
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
//退出消息队列
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
//重写耗时操作的逻辑,改方法会延伸到继承它的子类中实现
protected abstract void onHandleIntent(Intent intent);
}
IntentService具体方法解读
构造函数
IntentService(String name)创建一个 IntentService.
公用方法
onBind(Intent intent)不需要实现此方法,因为默认实现返回null
onCreate()当服务首次创建时由系统调用。
onDestroy()通知服务不再使用并正在被删除
onStartCommand不需要重写
setIntentRedelivery(boolean enabled) 源码中的体现是根据此方法设置的布尔值来决定onStartCommand 返回START_NOT_STICKY还是START_REDELIVER_INTENT;;;START_NOT_STICKY型服务会直接被关闭,而START_REDELIVER_INTENT 型服务会在可用资源不再吃紧的时候尝试再次启动服务。 由此我们可以发现,当我们的操作不是十分重要的时候,我们可以选择START_NOT_STICKY,这也是IntentService的默认选项,当我们认为操作十分重要时,则应该选择START_REDELIVER_INTENT 型服务
onHandleIntent(Intent intent)该函数用于针对Intent的不同进行不同的事务处理就可以了.执行完所一个Intent请求对象所对应的工作之后,如果没有新的Intent请求达到,则自动停止Service;否则ServiceHandler会取得下一个Intent请求传人该函数来处理其所对应的任务。
总结:
IntentService主要应用的场景为即要编写耗时操作又不得不放于后台管理的逻辑实现
例如:后台上传图片,批量操作数据库等。
还可以利用IntentService去优化你的App启动速度:
通常我们的App在Application的onCreate有很多第三方平台的初始化工作,耗时大户就是我们用的几大平台的初始化方法, 加载native的lib, 用ZipFile操作等
调整Application onCreate 例如:
@Override
public void onCreate() {
super.onCreate();
context = this;
InitializeService.start(this);
}
InitializeService中的代码:
用IntentService来做初始化工作.
public class InitializeService extends IntentService {
private static final String ACTION_INIT_WHEN_APP_CREATE = "com.risenbsy.ixing.service.action.INIT";
public InitializeService() {
super("InitializeService");
}
public static void start(Context context) {
Intent intent = new Intent(context, InitializeService.class);
intent.setAction(ACTION_INIT_WHEN_APP_CREATE);
context.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_INIT_WHEN_APP_CREATE.equals(action)) {
performInit();
}
}
}
private void performInit() {
//环信相关初始化
HuanxinHelper.getInstance().init(this);
initLive();
initCloudChannel(this);
DiskUtils.getContext(getApplicationContext());
ComplexUtil.initialize(getApplicationContext());
// ActiveAndroid.setLoggingEnabled(true);
registerActivityLifecycleCallbacks(ActivityManager.getActivityLifecycleCallbacks());
initImageLoader(getApplicationContext());
mShareAPI = UMShareAPI.get(this);
Config.REDIRECT_URL = "http://sns.whalecloud.com/sina2/callback";
Config.DEBUG=true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}
}
}
网友评论