IntentService(二)
来源:互联网 发布:飞利浦e5音响 知乎 编辑:程序博客网 时间:2024/06/05 09:04
此篇讲述IntentService的简单使用
什么是IntentService,首先看看官方的解释:
IntentService is a base class forServices that handle asynchronous requests (expressed asIntents) on demand. Clients send requests throughstartService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work
还有一个说明是:
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
大致意思是:所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。1.清单文件中注册
<service android:name="com.finddreams.runningman.MyIntentService">
</service>
2.java代码中实现IntentService
package com.finddreams.runningman;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
public class MyIntentService extends IntentService{
//构造方法1 错误
// public MyIntentService(String name) {
// super(name);
// Log.d("MyIntentService", "构造方法!!!!!!!!Thread----:"+Thread.currentThread().getName());
// }
//构造方法2 正确
public MyIntentService() {
super("MyIntentService");
Log.d("MyIntentService", "构造方法!!!!!!!!Thread----:"+Thread.currentThread().getName());
}
//onCreate方法
@Override
public void onCreate() {
super.onCreate();
Log.d("MyIntentService", "onCreate方法!!!!!!!!Thread----:"+Thread.currentThread().getName());
}
//onStartCommand方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyIntentService", "onStartCommand方法!!!!!!!!Thread----:"+Thread.currentThread().getName());
return super.onStartCommand(intent, flags, startId);
}
//onHandleIntent方法 耗时操作
@Override
protected void onHandleIntent(Intent arg0) {
String name=arg0.getStringExtra("name");
String age=arg0.getStringExtra("age");
//耗时操作 比如 下载文件 链接网络 下载图片...
Log.d("MyIntentService", "name----:"+name);
Log.d("MyIntentService", "age----:"+age);
Log.d("MyIntentService", "onHandleIntent方法!!!!!!!!Thread----:"+Thread.currentThread().getName());
}
}
3.java 代码中启动服务
Intent intent=new Intent(RuningManActivity.this,MyIntentService.class);
intent.putExtra("name", "张三");
intent.putExtra("age", "18");
startService(intent);
4.结果
5.说明
5.1.通过以上的输出结果我们可以发现,MyIntentService的onCreate、onStartCommand、onDestroy等回调方法都是运行在主线程中的,而onHandleIntent是运行在工作线程IntentService[MyIntentService]中的,这验证了我们上面所说的IntentService的第一个和第二个特点。即只有onHandleIntent方法运行在子线程中,其他生命周期方法和构造方法运行在UI线程。
5.2.如果我们连续调用了多次startService(intent)之后,onStartCommand依次被调用了多次,然后依次执行了onHandleIntent多次,这样就依次完成了job,当最后一个job完成,也就是在最后一次onHandleIntent调用完成之后,整个IntentService的工作都完成,执行onDestroy回调方法,IntentService销毁。
6.注意
IntentService的构造方法
为
public MyIntentService(String name) {
super(name);
Log.d("MyIntentService", "构造方法!!!!!!!!Thread----:"+Thread.currentThread().getName());
}
时
报错:
java.lang.RuntimeException: Unable to instantiate service com.finddreams.runningman.MyIntentService: java.lang.InstantiationException: can't instantiate class com.finddreams.runningman.MyIntentService; no empty constructor
IntentService的构造方法
为
public MyIntentService() {
super("MyIntentService");
Log.d("MyIntentService", "构造方法!!!!!!!!Thread----:"+Thread.currentThread().getName());
}
时
正确6.IntentService工作原理及源码解析
在上面我们已经介绍了IntentService的特点以及如何使用,那么你可能会疑问Android是如何将调度这些intent将其传入onHandleIntent完成工作的,其实IntentService的工作原理很简单,将intent转换为Message并放到消息队列中,然后让Handler依次从中取出Message对其进行处理。
IntentService的源码如下:
package android.app;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
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);
}
@Override
public void handleMessage(Message msg) {
//在工作线程中调用onHandleIntent,确保onHandleIntent不会阻塞主线程
onHandleIntent((Intent)msg.obj);
//在执行完了onHandleIntent之后,我们需要调用stopSelf(startId)声明某个job完成了
//当所有job完成的时候,Android就会回调onDestroy方法,销毁IntentService
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
//此处的name将用作线程名称
super();
mName = name;
}
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
//创建HandlerThread,利用mName作为线程名称,HandlerThread是IntentService的工作线程
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
//将创建的HandlerThread所绑定的looper对象传递给ServiceHandler,
//这样我们创建的Handler就和HandlerThread通过消息队列绑定在了一起
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(Intent intent, int startId) {
//在此方法中创建Message对象,并将intent作为Message的obj参数,
//这样Message与Intent就关联起来了
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
//将关联了Intent信息的Message发送给Handler
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//IntentService重写了onStartCommand回调方法:在内部调用onStart回调方法
//所以我们在继承IntentService时,不应该再覆写该方法,即便覆盖该方法,我们也应该调用super.onStartCommand()
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
//在onDestroy方法中调用了Handler的quit方法,该方法会终止消息循环
mServiceLooper.quit();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
protected abstract void onHandleIntent(Intent intent);
}
我对上面的代码已经加了很多注释,相信大家直接看代码就能理解IntentService是如何运作的了。
IntentService继承自Service类,并且IntentService重写了onCreate、onStartCommand、onStart、onDestroy回调方法,并且IntentService还添加了一个onHandleIntent回调方法。下面我们依次解释这几个方法在IntentService的作用。
onCreate: 在onCreate回调方法中,利用mName作为线程名称,创建HandlerThread,HandlerThread是IntentService的工作线程。HandlerThread在执行了start方法之后,其本身就关联了消息队列和Looper,并且消息队列开始循环起来。
onStartCommand:IntentService重写了onStartCommand回调方法:在内部调用onStart回调方法。
onStart: 在onStart方法中创建Message对象,并将intent作为Message的obj参数,这样Message与Intent就关联起来了,然后通过Handler的sendMessage方法将关联了Intent信息的Message发送给Handler。
onHandleIntent:当在onStart方法中,通过sendMessage方法将Message放入到Handler所关联的消息队列中后,Handler所关联的Looper对象会从消息队列中取出一个Message,然后将其传入Handler的handleMessage方法中,在handleMessage方法中首先通过Message的obj获取到了原始的Intent对象,然后将其作为参数传给了onHandleIntent方法让其执行。handleMessage方法是运行在HandlerThread的,所以onHandleIntent也是运行在工作线程中的。在执行完了onHandleIntent之后,我们需要调用stopSelf(startId)声明某个job完成了。当所有job完成的时候,Android就会回调onDestroy方法,销毁IntentService。
onDestroy:当所有job完成的时候,Service会销毁并执行其onDestroy回调方法。在该方法中,调用了Handler的quit方法,该方法会终止消息循环。
总结
IntentService可以在工作线程中完成工作而不阻塞主线程,但是IntentService不能并行处理多个job,只能依次处理,一个接一个,当所有的job完成后,会自动执行onDestroy方法而无需我们自己调用stopSelf()或stopSelf(startId)方法。IntentService并不神秘,只是Android对一种常见开发方式的封装,便于开发人员减少开发工作量。 IntentService是个助手类,如果Android没有提供该类也没什么,我们自己也可以写一个类似的。IntentService之余Service,类似于HandlerThread之于Handler。
总结:IntentService和Service去了这样的差别之外,没有什么区别了,比如注册一样,启动方式一样(启动式 绑带式)等等。
- IntentService(二)
- android service 之二(IntentService)
- android service 之二(IntentService)
- android service 之二(IntentService)
- android service 之二(IntentService)
- IntentService
- IntentService
- intentservice
- IntentService
- IntentService
- IntentService
- IntentService
- IntentService
- IntentService
- IntentService
- IntentService
- IntentService
- IntentService
- PopupWindow、EditText
- mysql delete和truncate区别
- VBA下弹框打开excel文件并读取数据
- Thinkphp我们知道的事!
- spring cloud-feign
- IntentService(二)
- 【C#】初学者的一点思考
- 轻松看懂机器学习十大常用算法
- There is no Action mapped for namespace [/cargo] and action name [contractAction_list] associated wi
- J2EE系列之Struts2学习笔记(二十二)--Struts2多文件上传和文件下载
- retrofit 图文上传
- bzoj 1211 prufer编码+排列组合
- Unity技术面试题100问
- Mybatis添加ehcache缓存支持