IntentService 使用与原理
来源:互联网 发布:淘宝网不能访问 编辑:程序博客网 时间:2024/05/18 03:41
IntentService
简介
- 在Service里面不能直接进行耗时操作,一般都需要去开启子线程,如果自己去管理Service的生命周期以及子线程难免会不完善,Android提供了一个类,IntentService。
- IntentService是一个基于Service的一个类,用来处理异步的请求。你可以通过startService(Intent)来提交请求,该Service会在需要的时候创建,当完成所有的任务以后自己关闭,而不需要我们去手动控制
使用
需要继承IntentService,然后复写onHandleIntent方法
public class UploadImgService extends IntentService { private static final String ACTION_UPLOAD_IMG = "com.jsj.handlerthreaddemo.action.UPLOAD_IMAGE"; public static final String EXTRA_IMG_PATH = "com.jsj.handlerthreaddemo.extra.IMG_PATH"; /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. * 给线程设置名字 */ public UploadImgService(String name) { super(name); } public UploadImgService() { super("UploadImgService"); } @Override protected void onHandleIntent(@Nullable Intent intent) { if (intent != null) { final String action = intent.getAction(); if (ACTION_UPLOAD_IMG.equals(action)) { final String path = intent.getStringExtra(EXTRA_IMG_PATH);//获取要处理的数据 //TODO 处理数据,然后通过广播将数据发送出去 Intent intent = new Intent(IntentServiceActivity.UPLOAD_RESULT); intent.putExtra(EXTRA_IMG_PATH, path); sendBroadcast(intent);//将处理完的数据通过广播的形式发送出去 } } }
开启服务
//开启服务,并将需要处理的数据传递过去Intent intent = new Intent(context, UploadImgService.class); intent.setAction(ACTION_UPLOAD_IMG); intent.putExtra(EXTRA_IMG_PATH, path); context.startService(intent);
通过广播接受者来接收发送过来的数据
private BroadcastReceiver uploadImgReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction() == UPLOAD_RESULT) { String path = intent.getStringExtra(UploadImgService.EXTRA_IMG_PATH); tv.setText(path + " upload success ~~~ "); } } };
源码
不多就都贴了出来,容易看
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((Intent)msg.obj); stopSelf(msg.arg1); } } /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. */ public IntentService(String name) { super(); mName = name; } /** * Sets intent redelivery preferences. Usually called from the constructor * with your preferred semantics. * * <p>If enabled is true, * {@link #onStartCommand(Intent, int, int)} will return * {@link Service#START_REDELIVER_INTENT}, so if this process dies before * {@link #onHandleIntent(Intent)} returns, the process will be restarted * and the intent redelivered. If multiple Intents have been sent, only * the most recent one is guaranteed to be redelivered. * * <p>If enabled is false (the default), * {@link #onStartCommand(Intent, int, int)} will return * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent * dies along with it. */ public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } @Override public void onCreate() { // TODO: It would be nice to have an option to hold a partial wakelock // during processing, and to have a static startService(Context, Intent) // method that would launch the service & hand off a wakelock. super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } /** * You should not override this method for your IntentService. Instead, * override {@link #onHandleIntent}, which the system calls when the IntentService * receives a start request. * @see android.app.Service#onStartCommand */ @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onDestroy() { mServiceLooper.quit(); } /** * Unless you provide binding for your service, you don't need to implement this * method, because the default implementation returns null. * @see android.app.Service#onBind */ @Override @Nullable public IBinder onBind(Intent intent) { return null; } /** * This method is invoked on the worker thread with a request to process. * Only one Intent is processed at a time, but the processing happens on a * worker thread that runs independently from other application logic. * So, if this code takes a long time, it will hold up other requests to * the same IntentService, but it will not hold up anything else. * When all requests have been handled, the IntentService stops itself, * so you should not call {@link #stopSelf}. * * @param intent The value passed to {@link * android.content.Context#startService(Intent)}. * This may be null if the service is being restarted after * its process has gone away; see * {@link android.app.Service#onStartCommand} * for details. */ @WorkerThread protected abstract void onHandleIntent(@Nullable Intent intent);
分析
1.onCreate里面初始化了一个HandlerThread
@Override public void onCreate() { // TODO: It would be nice to have an option to hold a partial wakelock // during processing, and to have a static startService(Context, Intent) // method that would launch the service & hand off a wakelock. super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); }
2.每次调用onStartCommand的时候,通过mServiceHandler发送一条带startId和Intent的消息,然后在该mServiceHandler的handleMessage中去回调onHandleIntent(intent);
@Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); }
当回调onHandleIntent(intent)后调用了方法stopSelf(msg.arg1);
@Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); }
跟下stopSelf方法,传入了一个int类型,当前发送的标识是最近发出的那一个
当所有的工作执行完后:就会执行onDestroy方法,然后调用方法 mServiceLooper.quit()使looper停下来.
@Override public void onDestroy() { mServiceLooper.quit(); }
总结:
IntentService是继承于Service并处理异步请求的一个类
当完成所有的任务以后自己关闭,而不需要我们去手动控制
可以启动多次,每启动一次,就会新建一个work thread,但IntentService的实例始终只有一个,onCreate方法只执行了一次,而onStartCommand和onStart方法执行多次
在IntentService内拥有一个HandlerThread,获得工作线程的 Looper,并维护自己的工作队列
可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,按顺序执行
阅读全文
0 0
- IntentService 使用与原理
- IntentService原理和使用
- IntentService使用、原理
- IntentService解析与使用
- HandlerThread与IntentService原理解析
- IntentService的原理及使用
- IntentService的原理及使用
- IntentService的原理及使用
- IntentService的原理及使用
- IntentService的原理及使用
- 【IntentService】Android中IntentService的原理及使用
- IntentService的使用与优点
- IntentService简单使用与总结
- Android中IntentService的原理及使用
- Android中IntentService的原理及使用
- Android中IntentService的原理及使用
- Android中IntentService的原理及使用
- Android中IntentService的原理及使用
- XListView无网络
- 网络编程
- 计蒜客-乌鲁木齐网络赛&费用流&拆点-Our Journey of Dalian Ends
- hibernate分组查询后,求分组总数的实现方法(管理系统分页)
- Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能
- IntentService 使用与原理
- 反射
- JSP的C标签的使用
- DOS头部IMAGE_DOS_HEADER
- File文件操作
- JAVA Spring web mvc 学习 之 1
- 如何查看 App的appPackage和appActivity 【亲测多种方法后,真实有效】
- 授权命令
- 【干货】CPR式的IT运维管理,我们不要!