在我们使用Handler传递信息时,其实都是通过Looper通道的,当建立一个Handler对象时都是通过了LOOPER平时我们都是自动生成,但是当使用到用户自定义类handler就要自己手工调。
下面实现一个实例讲述looper作用:
布局文件代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="fill_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <TextView android:id="@+id/info" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/but" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="22dp" android:onClick="click" android:text="启动" /> </LinearLayout>
主Activity代码:
public class MainActivity extends Activity { private TextView info; private static final int set=1; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.info=(TextView)super.findViewById(R.id.info); } public void click(View v){ switch(v.getId()){ case R.id.but: Looper looper=Looper.myLooper(); MyHandler myhandler=new MyHandler(looper); myhandler.removeMessages(0);//清空所有的消息队列 String data="ee工作室创造科技前沿"; Message msg=myhandler.obtainMessage(set, 1, 1,data); myhandler.sendMessage(msg); break; } } private class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ switch(msg.what){ case 1: MainActivity.this.info.setText(msg.obj.toString()); } } } }
显示效果如下:
看到这里你是不是举得奇怪,就是明明不用Looper只用Handler和Message也能实现这样的功能。那么接下来我们要变形啦,用另一种变形代码深入理解Looper通道
在主线程子线程各自设置一个Handler处理,并且开启通道,通道会不惑目前使用通道的线程。通道因为是隐式我们只能通过这种方式了解主子线程传递消息的过程
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="fill_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <TextView android:id="@+id/info" android:text="等待子线程发送消息" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/but" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="22dp" android:onClick="click" android:text="交互" /> </LinearLayout>
这里info实现显示主线程接收到的信息,按键表示主线程发送给子线程的信息
主函数代码
ublic class MainActivity extends Activity { private TextView info; private static final int SetMain = 1; private static final int SetChild = 2; private Handler mainHandler, childHandler; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.info = (TextView) super.findViewById(R.id.info); MainActivity.this.mainHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case SetMain: MainActivity.this.info.setText("主线程接受到的数据: "+msg.obj.toString()); } } }; new Thread(new ChildThread(),"child thread").start(); } public void click(View v) { if(MainActivity.this.childHandler!=null){ Message childmsg=MainActivity.this.childHandler.obtainMessage(); childmsg.obj=MainActivity.this.mainHandler.getLooper().getThread().getName() +"--->儿子我来啦"; childmsg.what=SetChild; MainActivity.this.childHandler.sendMessage(childmsg); } } protected void onDestroy(){ super.onDestroy(); MainActivity.this.childHandler.getLooper().quit();//结束队列 } private class ChildThread implements Runnable { public void run() { Looper.prepare();//初始化队列 MainActivity.this.childHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case SetChild: System.out.println("主线程发给子线程的消息: "+msg.obj); //创建Message发给主线程 Message toMain=MainActivity.this.childHandler.obtainMessage(); toMain.obj="这是子线程发给主线程的消息:"+super.getLooper().getThread().getName(); toMain.what=SetMain; MainActivity.this.mainHandler.sendMessage(toMain); } } }; Looper.loop();//启动该线程的消息队列 } } }
这里很重要一点是建立Looper通道,如果不建立,子线程无法向主线程发送消息
首先我们按交互按钮,控制台输出:
这里说明子线程接受到了主线程发送的信息,并且显示当前使用通道线程是main主线程
主线程接收效果
同理学到这里相信还是很多人有疑问,当主线程发送给子线程的信息为什么不直接更新在UI上,反而要通过后天输出,这里还是强调一点,在安卓中,不支持子线程直接向UI更新,如果要实现的话,就只使用一个handler实现。
相关推荐
Android 消息处理机制之四: 消息循环 Looper 及其源码解析 http://blog.csdn.net/ahuier/article/details/17103517
Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用,使用Looper....
详细描述了Android的消息处理机制中,Looper和handler类详解
Looper Count测试Looper个数工具apk
bootstrap-looper 模版 bootstrap-looper 模版 bootstrap-looper 模版
Android系统的UI线程是一种带消息循环(Looper)机制的线程,同时Android也提供了封装有消息循环(Looper)的HandlerThread类,这种线程,可以绑定Handler()对象,并通过Handler的sendMessage()函数向线程发送消息,...
是Handler和消息队列之间通讯桥梁,程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列。Looper也把消息队列里的消息广播给所有的Handler:Handler接受到消息后调用handleMessage进行处理. 4、...
Android Looper的详细介绍,、android初学者可以下载来看看
android源码中包含了大量的设计模式, 除此以外, android sdk还精心为我们设计了... 其实还有一个Message Queue(消息队列) , 但是MQ被封装到Looper里面了, 我们不会直接与 MQ打交道, 因此我没将其作为核心类。
自己写的关于Android的Looper的示例程序。在主线程即UI线程外,新建一个Looper线程,并用Messenger和Handler来处理message和posted runnable。程序中,在负线程中默认加了一个3s的线程等来,来帮助理解sent message...
关于Looper的使用,可以在任意2个线程间通讯。
Handler和looper详解.
Android应用程序消息处理机制(Looper、Handler)分析
个人购买的资源,仅供学习使用,请勿用做商业用途,流行的Bootstrap框架,用于后台管理,风格简约
这次项目用到的主要是Handler Thread Looper,希望对这三者关系还不是很清楚的人能通过我的项目读懂,当然我也不敢保证一定能
Handler,AsyncTask,Looper自定义线程使用示例,自定义线程与UI线程交互,访问UI线程控件
Handler+Looper+MessageQueue
http://blog.csdn.net/lindonglian/article/details/43316239 不使用默认的looper
android looper handler 子线程 主线程详解