安卓新版本设计中,为了避免 anr(android not response)问题出现,所以不能再UI线程中访问耗时操作,只能创建子线程去访问,例如访问网络。但是为了安全又不能在子线程中访问UI,所以可以使用Handler去访问
安卓中为了解决上述问题,内置了一个消息队列机制。在子线程中将message放入Handler中,然后系统会自动去处理这些消息。
在程序中使用的过程如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.zl.itgeek.handler.MainActivity"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:text="发送消息"
android:onClick="click"
android:layout_height="wrap_content" />
<TextView
android:layout_width="match_parent"
android:id="@+id/tv_wait"
android:layout_height="match_parent" />
</LinearLayout>
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.ImageView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView tv_wait;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_wait = (TextView) findViewById(R.id.tv_wait);
}
public void click(View view){
new Thread(){
@Override
public void run() {
Message message = handler.obtainMessage();
message.what=100;
message.obj = "点击成功了";
handler.sendMessage(message);
//模拟耗时操作
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
Handler handler= new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==100){
tv_wait.setText(msg.what+"-----"+msg.obj.toString());
}
}
};
}
- 编写代码时先创建一个Handler 对象,可以是Handler 的子类也可以直接new Handler 的对象并重写
handleMessage()
方法。其中写上处理UI线程的操作。 然后再子线程中用上面handler对象的
handler.obtainMessage();
获取Message 对象,将要传递的数据保存到message 对象中,使用handler.sendMessage(message);
将消息发送到消息队列中,系统会自动执行其中的what用来标识一个消息,可以为任意整形数字。在Handler 类的handleMessage()方法中可以获取到来判断是那个消息。obj可以携带信息,在handler中可以用handler.obj获取到。