《android framework常用api源码分析》之IntentService意图服务
来源:互联网 发布:红色后代知乎 编辑:程序博客网 时间:2024/06/10 13:39
《android framework常用api源码分析》android生态在中国已经发展非常庞大了,一方面是因为手机移动端的覆盖,另一方面是从事android开发的人也月来越多。那么用人单位对android要求也变了,对android不仅要熟练使用而且要懂得原理。而就程序员自身阅读源码有什么那些?这里我通过自己理解归纳了一下。
提高程序执行效率,正确理解api可以高效使用,优化内存和执行效率。
避免八阿哥强势逆袭,android开发同学都知道android找bug比较麻烦,尤其是一下jni底层调用错误信息不够明确地方更加难找。
帮助自己写出优雅的代码,开发需要规范,而源码中有很多优秀的谷歌规范。
优秀的设计模式,帮助自己提升程序造诣。
黑科技,通过反射高一些api不能够达到的功能,例如插件化、热更新。
上面是简单个人理解,有更多补充欢迎留言。所以这里准备出一个系列的文章来分析android framework api, 这些文章也是来自整理于网络,所以要感谢那些具有分享精神的大神们。
文章目录:
- apk 打包过程解析。
- handler 消息机制。
- AsyncTask 异步任务。
- HandlerThread handler线程。
- IntentService意图服务。
- Zygote进程。
- SystemServer进程。
- Launcher 程序。
- app 进程启动流程。
- 系统app启动安装流程。
- app应用安装流程。
- Activity启动流程。
- LruCache内存缓存
什么是IntentService?本身继承了service,所以IntentService就是一个服务,只不过他内部实现了HandlerThread而且管理了service关闭,可以使调用这简单的调用用而不用关心他什么时候关闭;onHandleIntent是里面需要继承类实现的抽象方法,而他是在HandlerThread中执行所以在非ui线程,我们知道四大组件生命周期都是在主线程中执行,因为他们都是用handler机制回调,而我们启动服务往往都是需要处理耗时操作,这样IntentService是相当方便的; 我们来看其简单的使用方法:
- 定义一个IntentService
public class MIntentService extends IntentService{ public MIntentService() { super(""); } @Override protected void onHandleIntent(Intent intent) { Log.i("tag", intent.getStringExtra("params") + " " + Thread.currentThread().getId()); }}
- 在androidManifest.xml中定义service
<service android:name=".MIntentService" />
- 启动这个service
title.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, MIntentService.class); intent.putExtra("params", "ceshi"); startService(intent); } });
可以发现当点击title组件的时候,service接收到了消息并打印出了传递过去的intent参数,同时显示onHandlerIntent方法执行的线程ID并非主线程,这是为什么呢?
下面我们来看一下service的源码:
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(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(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 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)}. */ @WorkerThread protected abstract void onHandleIntent(Intent intent);}
怎么样,代码还是相当的简洁的,首先通过定义我们可以知道IntentService是一个Service,并且是一个抽象类,所以我们在继承IntentService的时候需要实现其抽象方法:onHandlerIntent。
下面看一下其onCreate方法:
@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); }
我们可以发现其内部定义一个HandlerIThread(本质上是一个含有消息队列的线程);然后用成员变量维护其Looper和Handler,由于其Handler关联着这个HandlerThread的Looper对象,所以Handler的handMessage方法在HandlerThread线程中执行。
然后我们发现其onStartCommand方法就是调用的其onStart方法,具体看一下其onStart方法:
@Override public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); }
很简单就是就是讲startId和启动时接受到的intent对象传递到消息队列中处理,那么我们具体看一下其消息队列的处理逻辑:
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); } }
可以看到起handleMessage方法内部执行了两个逻辑一个是调用了其onHandlerIntent抽象方法,通过分析其onCreate方法handler对象的创建过程我们知道其handler对象是依附于HandlerThread线程的,所以其handeMessage方法也是在HandlerThread线程中执行的,从而证实了我们刚刚例子中的一个结论,onHandlerIntent在子线程中执行。
然后调用了stopSelf方法,这里需要注意的是stopSelf方法传递了msg.arg1参数,从刚刚的onStart方法我们可以知道我们传递了startId,参考其他文章我们知道,由于service可以启动N次,可以传递N次消息,当IntentService的消息队列中含有消息时调用stopSelf(startId)并不会立即stop自己,只有当消息队列中最后一个消息被执行完成时才会真正的stop自身。
通过上面的例子与相关说明,我们可以知道:
IntentService是一个service,也是一个抽象类;
继承IntentService需要实现其onHandlerIntent抽象方法;
onHandlerIntent在子线程中执行;
IntentService内部保存着一个HandlerThread、Looper与Handler等成员变量,维护这自身的消息队列;
每次IntentService后台任务执行完成之后都会尝试关闭自身,但是当且仅当IntentService消息队列中最后一个消息被执行完成之后才会真正的stop自身;
- 《android framework常用api源码分析》之IntentService意图服务
- IntentService意图服务 源码解读
- 《android framework常用api源码分析》之handler消息机制
- 《android framework常用api源码分析》之AsyncTask异步任务
- 《android framework常用api源码分析》之HandlerThread handler线程
- 《android framework常用api源码分析》之LruCache内存缓存
- 《android framework常用api源码分析》之Zygote进程
- 《android framework常用api源码分析》之SystemServer进程
- 《android framework常用api源码分析》之Launcher 程序
- 《android framework常用api源码分析》之Activity启动流程
- 《android framework常用api源码分析》之apk打包过程解析
- 《android framework常用api源码分析》之app 进程启动流程
- 《android framework常用api源码分析》之系统app启动安装流程
- 《android framework常用api源码分析》之 app应用安装流程
- Android之IntentService使用及源码分析
- android-----IntentService源码分析
- Android IntentService源码分析
- Android线程IntentService源码分析
- 17.12.11,web学习第二十三天,还有一年,努力吧青年Listener
- D3D11显示ffmpeg解码出的YUV420P数据
- 引用图片防盗链js
- vba 64位office Excel不用ActiveX ScriptControl转换为UTF8
- Excel 导出
- 《android framework常用api源码分析》之IntentService意图服务
- 完美测试-软件测试系列最佳实践[电子工业出版社].pdf
- matplotlib中文乱码解决
- python一些关于字符串的知识
- SMTP的几个端口的比较
- TCP与UDP区别
- 1.1 图像分类:数据驱动的方法,k-近邻,划分训练集/验证集/测试集
- 明德扬FPGA-培训班公开课-第09期-《FIFO的使用技巧》
- 【八中】区间覆盖问题