Android多线程(三)
上次讲了关于Android多线程中通信中Thread、Handler、Looper等的基础概念和基本用法,用现实世界两个人写信交流的过程来理解是再好不过了。但是不得不说这一套完整的细节的确很繁琐,好在Android中为我们提供了另一个简化的API——HandlerThread,通过使用HandlerThread,我们可以以一种简单的方式开启线程、进行线程通信。Let's do it!
三、HandlerThread
1)参考文档:http://developer.android.com/reference/android/os/HandlerThread.html
前面的连篇文章中我都贴出来相应内容的官方文档地址,也斗胆说了一下读文档的重要性。这次我们换一种方式——读源代码,好的代码本身就是一份文档,除了会写还得能读!如何找到Android的源码?不管你用的是不再更新的ADT+Eclipse还是AS(Android studio),你的电脑里一定得下载sdk,在sdk目录下有个叫sources的文件夹,里面放的就是Android的系统源码。(开源大法好!)如果你没有,那就“翻墙”下一份,如何快速更新sdk我会在下一篇博客里写......
2)HandlerThread源码:
我在这把源码贴出来方便查看(我电脑上的源码是Android-22的)
package android.os; /**
* Handy class for starting a new thread that has a looper. The looper can then be
* used to create handler classes. Note that start() must still be called.
*/
public class HandlerThread extends Thread {
//线程的优先级
int mPriority; //线程id
int mTid = -1; //与线程绑定的Looper对象
Looper mLooper; public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
} /**
* Constructs a HandlerThread.
* @param name
* @param priority The priority to run the thread at. The value supplied must be from
* {@link android.os.Process} and not from java.lang.Thread.
*/
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
} /**
* Call back method that can be explicitly overridden if needed to execute some
* setup before Looper loops.
* 这里是你需要实现的部分,你的在这里实现对Handler的准备工作,定义你的Hadnler并实现
*handlerMessage(Message msg)方法。
*/
protected void onLooperPrepared() {
} @Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
} /**
* This method returns the Looper associated with this thread. If this thread not been started
* or for any reason is isAlive() returns false, this method will return null. If this thread
* has been started, this method will block until the looper has been initialized.
* @return The looper.
*/
public Looper getLooper() {
if (!isAlive()) {
return null;
} // If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
} /**
* Quits the handler thread's looper.
* <p>
* Causes the handler thread's looper to terminate without processing any
* more messages in the message queue.
* </p><p>
* Any attempt to post messages to the queue after the looper is asked to quit will fail.
* For example, the {@link Handler#sendMessage(Message)} method will return false.
* </p><p class="note">
* Using this method may be unsafe because some messages may not be delivered
* before the looper terminates. Consider using {@link #quitSafely} instead to ensure
* that all pending work is completed in an orderly manner.
* </p>
*
* @return True if the looper looper has been asked to quit or false if the
* thread had not yet started running.
*
* @see #quitSafely
*/
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
} /**
* Quits the handler thread's looper safely.
* <p>
* Causes the handler thread's looper to terminate as soon as all remaining messages
* in the message queue that are already due to be delivered have been handled.
* Pending delayed messages with due times in the future will not be delivered.
* </p><p>
* Any attempt to post messages to the queue after the looper is asked to quit will fail.
* For example, the {@link Handler#sendMessage(Message)} method will return false.
* </p><p>
* If the thread has not been started or has finished (that is if
* {@link #getLooper} returns null), then false is returned.
* Otherwise the looper is asked to quit and true is returned.
* </p>
*
* @return True if the looper looper has been asked to quit or false if the
* thread had not yet started running.
*/
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
} /**
* Returns the identifier of this thread. See Process.myTid().
*/
public int getThreadId() {
return mTid;
}
}
这里我们重点看两个方法:
protected void onLooperPrepared() 这是一个在拓展类中需要重写的方法,它完成准备工作,一般是对Handelr进行定义。比如接受到主线程发来的消息时如何做出应对。在后面的示例中我就会对Handler进行定义,在handleMessage(Message msg)中定义行为。
public void run() 再看这个方法里的内容是不是感到很熟悉,理解了Thread、Handler、Looper等概念后,是不是很容易就读懂了它的意思。对了,拓展HandlerThread时,如果要override run方法一定要记得调用父类的run() 。
对于其他的方法,在这里就不赘述了,每个方法的前面的注释就详细说明了它们的作用。
3)一个简单的示例:
还是一样的,我用一个示例来说明HandlerThread的用法。还是一样的开启线程,等到接收到主线程发来的消息,然后打印打印日志。
布局:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="HandlerThread"/> <Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="send message"/>
拓展的HandlerThread类:
public class MyThread extends HandlerThread { private static final String TAG = "MyThread";
private Handler mHandler; public MyThread() {
super(TAG);
} @Override
protected void onLooperPrepared() {
super.onLooperPrepared();
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what == MainActivity.MSG_MAIN){
handlerRequest(msg.obj);
}
}
};
return;
} private void handlerRequest(Object obj){
Log.d(TAG, "handlerRequest:" + obj + ",thread:" + Thread.currentThread().getName());
Looper looper = Looper.getMainLooper();
Handler handler = new Handler(looper);
handler.post(new Runnable() {
@Override
public void run() {
Log.d(TAG,"message is handled,thread:"+Thread.currentThread().getName());
return;
}
});
return;
} public Handler getHandler() {
return mHandler;
}
}
这次我使用了post方法很主线程进行通信。
Activity代码:
public class MainActivity extends AppCompatActivity { public static final int MSG_MAIN = 100; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); final MyThread thread = new MyThread();
thread.start();
thread.getLooper(); final Button sendButton = (Button) findViewById(R.id.button);
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Handler handler = thread.getHandler();
Message msg = handler.obtainMessage();
msg.what = MainActivity.MSG_MAIN;
msg.obj="testing HandlerThread";
handler.sendMessage(msg);
return;
}
});
}
}
Logcat打印日志:
10-08 11:45:47.152 13949-14004/comfallblank.github.handlerthread D/MyThread: handlerRequest:testing HandlerThread,thread:MyThread
10-08 11:45:47.162 13949-13949/comfallblank.github.handlerthread D/MyThread: message is handled,thread:main
这次我在日志中加入了线程名称,这样就可以看出任务执行的线程了。
到这里,关于Android线程的内容算写完了,本来打算在国庆期间写完了,最后拖拖拉拉延迟了一天。还有国庆长假后第一天上课好累啊!就这样吧!下一篇关于如何快速更新sdk努力在这周写出来。
最后,欢迎大家交流,指正我不正确的地方。
邮箱:fallblank525@gmail.com QQ:1054746297
Android多线程(三)的更多相关文章
- android 多线程
本章讲述在android开发中,多线程的应用.多线程能够处理耗时的操作并优化程序的性能.本章主要介绍知识点,AsyncTask,Java线程池,ThreadPoolExecutor线程池类.本章案例只 ...
- Android多线程分析之五:使用AsyncTask异步下载图像
Android多线程分析之五:使用AsyncTask异步下载图像 罗朝辉 (http://www.cnblogs.com/kesalin) CC 许可,转载请注明出处 在本系列文章的第一篇<An ...
- android程序---->android多线程下载(一)
多线程下载是加快下载速度的一种方式,通过开启多个线程去执行一个任务,可以使任务的执行速度变快.多线程的任务下载时常都会使用得到断点续传下载,就是我们在一次下载未结束时退出下载,第二次下载时会接着第一次 ...
- Android多线程----异步消息处理机制之Handler详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- android 多线程断点续传下载
今天跟大家一起分享下Android开发中比较难的一个环节,可能很多人看到这个标题就会感觉头很大,的确如果没有良好的编码能力和逻辑思维,这块是很难搞明白的,前面2次总结中已经为大家分享过有关技术的一些基 ...
- android程序---->android多线程下载(二)
上篇我们讲到了android中下载的断点续传问题,今天我们开始学习下载的多线程问题.本次的多线程源码下载:androdi中多线程下载的实现代码.有关断点续传的问题,请参见博客:android程序--- ...
- java多线程以及Android多线程
Java 多线程 线程和进程的区别 线程和进程的本质:由CPU进行调度的并发式执行任务,多个任务被快速轮换执行,使得宏观上具有多个线程或者进程同时执行的效果. 进程:在操作系统来说,一个运行的程序或者 ...
- android多线程-AsyncTask之工作原理深入解析(上)
关联文章: Android 多线程之HandlerThread 完全详解 Android 多线程之IntentService 完全详解 android多线程-AsyncTask之工作原理深入解析(上) ...
- Andoid 更好的Android多线程下载框架
概述 为什么是更好的Android多线程下载框架呢,原因你懂的,广告法嘛! 本篇我们我们就来聊聊多线程下载框架,先聊聊我们框架的特点: 多线程 多任务 断点续传 支持大文件 可以自定义下载数据库 高度 ...
随机推荐
- 编程马拉松大赛试题及代码(C++实现)
前段时间牛客网举办了编程马拉松大赛,总共86道题,20天内完毕. 题目难度难中易都有.我发现这些题目,主要关注性能和思维. 非常多题目用常规方法是不能通过时间要求的.题目是来自于各大oj以及面试题.所 ...
- js进阶 10-5 jquery中的层级选择器有哪些
js进阶 10-5 jquery中的层级选择器有哪些 一.总结 一句话总结: 1.jquery中的层级选择器有哪些? 四种,后代,子代,兄弟,相邻兄弟 2.如何区别jquery中的层级选择器? 记住这 ...
- 【a601】雇佣计划
Time Limit: 1 second Memory Limit: 32 MB [问题描述] 一位管理项目的经理想要确定每个月需要的工人,他知道每月所需的最少工人数.当他雇佣或解雇一个工人时,会有一 ...
- 【Material Design视觉设计语言】开篇
作者:郭孝星 微博:郭孝星的新浪微博 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells Github:https://github.co ...
- 自绘实现半透明水晶按钮(继承CButton,设置BS_OWNERDRAW风格,覆盖DrawItem函数绘制按钮,把父窗口的背景复制到按钮上,实现视觉上的透明,最后通过AlphaBlend实现半透明)
运行效果 实现方法 1.给按钮加上BS_OWNERDRAW样式2.重载DrawItem函数,在这里绘制按钮3.关键之处就是把父窗口的背景复制到按钮上,实现视觉上的透明4.最后通过AlphaBlend实 ...
- 浅谈CAS(Compare and Swap) 原理
浅谈CAS原理java并发编程也研究了一段时间了,对CAS的原理总是不太理解,今天再研究了一下,记录一些自己的理解. 说到CAS,再java中的某些情况下,甚至jdk1.5以后的大多数情况,并发 ...
- Enhancing network controls in mandatory access control computing environments
A Mandatory Access Control (MAC) aware firewall includes an extended rule set for MAC attributes, su ...
- Access control differentiation in trusted computer system
A trusted computer system that offers Linux® compatibility and supports contemporary hardware speeds ...
- 卷积与反卷积、步长(stride)与重叠(overlap)
1. 卷积与反卷积 如上图演示了卷积核反卷积的过程,定义输入矩阵为 I(4×4),卷积核为 K(3×3),输出矩阵为 O(2×2): 卷积的过程为:Conv(I,W)=O 反卷积的过称为:Deconv ...
- TDM-GCC是从mingw-w64项目patch而来,全部使用静态链接,对线程不需要额外的DLL,默认使用SJLJ异常(真是好东西)
Windows版GCC之TDM-GCC 4.5.2 平时写 C/C++ 小程序的时候,不喜欢开VS,太庞大了,还要建项目.对于小程序,一个可以进行单文件编译的 IDE 是我的首选,我用的是 C-Fre ...