消息队列处理模型
容器保存事件,队列
涉及到角色:
类 功能
MessageQueue 存放消息
Looper 轮循消息队列,从中取出消息
Thread 处理消息
Message 消息
Handler 在其他线程发消息给当前线程
1.looper的例子及说明
由Looper决定
Looper对象在哪个线程创建,
Handler的handleMessage方法就在哪个线程执行
public class MainActivity extends Activity
{
private Handler mHandler;
int what = 0;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
mHandler.sendEmptyMessage(what ++);//主线程发送
new Thread("aaa")
{
public void run()
{
mHandler.sendEmptyMessage(what ++);//“aaa”子线程发送
}
}.start();
}
});
new Thread("自定义消息队列")
{//单线程处理所有线程发过来的消息,会以队列的顺序排队执行
public void run()
{
Looper.prepare();
//查看prepare()里80行和189行,创建了messageQueue、looper
mHandler = new Handler(Looper.myLooper())
//Looper.myLooper()得到当前线程的looper
{
//handler在哪个线程处理消息,取决于Looper在哪个线程创建
@Override
public void handleMessage(Message msg)
{
String content = "当前线程:" + Thread.currentThread().getName() + "msg:" + msg.what;
Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
}
};
Looper.loop();//looper开始轮循队列
}
}.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
注意:
在子线程中直接new handle()会出现以下错误,是因为子线程中默认没有创建Looper对象,需要先调用Looper.prepare()方法启用Looper。主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。
E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception
E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
2. HandlerThread
封装了Thread和Looper、MessageQueue
public class MainActivity extends Activity
{
private Handler mHandler;
int what = 0;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
mHandler.sendEmptyMessage(what ++);//主线程发送
new Thread("aaa")
{
public void run()
{
mHandler.sendEmptyMessage(what ++);//“aaa”子线程发送
}
}.start();
}
});
// 因为HandlerThread()里面已经封装好了Looper.prepare()和Looper.loop();
HandlerThread thread = new HandlerThread("自定义消息队列");
thread.start();
//thread.getLooper()如果换成Looper.myLooper()就是得到主线程的looper
mHandler = new Handler(thread.getLooper())
{
//handler在哪个线程处理消息,取决于Looper在哪个线程创建
@Override
public void handleMessage(Message msg)
{
String content = "当前线程:" + Thread.currentThread().getName() + "msg:" + msg.what;
Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
}
};
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
3. IntentService
Thread、Looper、MessageQueue、Handler、Message
MainActivity中显式意图启动service
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{//启动MyService,传值过去
Intent service = new Intent(MainActivity.this,MyService.class);
service.putExtra("msg", "aaa");
startService(service );
}
});
}
}
MyService继承了IntentService,接收到MainActivity传来的值
public class MyService extends IntentService
{
//封装好了handleMessage();64行
// 写好了HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
// thread.start();
public MyService()
{//IntentService有个有参的构造方法75行
super("消息队列IntentService");
}
@Override
public IBinder onBind(Intent intent)
{
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
protected void onHandleIntent(Intent intent)
{
String extra = intent.getStringExtra("msg");
String content = "当前线程:" + Thread.currentThread().getName() + "msg:" + extra;
Log.e("onHandleIntent", content);
}
}
转载于:https://blog.51cto.com/wangcuijing/1290537