IntentService源码分析
来源:互联网 发布:淘宝全屏首页怎么做 编辑:程序博客网 时间:2024/05/22 08:04
接触过Android的同学都应该知道Service,Android四大组件之一嘛,应该都很熟悉了,咋一看IntentService那又是什么鬼呢?
其实IntentService也是一个Service,是用来处异步任务的,比如说下载一个文件,处理耗时操作,当任务处理完成后这个Service会自动关闭。那么为什么需要IntentService呢?我们知道Service虽然被大家经常说是后台服务,但是Service所运行的线程其实还是主线程,不能执行耗时操作,会出现ANR导致应用卡死的假象,给用户不好的体验。所以如果我们要在Service里面处理耗时操作那就要手动去开启一个线程,google为了方便我们,就开发了IntentService给我们解决了自己手动开启线程的问题。下面我将带领大家一起来分析下IntentService
IntentService的使用
下面简单的模拟一个文件下载的操作,比如我们应用中经常使用到软件更新,当检测到软件更新的时候,自动下载apk,然后安装,这个场景最适合使用IntentService,因为下载apk的Service是一次性的,下载完成后就没必要存在可。所以我们新建一个UpdateService.java,代码如下:
package com.wms.github.intentservice;import android.app.IntentService;import android.content.Intent;import android.support.annotation.Nullable;import android.util.Log;/** * Created by 王梦思 on 2017/5/26. */public class UpdateService extends IntentService { private static final String TAG = "UpdateService"; public UpdateService(String name) { super(name); } public UpdateService() { super(""); } @Override protected void onHandleIntent(@Nullable Intent intent) { Log.e("UpdateService","onHandleIntent..."); if (intent != null) { String path = intent.getStringExtra("apkFilePath"); downloadApk(path); } } private void downloadApk(String path) { Log.e("UpdateService",path); //模拟耗时操作,这里就不真的下载文件了 try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } //这里代码执行完成后,Service就停止了 } @Override public void onCreate() { super.onCreate(); Log.e(TAG, "onCreate..."); } @Override public void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy..."); }}
MainActivity.java代码如下:
package com.wms.github.intentservice;import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;/** * Created by 王梦思 on 2017/5/26. */public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.start_service).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, UpdateService.class); intent.putExtra("apkFilePath","http://www.baidu.com/apk/demo.apk"); startService(intent); } }); }}
布局文件activity_main.xml代码如下:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.wms.github.intentservice.MainActivity"> <Button android:id="@+id/start_service" android:layout_width="match_parent" android:layout_height="50dp" android:layout_centerInParent="true" android:text="下载apk"/></RelativeLayout>
当我们点击下载apk按钮的时候,则会开启UpdateService,先看下UpdateService执行的时候的日志。
05-26 10:39:42.573 21936-21936/com.wms.github.intentservice E/UpdateService: onCreate...05-26 10:39:42.574 21936-22017/com.wms.github.intentservice E/UpdateService: onHandleIntent...05-26 10:39:42.575 21936-22017/com.wms.github.intentservice E/UpdateService: http://www.baidu.com/apk/demo.apk05-26 10:39:42.575 21936-22017/com.wms.github.intentservice E/UpdateService: 正在下载安装包...05-26 10:39:47.576 21936-22017/com.wms.github.intentservice E/UpdateService: 安装包下载完成...05-26 10:39:47.581 21936-21936/com.wms.github.intentservice E/UpdateService: onDestroy...
分析下UpdateService的执行顺序,顺序依次是onCreate–>onHandleIntent–>执行任务代码–>onDestroy,所以我们一般的处理异步任务的逻辑都是在onHandleIntent里面去做的,当这里面的任务逻辑处理完成后,服务就自动销毁了,将不会占用任何的系统资源。
通过上面的简单分析,相信大家已经知道IntentService是怎么使用的,但是我们要作为一个合格的程序员,应该知其然知其所以然,下面将从源码的角度来分析下IntentService。
源码分析IntentService
由于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); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } } public IntentService(String name) { super(); mName = name; } public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } @Override public void onCreate() { 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); } @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(); } @Override @Nullable public IBinder onBind(Intent intent) { return null; } @WorkerThread protected abstract void onHandleIntent(@Nullable Intent intent);}
可以看出IntentService的代码其实也就不到100行,还是很简单的。
当我们开启服务的时候,第一个执行的方法是onCreate方法,所以我们看下IntentService的onCreate方法里面创建了一个HandlerThread,HandlerThread其实就是一个继承Thread的类,只不过里面给我们新建了一个Looper。然后实例化了mServiceHandler,其实就是一个包含了Looper的Handler,我们一般创建一个Handler的时候都没有传递Looper,其实默认就是传递了主线程的Looper,这个主线程的Looper是在哪里创建的呢?其实是在我们应用开启的时候ActivityThread.java中的main方法里面创建的。这里扯远了,就不多说了。
当onCreate执行完成之后,就会调用onStart方法,在onStart方法里面创建了一个消息对象,通过onCreate实例化的mServiceHandler发送一个消息,这时候就会调用到IntentService 中静态内部类ServiceHandler的handleMessage方法,我们所说的onHandleIntent就是在handleMessage里面,onHandleIntent是一个抽象方法,所以这就是为什么我们继承IntentService的时候为什么需要重新onHandleIntent方法了。
当onHandleIntent执行完成之后,我们回到上面所说的handleMessage方法内部,在onHandleIntent下面还有一行代码就是stopSelf(),stopSelf就是停止当前的Service,这也就是为什么我们的异步任务处理完成后Service会自动停止了。
当Service停止时,就会调用onDestroy方法咯,整个流程到这里就讲解清楚了。总结一下,其实ItentService没什么神奇的地方,就是结合了Handler + Looper + Messeage来完成的,这个其实我们早就滚瓜烂熟了。
代码传送门:http://github.com/wms1993/blog_intentservice_demo
- IntentService源码分析
- IntentService源码分析
- IntentService源码分析
- IntentService源码分析
- IntentService源码分析
- IntentService源码分析
- 从源码分析IntentService
- IntentService源码分析
- IntentService源码分析
- IntentService 源码分析
- IntentService 源码分析
- intentservice源码分析
- android-----IntentService源码分析
- IntentService的源码分析
- IntentService源码分析
- IntentService源码分析
- IntentService源码分析
- IntentService源码分析
- 指纹模块调用
- LeetCode 60 Permutation Sequence
- Linux常用操作
- 时钟问题
- Sublime Text 3 设置
- IntentService源码分析
- java基本常识1
- Linux下Ubuntu关闭触摸板(TinkPad)
- 堆排-寻找大富翁.cpp
- spring基础知识
- 不止互联网 开源软件正在一步步推动汽车科技的创新
- MySQL索引
- Java多线程-工具篇-BlockingQueue
- 教你如何理解DSP、SSP、RTB、ADX名词