private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
static {
sWorkerThread.start();
}
//在主线程中为子线程sWorkerThread创建handler,如果没有构造参数,默认为当前线程创建Handler
private static final Handler sWorker = new Handler(sWorkerThread.getLooper());
一个线程可以有多个Handler,一个线程只有一个Looper,Looper有一个成员变量MessageQueue !
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
@Override
//isFinishing
public void run() {
Log.d("yzy","线程对象被投递到MessageQueue被Looper传递给Handler");
}
}, 5000);
setContentView(R.layout.hello_activity);
即使 mHandler所在的Activity调用了finish方法(比如按了back),
5秒以后这个 run方法还是会执行的。
startActvitity之后的代码也会执行。
1.onResume()完全执行结束了(没有阻塞)的时候才会 在手机上面显示界面。
2.不能在UI thread执行耗时操作 否则ANR ,在主线程的handler执行 handler.post或者postDelay并没有启动子线程,只是直接执行了run方法
3.不能在非UI thread操作 UI 控件,需要使用handler
4.使用Thread+Message+Handler解决上述问题
package handler.activity; import android.app.Activity; import android.app.ProgressDialog; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { static final int DOWNSUCCESS = 1; static final int DOWNFAIL = 0; ProgressDialog dialog = null; private Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { // //执行接收到的通知,更新UI 此时执行的顺序是按照队列进行,即先进先出 super.handleMessage(msg); switch (msg.what) { case DOWNSUCCESS: dialog.dismiss(); Toast.makeText(MainActivity.this, "下载成功", Toast.LENGTH_SHORT) .show(); break; } } }; // ***************************************** // 主线程Handler负责更新UI,Handler与 Thread通过Message通信 private Thread myThread = new Thread(new Runnable() { @Override public void run() { // 耗时操作 SystemClock.sleep(2000); Message msg = new Message(); msg.what = DOWNSUCCESS; MainActivity.this.myHandler.sendMessage(msg); } }); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) this.findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { myThread.start(); dialog = ProgressDialog.show(MainActivity.this, "", "Loading. Please wait...", true); } }); } }
==================================================================================
5.HandlerThread Looper MessageQueue三者之间的关系
HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量。
这个Looper其实就是对消息队列以及队列处理逻辑的封装,简单说就是 消息队列+消息循环。
Android中每一个线程都跟着一个Looper,Looper可以帮助线程维护一个消息队列,Looper对象的执行需要初始化Looper.prepare方法,
使用Looper.loop方法启动消息队列管理机制,退出时还要使用Looper.release方法释放资源
关于Looper Handler Message的原理 与 线程局部变量 请参考这篇文章
http://www.cnblogs.com/codingmyworld/archive/2011/09/14/2174255.html
private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); static { sWorkerThread.start(); } private static final Handler sWorker = new Handler(sWorkerThread.getLooper());//类比new Handler(getMainLooper())创建主线程handler @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.hello_activity); Runnable r = new Runnable() { public void run() { } }; if (sWorkerThread.getThreadId() == Process.myTid()) { r.run(); } else {//sWorker 这个Handler 是HandlerThread这个子线程的,所以是post到子线程的looper里面去,会开启新线程! sWorker.post(r); } }
public class MainActivity extends Activity implements RequestCallBack{ public static class HttpHandler extends Handler { RequestCallBack callback; public HttpHandler() { super(); } public HttpHandler(Looper looper) { super(looper); } public void setCallBack(RequestCallBack c){ callback = c; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: //TODO:用循环兼容 Map<String, String> params = new HashMap<String, String>(); if (msg.getData() != null) { Iterator<String> keyValuePairs = msg.getData().keySet().iterator(); for (int i = 0; i < msg.getData().size(); i++) { String key = keyValuePairs.next(); params.put(key, msg.getData().getString(key)); } } String xml = HttpXmlClient.post("http://www.secphone.org:6082/a/wp/user/login", params); Log.d("yzy","xml="+xml); callback.onRequestDone(xml); break; } } } private Button mLoginBtn; private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); static { sWorkerThread.start(); } private static final HttpHandler sWorker = new HttpHandler(sWorkerThread.getLooper()); //类比new Handler(getMainLooper())创建主线程handler @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sWorker.setCallBack(this); mLoginBtn = (Button) this.findViewById(R.id.login); mLoginBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Message msg = sWorker.obtainMessage(); msg.what = 1; Bundle msgData = msg.getData(); String imei = ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).getDeviceId(); msgData.putString("uid", "18614002022"); msgData.putString("pw", "12345678"); msgData.putString("dev_id", imei); sWorker.sendMessage(msg); } }); @Override public void onRequestDone(String str) { //run on ui } } interface RequestCallBack{ public void onRequestDone(String s); };
===============================================================
6.AsyncTask
package androidthread.acitvity; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private Button btn = null; private EditText etaddrss = null; private EditText etcontent =null; private ProgressBar pb =null; private ProgressDialog dialog =null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) this.findViewById(R.id.btnsend); etaddrss = (EditText) this.findViewById(R.id.etaddress); etcontent = (EditText) this.findViewById(R.id.etcontent); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { new MyThreads().execute(etaddrss.getText().toString(),etcontent.getText().toString()); }}); } //一般作为内部类使用 public class MyThreads extends AsyncTask<String,Integer , String>{ int i=0; @Override //这里的参数 与 execute 中的相对应 //这个方法不在UI线程(主线程)不能访问UI组件 protected String doInBackground(String... arg) { //arg[0]+arg[1]; while(i<=100){ //模拟耗时操作 SystemClock.sleep(500); this.publishProgress(i); i+=10; } return "发送给"+arg[0]+"内容为"+arg[1]+"邮件已成功发送"; } @Override //参数reslut 是doInBackground()的返回值 protected void onPostExecute(String result) { Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show(); dialog.dismiss(); pb.setVisibility(View.INVISIBLE); } @Override protected void onPreExecute() { Toast.makeText(MainActivity.this, "开始发送邮件", Toast.LENGTH_SHORT).show(); dialog = ProgressDialog.show(MainActivity.this, "", "Loading. Please wait...", true); pb =new ProgressBar(MainActivity.this,null,android.R.attr.progressBarStyleHorizontal); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(200,20); params.setMargins(10, 10, 0, 0); pb.setLayoutParams(params); pb.setMax(100);// 设置最大值 pb.setProgress(0); pb.setVisibility(View.VISIBLE); MainActivity.this.addContentView(pb, params); super.onPreExecute(); } @Override protected void onProgressUpdate(Integer... process) { Log.i("process",process[0].intValue() +""); pb.setProgress(process[0].intValue() ); super.onProgressUpdate(process); } } }