(转)android handler

对于Handler来说,它和与它调用它的Activity是出于同一线程的,上一篇并没有调用线程
的start方法,而是直接执行的run方法。而启动一个线程是调用的start方法

上一篇博客里的对Handler的调用时通过Runnable接口来实现的,并且是通过run()方法来启动那个线程的,而且是Activity和Handler是两个线程独立运行的,互补干扰,但是实际情况确实,Activity所在的线程和Handler的线程是同一个线程,下面进行一下实验

Java代码
  1. packageorg.hualang.handlertest3;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.os.Handler;
  5. importandroid.util.Log;
  6. publicclassHandlerTest3extendsActivity{
  7. privateHandlerhandler=newHandler();
  8. privateStringTAG="System.out";
  9. @Override
  10. publicvoidonCreate(BundlesavedInstanceState){
  11. super.onCreate(savedInstanceState);
  12. handler.post(r);
  13. setContentView(R.layout.main);
  14. //Threadt=newThread(r);
  15. //t.start();
  16. Log.d(TAG,"Activityid:"+Thread.currentThread().getId());
  17. Log.d(TAG,"Activityname:"+Thread.currentThread().getName());
  18. }
  19. Runnabler=newRunnable()
  20. {
  21. publicvoidrun()
  22. {
  23. Log.d(TAG,"Handlerid:"+Thread.currentThread().getId());
  24. Log.d(TAG,"Handlername:"+Thread.currentThread().getName());
  25. try{
  26. Thread.sleep(5000);
  27. }catch(InterruptedExceptione){
  28. //TODOAuto-generatedcatchblock
  29. e.printStackTrace();
  30. }
  31. }
  32. };
  33. }
package org.hualang.handlertest3;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

public class HandlerTest3 extends Activity {
    private Handler handler = new Handler();
    private String TAG = "System.out";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handler.post(r);
        setContentView(R.layout.main);
        //Thread t = new Thread(r);
        //t.start();
        
        Log.d(TAG,"Activity id:"+Thread.currentThread().getId());
        Log.d(TAG,"Activity name:"+Thread.currentThread().getName());
        
    }
    Runnable r = new Runnable()
    {
    	public void run()
    	{
    		Log.d(TAG,"Handler id:"+Thread.currentThread().getId());
            Log.d(TAG,"Handler name:"+Thread.currentThread().getName());
            try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    };
}

运行结果:

证明是同一个线程的两个依据:

①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. Threadt=newThread(r);
  4. t.start();
        //handler.post(r);
        setContentView(R.layout.main);
        Thread t = new Thread(r);
        t.start();

再次执行,运行结果如下,通过start启动线程,它们不在同一个线程中

----------------------------------------------------------------------------------------------------------------

Looper即循环的从队列当中取得消息的功能,如果在线程中使用Looper
那么,就会循环的从线程队列当中取得消息并处理,如果队列当中没有消息的话
,线程就进入了休眠状态

Looper很少自己创建,在Android中给出了HandlerThread类,并且具有循环取得并处理消息的功能

下面来实现这种Activity和Handler分别在两个线程中执行,实现真正的异步处理

Java代码
  1. packageorg.hualang.handlertest;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.os.Handler;
  5. importandroid.os.HandlerThread;
  6. importandroid.os.Looper;
  7. importandroid.os.Message;
  8. importandroid.util.Log;
  9. publicclassHandlerTest4extendsActivity{
  10. /**Calledwhentheactivityisfirstcreated.*/
  11. @Override
  12. publicvoidonCreate(BundlesavedInstanceState){
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.main);
  15. Log.d("System.out","Activity所在线程的id:"+Thread.currentThread().getId());
  16. /**
  17. *生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能
  18. *这个类由Android应用程序框架提供
  19. */
  20. HandlerThreadhandlerThread=newHandlerThread("handlerThread");
  21. handlerThread.start();
  22. MyHandlerhandler=newMyHandler(handlerThread.getLooper());
  23. Messagemsg=handler.obtainMessage();
  24. /**
  25. *将Message对象发送到目标对象
  26. *所谓的目标对象,就是生成该msg对象的handler对象
  27. */
  28. msg.sendToTarget();
  29. }
  30. classMyHandlerextendsHandler
  31. {
  32. publicMyHandler()
  33. {
  34. }
  35. publicMyHandler(Looperlooper)
  36. {
  37. super(looper);
  38. }
  39. publicvoidhandleMessage(Messagemsg)
  40. {
  41. Log.d("System.out","handler所在线程的id:"+Thread.currentThread().getId());
  42. }
  43. }
  44. }
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;

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.start();
        MyHandler handler = new MyHandler(handlerThread.getLooper());
        Message msg = handler.obtainMessage();
        /**
         * 将Message对象发送到目标对象
         * 所谓的目标对象,就是生成该msg对象的handler对象
         */
        msg.sendToTarget();
    }
    class MyHandler extends Handler
    {
    	public MyHandler()
    	{	
    	}
    	public MyHandler(Looper looper)
    	{
    		super(looper);
    	}
    	public void handleMessage(Message msg)
    	{
    		Log.d("System.out", "handler所在线程的id:"+Thread.currentThread().getId());
    	}
    }
}

运行结果:



可以看到,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. Bundleb=newBundle();
  2. b.putInt("age",22);
  3. b.putString("name","loulijun");
  4. msg.setData(b);
  5. msg.sendToTarget();
        Bundle b = new Bundle();
        b.putInt("age", 22);
        b.putString("name", "loulijun");
        msg.setData(b);
        msg.sendToTarget();

上面的代码用来设置要传递的数据

下面的代码用来获取Bundle传递过来的数据并且用Toast来显示

Java代码
  1. Bundleb=msg.getData();
  2. intage=b.getInt("age");
  3. Stringname=b.getString("name");
  4. Toasttoast=Toast.makeText(getApplicationContext(),"age="+age+"name="+name,Toast.LENGTH_LONG);
  5. toast.show();
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();

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());
}
}
}

运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值