行业资讯

Android -- Looper.prepare()和Looper.loop()

发布时间:2026/8/27 12:43:25
Android -- Looper.prepare()和Looper.loop() Looper.prepare()和Looper.loop()Android中的Looper类是用来封装消息循环和消息队列的一个类用于在android线程中进行消息处理。handler事实上能够看做是一个工具类。用来向消息队列中插入消息的。(1) Looper类用来为一个线程开启一个消息循环。 默认情况下android中新诞生的线程是没有开启消息循环的。主线程除外主线程系统会自己主动为其创建Looper对象开启消息循环。 Looper对象通过MessageQueue来存放消息和事件。一个线程仅仅能有一个Looper。相应一个MessageQueue。(2) 一般是通过Handler对象来与Looper进行交互的。Handler可看做是Looper的一个接口。用来向指定的Looper发送消息及定义处理方法。 默认情况下Handler会与其被定义时所在线程的Looper绑定比方Handler在主线程中定义。那么它是与主线程的Looper绑定。mainHandler new Handler() 等价于new HandlerLooper.myLooper(). Looper.myLooper()获取当前进程的looper对象类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。(3) 在非主线程中直接new Handler() 会报例如以下的错误: E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception E/AndroidRuntime( 6173): java.lang.RuntimeException: Can’t create handler inside thread that has not called Looper.prepare() 原因是非主线程中默认没有创建Looper对象须要先调用Looper.prepare()启用Looper。(4) Looper.loop(); 让Looper開始工作从消息队列里取消息处理消息。注意写在Looper.loop()之后的代码不会被执行这个函数内部应该是一个循环当调用mHandler.getLooper().quit()后。loop才会中止其后的代码才干得以执行。(5) 基于以上知识可实现主线程给子线程非主线程发送消息。把以下样例中的mHandler声明成类成员在主线程通过mHandler发送消息就可以。Android官方文档中Looper的介绍 Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.Most interaction with a message loop is through the Handler class.This is a typical example of the implementation of a Looper thread, using the separation of prepare() and loop() to create an initial Handler to communicate with the Looper.class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); }假设线程中使用Looper.prepare()和Looper.loop()创建了消息队列就能够让消息处理在该线程中完毕。android HandlerThread使用小例之前研究过handler 和 looper 消息队列。只是android里的handler不是另外开启线程来运行的。还是在主UI线程中假设想另启线程的话须要用到HandlerThread来实现。在使用HandlerThread的时候须要实现CallBack接口以重写handlerMessage方法。在handlerMessage方法中来处理自己的逻辑。下来给出一个小样例程序。layout文件非常easy就一个button来启动HanlderTread线程?xml version1.0 encodingutf-8? LinearLayout xmlns:android“http://schemas.android.com/apk/res/android” android:layout_width“fill_parent” android:layout_height“fill_parent” android:orientation“vertical” TextView android:layout_width“fill_parent” android:layout_height“wrap_content” android:text“string/hello” / Button android:id“id/handlerThreadBtn” android:layout_width“wrap_content” android:layout_height“wrap_content” android:text“startHandlerThread” /Activity代码例如以下package com.tayue; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.os.HandlerThread; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; /\*\* \* \* author xionglei \* \*/ public class TestHandlerActivity extends Activity implements OnClickListener{ public Button handlerThreadBTN; MyHandlerThread handlerThread; Handler handler; /\*\* Called when the activity is first created. \*/ Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //打印UI线程的名称 System.out.println(onCreate CurrentThread Thread.currentThread().getName()); setContentView(R.layout.main); handlerThreadBTN (Button) findViewById(R.id.handlerThreadBtn); handlerThreadBTN.setOnClickListener(this); handlerThread new MyHandlerThread(myHanler); handlerThread.start(); //注意 这里必须用到handler的这个构造器由于须要把callback传进去从而使自己的HandlerThread的handlerMessage来替换掉Handler原生的handlerThread handler new Handler(handlerThread.getLooper(), handlerThread); } Override public void onClick(View v) { //点击button后来开启线程 handler.sendEmptyMessage(1); } private class MyHandlerThread extends HandlerThread implements Callback { public MyHandlerThread(String name) { super(name); } Override public boolean handleMessage(Message msg) { //打印线程的名称 System.out.println( handleMessage CurrentThread Thread.currentThread().getName()); return true; } } }点击button。打印的日志例如以下这里点击了3次 07-06 09:32:48.776: I/System.out(780): onCreate CurrentThread main 07-06 09:32:55.076: I/System.out(780): handleMessage CurrentThread myHanler 07-06 09:32:58.669: I/System.out(780): handleMessage CurrentThread myHanler 07-06 09:33:03.476: I/System.out(780): handleMessage CurrentThread myHanlerHandlerThread就这么简单。当然 android自己也有异步线程的handler就是AsyncTask。这个类就是封装了HandlerThread 和handler来实现异步多线程的操作的。相同能够这样使用private boolean iscancel false; //用户手动取消登录的标志位 handlerThread new HandlerThread(myHandlerThread); handlerThread.start(); handler new MyHandler(handlerThread.getLooper()); // 将要运行的线程对象加入到线程队列中 handler.post(new Runnable() { Override public void run() { Message message handler.obtainMessage(); UserBean user Bbs.getInstance().Login(username, password);//耗时任务 Bundle b new Bundle(); b.putSerializable(user, user); message.setData(b); message.sendToTarget(); //或使用 handler.sendMessage(message); } }); class MyHandler extends Handler { public MyHandler(Looper looper) { super(looper); } Override public void handleMessage(Message msg) { if(iscancel false){ // 操作UI线程的代码 Bundle b msg.getData(); UserBean user (UserBean)b.get(user); ...... } } }Looper.prepare()和Looper.loop()就到这里更多的Android学习资料可以扫码免费领取Android基础课程资料包目录第一章 UI第一章 UI更有更多资料加微信免费领取