- 当主线程诞生时,就会去执行一个代码循环(Looper),以便持续监视它的信息队列(Message Queue简称MQ)。当UI事件发生了,通常会立即丢一个信息 (Message)到MQ,此时主线程就立即从MQ里面取出该信息,并且处理。
- 例如,用户在UI画面上按下一个Button按 钮时,UI事件发生了,就会把onClick信息丢到 MQ里,于是,主线程会及时从MQ里取出onClick信息,然后调用Activity的onClick()函数去处理之。处理完毕之后,主线程又返回去继续执行信息循环,继续监视它的MQ,一直循环下去,直到主线程的生命周期的终了。 通常是进程被删除时,主线程才会被删除。
- 即一个主线程有它自己专属的Looper对象,此线程诞生时,就会执行此对象里的信息循环。此外,一个主线程还会有其专属的MQ信息结构。如下图所示:
- 由于主线程会持续监视MQ的动态,所以在程序的任何函数,只要将信息(以Message 类别的对象表示)丢入主线程的MQ里, 就能与主线程沟通了。
- 在Android里,也定义了一个Handler类别,在程序的任何函数里,可以诞生Handler对象来将Message对象丢入MQ里,与主线程进行沟通。
- 在Android的预设情况下,主线程诞生时,就会拥有自己的Looper对象和MQ(即 Message Queue)数据结构。
- 然而,主线程诞生子线程时,于预设情形 下,子线程并不具有自己的Looper对象和 MQ。由于没有Looper对象,就没有信息回圈(Message Loop),一旦工作完毕了,此子线程就结束了。
- 既然没有Looper对象也没有MQ,也就不 能接受外来的Message对象了。则别的线 程就无法透过MQ来传递信息给它了。如果别的线程(如主线程)需要与子线程通讯时,就得要手动替它诞生一 个Looper对象和一个MQ。
Demo展示:
- 主线程丢信息给自己
package com.example.aaa;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
private Button btn1,btn2;
private TextView textView;
private Handler h=new Handler(){
public void handleMessage(Message msg) {
if(msg.what==1)
textView.setText((String)msg.obj);
};
};;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
btn1=(Button) findViewById(R.id.btn1);
btn2=(Button) findViewById(R.id.btn2);
textView=(TextView) findViewById(R.id.textview);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn1:
h.removeMessages(1);
Message m=h.obtainMessage(1, "this is my message");
h.sendMessage(m);
break;
case R.id.btn2:
this.finish();
default:
break;
}
}
}
运行结果:
- 子线程丢信息给主线程
package com.example.aaa;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
private Button btn1,btn2;
private TextView textView;
private Timer timer=new Timer();
private int k=0;
private Handler h=new Handler(){
public void handleMessage(Message msg) {
if(msg.what==1)
textView.setText((String)msg.obj);
};
};;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
btn1=(Button) findViewById(R.id.btn1);
btn2=(Button) findViewById(R.id.btn2);
textView=(TextView) findViewById(R.id.textview);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn1:
TimerTask timerTask=new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
h.removeMessages(1);
Message m=h.obtainMessage(1, Thread.currentThread().getName()+":"+String.valueOf(k++));
h.sendMessage(m);
}
};
timer.schedule(timerTask, 500, 1500);
break;
case R.id.btn2:
this.finish();
default:
break;
}
}
}
运行结果:
- 替子线程诞生Looper和MQ
package com.example.aaa;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
private Button btn1,btn2,btn3;
private TextView textView;
private Thread t;
private Handler h;
private String str;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
btn1=(Button) findViewById(R.id.btn1);
btn2=(Button) findViewById(R.id.btn2);
btn3=(Button) findViewById(R.id.btn3);
textView=(TextView) findViewById(R.id.textview);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
t=new Thread(new Task());
t.start();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn1:
h.removeMessages(1);
Message m=h.obtainMessage(1, Thread.currentThread().getName()+":"+String.valueOf(k++));
h.sendMessage(m);
break;
case R.id.btn2:
btn2.setText(str);
break;
case R.id.btn3:
h.getLooper().quit();
finish();
break;
}
}
class Task implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
Looper.prepare();
h=new Handler(){
public void handleMessage(Message msg) {
if(msg.what==1)
str=Thread.currentThread().getName()+",value="+String.valueOf(msg.what);
};
};
Looper.loop();
}
}
}
运行结果: