Handler
Handler,它直接继承自Object,一个Handler允许发送和处理Message或者Runnable对象,并且会关联到主线程的MessageQueue中。每个Handler具有一个单独的线程,并且关联到一个消息队列的线程,就是说一个Handler有一个固有的消息队列。当实例化一个Handler的时候,它就承载在一个线程和消息队列的线程,这个Handler可以把Message或Runnable压入到消息队列,并且从消息队列中取出Message或Runnable,进而操作它们。
一下是一个简单的例子。两个按钮只是测试用的。点击按钮后,将改变TextView的文字。
package com.jam.testhandler; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private Button button1; private Button button2; private TextView textView; private MyHandler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); handler = new MyHandler(); button1 = (Button) findViewById(R.id.button1); button2 = (Button) findViewById(R.id.button2); textView = (TextView) findViewById(R.id.textView); button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Thread t = new MyWorkThread(); t.start(); } }); button2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { TestThread tt = new TestThread(); Thread thread = new Thread(tt); thread.start(); } }); } //集成Thread的方法 private class MyWorkThread extends Thread { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } String s = "String from work thread"; //这里我没弄清楚obtainMessage和new Message的区别。 // Message msg = handler.obtainMessage(); Message msg = new Message(); msg.obj = s; handler.sendMessage(msg); } } //实现Runnable //注意Runnable代表线程体而不是一个线程 private class TestThread implements Runnable { @Override public void run() { Runnable r = new Runnable() { @Override public void run() { System.out.println("Thread的名字-->" + Thread.currentThread().getName()); } }; handler.post(r); } } }
Handler 发送的 message 到队列中后,Looper 拿到后会返回到发送消息的Handler中处理。
Handler拿到后,在这个例子中,由于Handler是在主线程当中,所以这个机制可以另其他线程处理的东西拿到Handler中,再进行UI的修改。
以下是另一种用法,在新的线程中使用Handler
package com.example.testhandler2; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private Button button; private TextView textView; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); textView = (TextView) findViewById(R.id.textView); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Message msg = new Message(); msg.what = 50; handler.sendMessage(msg); } }); WorkerThread workerThread = new WorkerThread(); workerThread.start(); } private class WorkerThread extends Thread { @Override public void run() { Looper.prepare(); handler = new Handler() { @Override public void handleMessage(Message msg) { Log.d("msg", "" + msg.what); } }; Looper.loop(); } } }
在点击按钮后,使用handler发送数据,在另一个线程中把数据取出来。
在子线程创建使用Handler要注意固定用法:
先准备Loop
Looper.prepare()
复写Handler的方法handleMessage
Looper.loop
注意:
Thread代表线程
Runnable代表线程体不是一个线程,线程体传入线程才能用
Handler在哪个线程生成,Looper就在哪个线程
Handler.post()方法 将一个Runnable放入Message的callback中,然后传入消息队列。
Loop取出带有Runnable的Message后,判断是否有callback属性,有则执行handleCallback(Message msg),然后在此方法中执行run方法,没有new一个Thread,一般在这个run()方法中写入需要在UI线程上的操作。
用这样的机制可以弥补没有语句块的缺憾。(oc语言)
另外,有两遍关于Handler很好的博文:
Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等