主线程(UI线程)不能执行耗时的操作,例如连网读数据,读本地文件等。这些操作必须放在子线程中执行,但子线程又涉及到UI更新,而更新UI只能在主线程进行。所以,Handler可解决这问题。Handler运行在主线程中,Handler与子线程之间通过Message对象传递消息,子线程通过sendMessage传递Message对象,Handler通过handerMessage进行更新UI。主线程发送消息给子线程,也可使用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:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="44dp"
android:id="@+id/tv"
android:text="你好 World!" />
<Button
android:layout_width="60dp"
android:layout_height="40dp"
android:text="发送"
android:id="@+id/btn"/>
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private Button btn;
private TextView tv;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.btn);
tv = (TextView)findViewById(R.id.tv);
Log.i("test","主线程名字 = " + Thread.currentThread().getName() +
"主线程id = " + Thread.currentThread().getId());
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
//主线程更新UI
tv.setText(msg.obj.toString());
break;
}
}
};
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//创建一个子线程
new Thread(){
@Override
public void run() {
Log.i("test","子线程名字 = " + Thread.currentThread().getName() +
"子线程id = " + Thread.currentThread().getId());
Message msg = handler.obtainMessage();
msg.what = 0;
msg.obj = Thread.currentThread().getName();
handler.sendMessage(msg);
}
}.start();
}
});
}
}
Logcat分析:
1. app启动,只有一个主线程:
主线程名字 = main主线程id = 1
2. 点击发送按钮,生成一个子线程:
09-29 子线程名字 = Thread-64520子线程id = 64520
09-29 子线程名字 = Thread-64521子线程id = 64521
09-29 子线程名字 = Thread-64522子线程id = 64522
09-29 子线程名字 = Thread-64523子线程id = 64523
09-29 子线程名字 = Thread-64524子线程id = 64524
09-29 子线程名字 = Thread-64525子线程id = 64525
09-29 子线程名字 = Thread-64526子线程id = 64526
09-29 子线程名字 = Thread-64527子线程id = 64527
----------
public class MainActivity extends AppCompatActivity {
private Button btn;
private TextView tv;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.btn);
tv = (TextView)findViewById(R.id.tv);
Log.i("test","主线程名字 = " + Thread.currentThread().getName() +
"主线程id = " + Thread.currentThread().getId());
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
//主线程更新UI
tv.setText(msg.obj.toString());
break;
}
}
};
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//创建一个子线程
new Thread(new MyRunnable(handler)).start();
}
});
}
}
class MyRunnable implements Runnable{
Handler handler;
public MyRunnable(Handler handler){
this.handler = handler;
}
@Override
public void run() {
Log.i("test","子线程名字 = " + Thread.currentThread().getName() +
"子线程id = " + Thread.currentThread().getId());
Message msg = handler.obtainMessage();
msg.what = 0;
msg.obj = Thread.currentThread().getName();
handler.sendMessage(msg);
}
}
总结: