通州北大青鸟学术部推荐:对于Handler来说,它和与它调用它的Activity是出于同一线程的,下面进行一下实验
Java代码
1. package org.hualang.handlertest3;
2.
3. import android.app.Activity;
4. import android.os.Bundle;
5. import android.os.Handler;
6. import android.util.Log;
7.
8. public class HandlerTest3 extends Activity {
9. private Handler handler = new Handler();
10. private String TAG = "System.out";
11. @Override
12. public void onCreate(Bundle savedInstanceState) {
13. super.onCreate(savedInstanceState);
14. handler.post(r);
15. setContentView(R.layout.main);
16. //Thread t = new Thread(r);
17. //t.start();
18.
19. Log.d(TAG,"Activity id:"+Thread.currentThread().getId());
20. Log.d(TAG,"Activity name:"+Thread.currentThread().getName());
21.
22. }
23. Runnable r = new Runnable()
24. {
25. public void run()
26. {
27. Log.d(TAG,"Handler id:"+Thread.currentThread().getId());
28. Log.d(TAG,"Handler name:"+Thread.currentThread().getName());
29. try {
30. Thread.sleep(5000);
31. } catch (InterruptedException e) {
32. // TODO Auto-generated catch block
33. e.printStackTrace();
34. }
35. }
36. };
37. }
运行结果: (通州北大青鸟)
证明是同一个线程的两个依据:
①Activity的id或name和Handler的id或name是同样的
②我设置了
handler.post(r);
setContentView(R.layout.main);
也就是,如果执行后马上显示文本信息,那么可以证明它们不在同一个线程,但是实际情况是要先执行了handler后5秒,才显示文本信息,说明它们在同一线程
如果将代码改为(通州北大青鸟)
Java代码
1. //handler.post(r);
2. setContentView(R.layout.main);
3. Thread t = new Thread(r);
4. t.start();
再次执行,运行结果如下,通过start启动线程,它们不在同一个线程中
Looper即循环的从队列当中取得消息的功能,如果在线程中使用Looper
那么,就会循环的从线程队列当中取得消息并处理,如果队列当中没有消息的话
,线程就进入了休眠状态
Looper很少自己创建,在Android中给出了HandlerThread类,并且具有循环取得并处理消息的功能
下面来实现这种Activity和Handler分别在两个线程中执行,实现真正的异步处理
Java代码 (通州北大青鸟)
1. package org.hualang.handlertest;
2.
3. import android.app.Activity;
4. import android.os.Bundle;
5. import android.os.Handler;
6. import android.os.HandlerThread;
7. import android.os.Looper;
8. import android.os.Message;
9. import android.util.Log;
10.
11. public class HandlerTest4 extends Activity {
12. /** Called when the activity is first created. */
13. @Override
14. public void onCreate(Bundle savedInstanceState) {
15. super.onCreate(savedInstanceState);
16. setContentView(R.layout.main);
17. Log.d("System.out","Activity所在线程的id:"+Thread.currentThread().getId());
18. /**
19. * 生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能
20. * 这个类由Android应用程序框架提供
21. */
22. HandlerThread handlerThread = new HandlerThread("handlerThread");
23. handlerThread.start();
24. MyHandler handler = new MyHandler(handlerThread.getLooper());
25. Message msg = handler.obtainMessage();
26. /**
27. * 将Message对象发送到目标对象
28. * 所谓的目标对象,就是生成该msg对象的handler对象
29. */
30. msg.sendToTarget();
31. }
32. class MyHandler extends Handler
33. {
34. public MyHandler()
35. {
36. }
37. public MyHandler(Looper looper)
38. {
39. super(looper);
40. }
41. public void handleMessage(Message msg)
42. {
43. Log.d("System.out", "handler所在线程的id:"+Thread.currentThread().getId());
44. }
45. }
46. }
运行结果:
可以看到,Activity和Handler是在两个不同的线程中执行的,这样就是实现了真正的异步处理(通州北大青鸟)
1、首先创建一个HandlerThread对象,这个HandlerThread类实现了循环的取得消息并处理
2、用start方法启动一个新线程
3、创建MyHandler类,里面传递的参数即Looper方法所获得的可以循环在队列中取得的消息
4、MyHandler类调用的是带参数Looper的构造方法,并且实现了handlerMessage方法
5、获取一个Message对象
6、将这个对象发送到生成该msg对象的handler对象,从而执行了handleMessage方法
-----------------------------------------------------------------------------------------------------
最后,将说一下Message里传送的数据的使用,这里的msg对象可以使用arg1,arg2或者obj
arg1 and arg2 are lower-cost alternatives to using setData() if you only need to store a few integer values. 也就是相对于setData()方法,如果你仅仅保存一些简单的整形数的话,arg1,arg2对资源的要求较低,而setData()方法一般用于传递大量数据的时候会用到
如果是msg.obj,那么可以这样用
msg.obj = "Welcome to china";
然后在handleMessage()方法中用
String str = (String)msg.obj;来获得传递的值
如果使用getData()方法的话,需要用到Bundle对象来传递,下面用个例子来说明
Java代码
1. Bundle b = new Bundle();
2. b.putInt("age", 22);
3. b.putString("name", "loulijun");
4. msg.setData(b);
5. msg.sendToTarget();
上面的代码用来设置要传递的数据(通州北大青鸟)
下面的代码用来获取Bundle传递过来的数据并且用Toast来显示
Java代码
1. Bundle b = msg.getData();
2. int age = b.getInt("age");
3. String name = b.getString("name");
4. Toast toast = Toast.makeText(getApplicationContext(), "age="+age+"name="+name, Toast.LENGTH_LONG);
5. toast.show();
package org.hualang.handlertest;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
public class HandlerTest4 extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d("System.out","Activity所在线程的id:"+Thread.currentThread().getId());
/**
* 生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能
* 这个类由Android应用程序框架提供
*/
HandlerThread handlerThread = new HandlerThread("handlerThread");
/**
* 使用HandlerThread的getLooper()方法之前,必须先调用该类的start()方法,否则是个null,会报错
*/
handlerThread.start();
MyHandler handler = new MyHandler(handlerThread.getLooper());
Message msg = handler.obtainMessage();
/**
* 将Message对象发送到目标对象
* 所谓的目标对象,就是生成该msg对象的handler对象
*/
//msg.obj = "Hello world";
Bundle b = new Bundle();
b.putInt("age", 22);
b.putString("name", "loulijun");
msg.setData(b);
msg.sendToTarget();
}
class MyHandler extends Handler
{
public MyHandler()
{
}
public MyHandler(Looper looper)
{
super(looper);
}
public void handleMessage(Message msg)
{
//String str = (String)msg.obj
Bundle b = msg.getData();
int age = b.getInt("age");
String name = b.getString("name");
Toast toast = Toast.makeText(getApplicationContext(), "age="+age+"name="+name, Toast.LENGTH_LONG);
toast.show();
Log.d("System.out", "handler所在线程的id:"+Thread.currentThread().getId());
}
}
}
运行结果:(通州北大青鸟)
(通州北大青鸟)