使用
MyIntentService.java

public class MyIntentService extends IntentService {

/**
* 是否正在运行
*/
private boolean isRunning;

/**
*进度
*/
private int count;

public MyIntentService() {
super("test");
}

/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public MyIntentService(String name) {
super(name);
}

@Override
protected void onHandleIntent(Intent intent) {
Logout.e("onHandleIntent"+intent.getStringExtra("name"));
try {
Thread.sleep(1000);
isRunning = true;
count = 0;
while (isRunning) {
count++;
if (count >= 100) {
isRunning = false;
}
Thread.sleep(50);
Logout.e("线程运行中..."+ count);
}

} catch (InterruptedException e) {
e.printStackTrace();
}
Logout.e("结束了任务");
}

@Override
public void onDestroy() {
super.onDestroy();
Logout.e("线程结束运行..." + count);
}

public static class Logout{
private static final String TAG = "Logout";
public static void e(String conent){
Log.d(TAG, "e: "+conent);
}
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public classTestActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task);

startService(new Intent(this, MyIntentService.class));
new Handler().post(new Runnable() {
@Override
public void run() {
//延迟一段时间,发送第二次消息
Intent intent = new Intent(AsyncTaskActivity.this, MyIntentService.class);
intent.putExtra("name", "helloWorld");
startService(intent);
}
});
}

@Override
protected void onDestroy() {
super.onDestroy();
// handlerThread.quit();
// unbindService(serviceConnection);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
上面就是简单的使用IntentService的教程。 IntentService是一个抽象类,所以需要自己集成实现,这里有两点需要注意。

自己实现的类需要提供无参的构造函数
IntentService 是在onHandleIntent中处理耗时操作,这里的intent 就是startService中的intent.
源码分析
我们首先来看一下IntentService 的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();
//构造一个IntentService,并启动
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();

//使用HandlerThread 的looper 构造一个handler,这样就可以从HandlerThread接收发送消息
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HandlerThread中比较值得关注的就是run方法。

@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
这里的代码也比较简单,流程基本上就是在非ui thread中构建Handler的标准流程,然后会走到 Looper.loop();中进入死循环。所以HandlerThread在使用结束以后,需要记得调用quit方法,停止死循环。

关注完oncreate方法,我们来着重观察一下IntentServcie的onstart 和 onStartCommand方法

@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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
可以看到这里利用了onStartCommand 每次startService每次都会调用onStartCommand的特点,用来给IntentService传递消息。IntentService收到消息后,就会调用mServiceHandler 将消息发送出去。这里主要的作用是将主线程的信息传递到HandlerThread。所以接下来,我们来看下ServiceHandler的具体的实现。

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);
}
}
---------------------

IntentService和HandlerThread的使用以及源码阅读的更多相关文章

  1. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  2. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  3. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  4. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  5. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  6. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  7. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

  8. 【原】AFNetworking源码阅读(二)

    [原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...

  9. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

随机推荐

  1. Ubuntu14 中安装 VMware10 Tools工具<2>

    网上说已经针对上一篇提到的无法显示共享文件夹的问题做了补丁.补丁地址是https://github.com/rasa/vmware-tools-patches,我没有成功,还是出现"hgfs ...

  2. kettle_删除“共享输出表”引发的错误

    原创作品.出自 "深蓝的blog" 博客.欢迎转载,转载时请务必注明出处,否则追究版权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanlong ...

  3. JavaScript的原生引用类型

    引用类型是一种数据结构,用于将数据和功能组织在一起,也常称做类.ECMAScript从技术上说是一门面向对象的语言.但它不具备传统的面向对象语言所支持的类和接口等基本结构. Object类型 大多数引 ...

  4. web的自己主动化公布

    </pre>基于眼下业务的版本号.使用的maven 及tomcat <p></p><p>假设我们使用 Jenkins 公布是比較好的,可是存在一定的问题 ...

  5. SmartSchool CC校友录V8(毕业入世版)

    SmartSchool CC校友录V8(毕业入世版) 使用说明 CC校友录V8(毕业入世版) 主要面向毕业后在某城市工作的校友,给大家构建一个充分交流的平台,“人脉”积累是本软件的功能特色,为此淡化了 ...

  6. 并行运维工具pssh的安装及实战应用

    并行运维工具pssh的安装及实战应用 - CSDN博客 https://blog.csdn.net/field_yang/article/details/68066468

  7. luogu1641 [SDOI2010]生成字符串

    题目大意 把$n$个$1$和$m$个$0$组成字符串,在任意的前$k$个字符中,$1$的个数不能少于$0$的个数.求这样的字符串的个数.$1\leq m\leq n\leq 1000000$. 原始模 ...

  8. java 内存模型 ——学习笔记

    一.Java 内存模型 java内存模型把 Java 虚拟机内部划分为线程栈和堆 下面这张图演示了调用栈和本地变量存放在线程栈上,对象存放在堆上.      ==>>  一个局部变量可能是 ...

  9. go语言笔记——多值函数,本质上和nodejs的回调很像,不过nodejs是回调的第一个参数是err,而golang里是第二个!

    5.2 测试多返回值函数的错误 Go 语言的函数经常使用两个返回值来表示执行是否成功:返回某个值以及 true 表示成功:返回零值(或 nil)和 false 表示失败(第 4.4 节).当不使用 t ...

  10. NodeJs函数式编程

    虽然标题是NodeJS函数式编程,但实际上NodeJS 是一个框架,不是一种语言,其采用的语言是 JavaScript.而JavaScript是一种典型的多范式编程语言,算不上是函数式语言,但它有函数 ...