AndroidApp在线程中创建handler的方法讲解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
AndroidApp在线程中创建handler的⽅法讲解
相关概念
1.Handler:可以看做是⼀个⼯具类,⽤来向消息队列中插⼊消息的;
2.Thread:所有与Handler相关的功能都是与Thread密不可分的,Handler会与创建时所在的线程绑定;
3.Message:消息;
4.MessageQueue:消息队列,对消息进⾏管理,实现了⼀个Message链表;
5.Looper:消息循环,从MessageQueue中取出Message进⾏处理;
6.HandlerThread:继承Thread,实例化时⾃动创建Looper对象,实现⼀个消息循环线程.
在Android开发中经常会使⽤到线程,⼀想到线程,⼀般都会想到:
new Thread(){...}.start();
这样的⽅式。
这样如果在⼀个Activity中多次调⽤上⾯的代码,那么将创建多个匿名线程,如果这些线程的没有被销毁,那肯定会影响性能呢。
这个时候我么就想到了android提供的⼀个异步处理线程的类HandlerThread。
⼀般Handler的⽤法
Handler handler = new Handler(){...};
这样创建的handler是在主线程即UI线程下的Handler,即这个Handler是与UI线程下的默认Looper绑定的(当然也只有主线程才能这么⼲,⼦线程是⼲不了的,除⾮⾃⼰创建个looper)。
因此,有些时候会占⽤ui主线程,引起⼀些问题,所以我们就想到了重新创建个⼦线程,来处理handler。
使⽤HandlerThread解决问题
HandlerThread实际上继承于Thread,只不过它⽐普通的Thread多了⼀个Looper。
我们可以使⽤下⾯的例⼦创建Handler HandlerThread thread = new HandlerThread("MyHandlerThread");
thread.start();
创建HandlerThread时要把它启动了,即调⽤start()⽅法。
接着就是handler的使⽤,如下:
mHandler = new Handler(thread.getLooper());
//TODO:you can post or send something....
创建Handler时将HandlerThread中的looper对象传⼊。
那么这个mHandler对象就是与HandlerThread这个线程绑定了(这时就不再是与UI线程绑定了,这样它处理耗时操作将不会阻塞UI)。
线程中消息处理的流程图
消息插⼊队列的位置由参数uptimeMillis来确定。
Handler与线程的关系
1.HandlerThread就是⼀个封装了Looper的Thread.
2.Handler会与实例化时所在的线程绑定.
UI线程与⼦线程通信相关
1.需要更新UI,则需要使⽤与主线程绑定的Handler发送消息,若使⽤在⼦线程中创建的Handler则会抛出异常;
2.⼦线程中实例化Handler对象⾸先需要调⽤Looper.prepare(),否则会抛出异常;
3.调⽤Looper.loop()⽅法消息循环才会启动;
使⽤Handler时⼀些需要注意的地⽅
Looper.prepare(),主线程使⽤handler,系统默认prepare了,⼦线程中创建handler必须在前⾯Looper.prepare(),后⾯加上Looper.loop();
源码中:
主线程:
在程序启动的时候,系统已经帮我们⾃动调⽤了Looper.prepare()⽅法。
查看ActivityThread中的main() public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
请注意Looper.prepareMainLooper():
public static final void prepareMainLooper() {
prepare();
setMainLooper(myLooper());
if (Process.supportsProcesses()) {
myLooper().mQueue.mQuitAllowed = false;
}
}
⼦线程:
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare()
handler2 = new Handler();
Looper.loop()
}
}).start();
如果没有Looper.prepare().会报错:
Can't create handler inside thread that has not called Looper.prepare()
因为没looper对象创建
looper.prepare()源码:
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}。