Android IntentService使用介绍以及源码解析
版权声明:本文出自汪磊的博客,转载请务必注明出处。
一、IntentService概述及使用举例
IntentService内部实现机制用到了HandlerThread,如果对HandlerThread不了解的话建议先看上篇文章:Android HandlerThread使用介绍以及源码解析。
IntentService是神马玩意?它就是一个Service,但是我们知道在Service中不能进行耗时操作,如果要进行耗时操作的话我们就需要自己new一个子线程在里面进行耗时操作,然而这一切谷歌工程师早就替我们做好了,只需使用IntentService即可,自己会启动一个子线程做耗时操作,无需我们自己管理子线程,并且完成任务后会自动停止。这么好的玩意赶紧看下怎么使用。
接下来我们编写一个小Demo,模拟在IntentService中进行网络通信,并且成功后通知主线程,主线程做出相应反应。Demo中通过广播接收者实现子线程与主线程的通信。
首先我们编写IntentService,如下:
public class MyIntentService extends IntentService { public static final String TAG = "WL"; public MyIntentService() {
//为子线程起一个名字
super("IntentService"); } //子线程中执行
@Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
if(null !=intent){
String action = intent.getAction();
if(action.equalsIgnoreCase(MainActivity.ACTION_START)){ String url = intent.getStringExtra(MainActivity.URL);
Log.i(TAG, "开始请求_URL:"+url);
//模拟网络请求
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, "请求成功");
//
handlerRequestSuccess();
}
}
} //
private void handlerRequestSuccess() {
// 发送广播通知主线程请求成功
Intent intent = new Intent(MainActivity.ACTION_START);
intent.putExtra("msg", "请求成功");
sendBroadcast(intent);
} }
主要逻辑就是继承IntentService,重写onHandleIntent方法,onHandleIntent运行在子线程可以进行耗时操作,在模拟网络请求成功的时候发送广播。
接下来看下MainActivity逻辑:
public class MainActivity extends Activity { //
public static final String ACTION_START= "START_HTTP_REQUEST";
public static final String URL= "URL";
private MyBroadcastReceiver myBroadcastReceiver; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//注册广播接收者
myBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_START);
registerReceiver(myBroadcastReceiver, filter);
} @Override
protected void onResume() {
//
super.onResume();
Intent intent = new Intent(this, MyIntentService.class);
intent.setAction(ACTION_START);
intent.putExtra(URL, "http://www.cnblogs.com/leipDao/");
startService(intent);//必须是start方式启动服务,bind方法无效,分析源码的时候就明白了
} @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(myBroadcastReceiver);
} private class MyBroadcastReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) { String action = intent.getAction();
if(action.equalsIgnoreCase(ACTION_START)){ String extra = intent.getStringExtra("msg");
Log.i(MyIntentService.TAG, "onReceive::::"+extra);
}
}
}
}
逻辑也是比较简单,onCreate的时候注册广播接收者,用于接收IntentService中模拟网络请求成功的时候发送的广播,onResume的时候启动服务。onDestroy的时候移除广播接收者。Demo比较简单,运行程序打印如下:
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);
}
} /**
* 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;
} 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();
} @Override
public IBinder onBind(Intent intent) {
return null;
} @WorkerThread
protected abstract void onHandleIntent(Intent intent);
}
很简短吧,出去注释不到100行,接下来我们分析重点部分。
24-27行,构造函数传递进来一个name,用于第40行初始化HandlerThread,就是子线程的名字。
接下来看34-45行onCreate()的时候:主要就是初始化一个HandlerThread以及ServiceHandler,7-17行发现ServiceHandler就是一个普通的Handler而已。看过上一篇Android HandlerThread使用介绍以及源码解析应该明白,ServiceHandler运行在子线程中,这里就不仔细解释了,不明白的地方可以查看Android HandlerThread使用介绍以及源码解析。
73-75行发现onBind的时候什么也没做,就是返回null,还记得demo中注释吗必须以start方式启动服务,因为bing方式启动什么也没做。
48-53行onStart的时候发送一个消息到ServiceHandler,第14行handleMessage的时候直接调用onHandleIntent方法,紧接着15行结束本次任务。
到这里主要流程就完了,其本质就是利用了HandlerThread保证ServiceHandler在子线程运行机制,在我们以start方式启动服务的时候,执行到service生命周期方法onStart的时候就会发送一个消息,然后在ServiceHandler中handleMessage方法执行onHandleIntent方法,子类重写此方法实现耗时任务即可。
好了,到此IntentService就分析完了,理解IntentService最核心的就是先理解HandlerThread。
本篇到此为止,希望对你有用。
Android IntentService使用介绍以及源码解析的更多相关文章
- Android HandlerThread使用介绍以及源码解析
摘要: 版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.HandlerThread的介绍及使用举例 HandlerThread是什么鬼?其本质就是一个线程,但是Han ...
- IPerf——网络测试工具介绍与源码解析(4)
上篇随笔讲到了TCP模式下的客户端,接下来会讲一下TCP模式普通场景下的服务端,说普通场景则是暂时不考虑双向测试的可能,毕竟了解一项东西还是先从简单的情况下入手会快些. 对于服务端,并不是我们认为的直 ...
- 【Android应用开发】EasyDialog 源码解析
示例源码下载 : http://download.csdn.net/detail/han1202012/9115227 EasyDialog 简介 : -- 作用 : 用于在界面进行一些介绍, 说明; ...
- IPerf——网络测试工具介绍与源码解析(1)
IPerf是一个开源的测试网络宽带并能统计并报告延迟抖动.数据包丢失率信息的控制台命令程序,通过参数选项可以方便地看出,通过设置不同的选项值对网络带宽的影响,对于学习网络编程还是有一定的借鉴意义,至少 ...
- Android Handler机制(四)---Handler源码解析
Handler的主要用途有两个:(1).在将来的某个时刻执行消息或一个runnable,(2)把消息发送到消息队列. 主要依靠post(Runnable).postAtTime(Runnable, l ...
- Android Handler机制(二)---MessageQueue源码解析
MessageQueue 1.变量 private final boolean mQuitAllowed;//表示MessageQueue是否允许退出 @SuppressWarnings(" ...
- IPerf——网络测试工具介绍与源码解析(2)
对于IPerf源码解析,我是基于2.0.5版本在Windows下执行的情况进行分析的,提倡开始先通过对源码的简单修改使其能够在本地编译器运行起来,这样可以打印输出一些中间信息,对于理解源码的逻辑,程序 ...
- Android Handler机制(三)----Looper源码解析
一.Looper Looper对象,顾名思义,直译过来就是循环的意思,从MessageQueue中不断取出message. Class used to run a message loop for a ...
- 【转载】Android IntentService使用全面介绍及源码解析
一 IntentService介绍 IntentService定义的三个基本点:是什么?怎么用?如何work? 官方解释如下: //IntentService定义的三个基本点:是什么?怎么用?如何wo ...
随机推荐
- 基于Vue.js的大型报告页项目实现过程及问题总结(一)
今年5月份的时候做了一个测评报告项目,需要在网页正常显示的同时且可打印为pdf,当时的技术方案采用jquery+template的方式,因为是固定模板所以并没有考虑报告的模块化区分,九月底产品提出新的 ...
- linux虚拟机局域网网卡配置
1:配置虚拟机 1-1:打开:虚拟机下编辑->虚拟网络编辑器 选择VMnet信息下的桥接模式,在“桥接到”下拉列表里选择自己的网卡. ...
- Android 开发笔记___spinner__适配器基础_arrayadapter
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout ...
- HTML资源定位器-URL
URL 也被称为网址. URL 可以由单词组成,比如 "www.baidu.com",或者是因特网协议(IP)地址:192.168.1.253. URL - Uniform Res ...
- C语言实现二叉树的基本操作
二叉树是一种非常重要的数据结构.本文总结了二叉树的常见操作:二叉树的构建,查找,删除,二叉树的遍历(包括前序遍历.中序遍历.后序遍历.层次遍历),二叉搜索树的构造等. 1. 二叉树的构建 二叉树的基本 ...
- 学习RocketMQ (一) 安装并且启动MQ
1.使用RocketMQ 的 软件要求 64bit OS, Linux/Unix/Mac is recommended;64bit JDK 1.8+;Maven 3.2.xGit 1)安装Linux ...
- 基于Cef内核的多店铺登录器(含源码)
公司是做电商的,在速卖通平台上开了若干店铺,每天都需要登录店铺打理,如:发货提交.获取运单号等.多个店铺的情况下,同时使用浏览器就会非常繁琐,如:要记住帐户名和密码,还要在不同店铺间切换.如果能够制作 ...
- 六:在线工具网站,让你PC上要装的软件少一半!
记住这几个在线工具网站,让你PC上要装的软件少一半! 一.uzer.me——丰富的云端应用聚合 这个云平台将我们常用的Office系列软件.Adobe家族的系列软件……乃至CAD制图都整合在了云端,随 ...
- c# 小小备忘录
一.简述 备忘录,相信大家生活中都使用过,比如记笔记.手机备忘录等等,这些都是记录自己灵感时所想.定期内想做的事情,好像跑题了,说说我的备忘录吧,我的备忘录功能上也就是增删改查的操作,另加到时提醒.语 ...
- Spring的IOC容器第一辑
一.Spring的IOC容器概述 Spring的IOC的过程也被称为依赖注入(DI),那么对象可以通过构造函数参数,工厂方法的参数或在工厂方法构造或返回的对象实例上设置的属性来定义它们的依赖关系,然后 ...