Hanler、Loop、MessageQueue的工作原理
1.Handler类介绍:
A.在新启动的线程中发送消息。
B.在主线程中获取、处理消息。
Handler类包含的方法:
void handleMessage(Message msg):处理消息的方法。该方法通常用于被重写。
final boolean hasMessages(int what):检查消息队列中是否包含what属性为指定值的消息
final boolean hasMessages(int what,Object object):检查消息队列中是否包含what属性为指定值且object属性为指定对象的消息。
多个重载的Message obtainMessage():获取消息。
sendEmptyMessage(int what):发送空消息
final boolean sendEmptyMessageDelayed(int what,long delayMillis):指定多少毫秒之后发送空消息。
final boolean sendMessage(Message msg ):立即发送消息。
final boolean sendMessageDelayed(Message msg,long delayMillis):指定多少毫秒之后发送消息。
2.Handler、Loop、MessageQueue的工作原理:
Message:Handler接收和处理的消息对象
Looper:每个线程只能拥有一个Looper。它的loop方法负者读取MessageQueue中的消息,读到信息之后就把消息交给发送该消息的Handler进行处理。
MessageQueue:消息队列,它采用先进先出的方式来管理Message。程序创建Looper对象时会在它的构造器中创建Looper对象。
Handler:它的作用有两个-发送消息和处理消息,程序使用Handler发送消息,被Handler发送的消息必须被送到指定的MessageQueue。也就是说,如果希望Handler正常工作,必须在当前线程中有一个MessageQueue,否则消息就没有MessageQueue进行保存了。不过MessageQueue是在由Looper负载管理的,也就是说,如果希望Handler正常工作必须在当前线程中有一个Looper对象。为了保存当前线程中有Looper对象,可以分两种情况处理。(A、B)
A.主UI线程中,系统已经初始化了一个Looper对象,因此程序直接创建Handler即可,然后就可通过Handler来发送消息、处理消息。
B.程序员自己启动的子线程,程序员必须自己创建一个Looper对象,并启动它。创建Looper对象调用它的perpare()方法即可。
3.总结:
Looper:每一个线程只有一个Looper,它负责管理MessageQueue,会不断地从MessageQueue中取出消息,并将消息分给对应的Handler处理。
MessageQueue:由Looper负责管理。它采用先进先出来管理Message。
Handler:它能把消息发送给Looper管理的MessageQueue,并负责处理Looper分给它的消息。
4.示例
自动播放图片示例:
Handler在主UI线程中时(在drawable中添加一些图片)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imgView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class HandlerActivity extends Activity { //定义图片数组 int [] images = new int[]{ R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4, R.drawable.a5, R.drawable.a6 }; int currentImageIndex=0;//当前显示的图片 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); final ImageView imgView = (ImageView)findViewById(R.id.imgView); final Handler handler = new Handler(){ //处理消息的方法,一般用于被重写 @Override public void handleMessage(Message msg) { if(msg.what == 0x1233){ imgView.setImageResource(images[currentImageIndex++ % images.length]);//设置显示的图片 } } }; //创建一个定时器 new Timer().schedule(new TimerTask() { @Override public void run() { handler.sendEmptyMessage(0x1233); } },0,1200); } }
求输入数范围内的所以质数示例:
Handler在程序员自己创建的线程中时
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="数字:"/> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/editNumber"/> </LinearLayout> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/btnGetCalPrime" android:text="获取质数"/> </LinearLayout>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class CalPrimeActivity extends Activity { EditText editNumber = null; String upper_num = "upper"; CalThead calThead; class CalThead extends Thread{ public Handler handler=null; @Override public void run() { Looper.prepare(); handler = new Handler(){ @Override public void handleMessage(Message msg) { if (msg.what == 0x123){ int upper = msg.getData().getInt(upper_num); List<Integer> nums = new ArrayList<Integer>(); outer: for (int i=2;i<=upper;i++){ for (int j=2;j<=Math.sqrt(i);j++){ if (i != 2 && i%j == 0){ continue outer; } } nums.add(i); } Toast.makeText(CalPrimeActivity.this,nums.toString(),Toast.LENGTH_LONG).show(); } } }; Looper.loop(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_calprime); editNumber = (EditText)findViewById(R.id.editNumber); calThead = new CalThead(); calThead.start(); Button btn = (Button)findViewById(R.id.btnGetCalPrime); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { cal(); } }); } public void cal (){ Message msg = new Message(); msg.what=0x123; Bundle bundle = new Bundle(); bundle.putInt(upper_num,Integer.parseInt(editNumber.getText().toString())); msg.setData(bundle); calThead.handler.sendMessage(msg); } }
效果图片: