您的位置:首页 > 移动开发 > Android开发

Android 消息机制与Handler和线程的关系

2017-02-28 11:32 459 查看
Android消息机制

    ·Android不可避免要操作一些耗时操作

       ·主线程堵塞影响用户交互,需要运行完后通知主线程更新

    ·下面我们来了解下Android的消息机制

                                          


               在主线程创建完成后系统会默认的创建一个looper对象,他就是个循环操作,循环的读取系统为主线程创建  好的 Message Queue中的消息(Messa Queue 中存放着许多的MSg),当looper读取到一个消息时候会为这个消息进行操作处理,当对应的处理执行完成后消息(msg)会被移除出消息队列(Message Queue),依次循环。

      

Message与Handler

    那么我们在开发过程中遇到的耗时操作是如何处理的呢?

     · 这里就用到handle了,首先Handle 对象调用sendMessage 向我们的Messagequeue里面插入一条消息。

     · 当looper读取到这条消息的时候,looper又调用Handler的对象来调用 dispartchMessage 和handleMessage,

      值得注意的是 dispatchMessage通常是系统使用的,我们自己定义的Messag消息处理通常是利用                               handleMessage

     · 对消息队列的响应操作只能通过Handle来进行,主线的looper发现MessageQueue改变就回去响应消息

     · 那个Handle发的消息就有那个handle来响应

                                                         


 ·Handler中的常用方法:

                           


                           


  

 简单的例子:

package com.example.chenzhu.myprojectblog;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MyHandleActivity extends AppCompatActivity {
Handler handler = new Handler(){
//接受消息并且处理消息
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Toast.makeText(MyHandleActivity.this, "handle Message What="+msg.what, Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_handle);
Button button = (Button)findViewById(R.id.sendHandle);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Message msg  =  new Message();//建立一个消息
msg.what=1;
handler.sendMessage(msg);//发送一个消息
}
});
}
}


Thread与Handler

        然而在主线程,如果looper在messagequeue里面读取到一个耗时操作或者死循环消息,然后还是会交给Handle  对象调用dispatchMessage来处理这个消息。而此时我们在次通过Handle 网MessageQueue里面发送一条消息          Looper读取到后有交给Handle对象处理,而此时系统还在处理上一个耗时操作。那么会怎样呢??  
  著名的ANR就来了,所以我们可以得到一下结论。   

         

          · Handler的sendMessage可以在其他线程中运行(本身并不需要刷新界面,只需要发送消息)

          · 耗时操作又必须在其他线程中运行。

         
· 所以耗时操作在子线程完成后通过handle发送message通知主线程来完成UI线程更新UI。

 


 我们在上面的例子上在进一步进行简单的升级:

package com.example.chenzhu.myprojectblog;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MyHandleActivity extends AppCompatActivity {
Handler handler = new Handler(){
//接受消息并且处理消息
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==1) {
Toast.makeText(MyHandleActivity.this, "耗时操作开始" + msg.what, Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(MyHandleActivity.this, "耗时操作结束可以更新UI" + msg.what, Toast.LENGTH_SHORT).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_handle);
Button button = (Button)findViewById(R.id.sendHandle);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Message msg  =  new Message();//建立一个消息
msg.what=1;
handler.sendMessage(msg);//发送一个消息
new  MyTheard().start();
}
});
}
//模拟耗时操作
class  MyTheard extends  Thread{
@Override
public void run() {
super.run();
try {
sleep(5);
//模拟耗时操作结束 发送消息
Message msg  =  new Message();
msg.what=2;
handler.sendMessage(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐