MyException - 我的异常网
当前位置:我的异常网» Android » 玩转Android-组件篇-Handler的施用(2)

玩转Android-组件篇-Handler的施用(2)

www.MyException.Cn  网友分享于:2013-07-26  浏览:4次
玩转Android---组件篇---Handler的使用(2)
对于Handler来说,它和与它调用它的Activity是出于同一线程的,上一篇并没有调用线程
的start方法,而是直接执行的run方法。而启动一个线程是调用的start方法

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



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


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代码 
//handler.post(r);  
setContentView(R.layout.main);  
Thread t = new Thread(r);  
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代码 
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());  
        }  
    }  


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代码 
Bundle b = new Bundle();  
b.putInt("age", 22);  
b.putString("name", "loulijun");  
msg.setData(b);  
msg.sendToTarget(); 

        Bundle b = new Bundle();
        b.putInt("age", 22);
        b.putString("name", "loulijun");
        msg.setData(b);
        msg.sendToTarget();

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

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

Java代码 
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(); 

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

运行结果:






文章评论

中美印日四国程序员比较
中美印日四国程序员比较
 程序员的样子
程序员的样子
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
10个调试和排错的小建议
10个调试和排错的小建议
总结2014中国互联网十大段子
总结2014中国互联网十大段子
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
程序员都该阅读的书
程序员都该阅读的书
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
旅行,写作,编程
旅行,写作,编程
为什么程序员都是夜猫子
为什么程序员都是夜猫子
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序员必看的十大电影
程序员必看的十大电影
每天工作4小时的程序员
每天工作4小时的程序员
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
Java程序员必看电影
Java程序员必看电影
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
我的丈夫是个程序员
我的丈夫是个程序员
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
程序员的鄙视链
程序员的鄙视链
那些争议最大的编程观点
那些争议最大的编程观点
代码女神横空出世
代码女神横空出世
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
老程序员的下场
老程序员的下场
如何成为一名黑客
如何成为一名黑客
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
我是如何打败拖延症的
我是如何打败拖延症的
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序员应该关注的一些事儿
程序员应该关注的一些事儿
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有