玩转Android---组件篇---Handler的使用(1)

在android中,有很多功能是不能放在onCreate或者onStart方法里面,因为这些功能相对

来说费时比较长,比如说下载一个文件,下载的过程比较长,但是如果写在Activity中,

那么这段时间Activity是完全没有响应的,那么就可以将这种处理大量数据或者耗时比较

长的东西放在一个单独的线程中来完成,即Activity是一个线程,而下载的是在另外一个

线程,那么这样就可以使得下载跟Activity之间互不影响,从而得到了良好的用户体验

这里有两种队列,一种是线程队列,就是用postXX方法或者removeCallbacks方法对线程对象的操作。另一种是消息队列,用sendMessage和handleMessage方法来对消息对象进行处理

玩转Android---组件篇---Handler的使用(1)_第1张图片


handler采用的是一个消息队列的方式,每一个handler都有一个与之关联的消息队列,而且是先进先出的方式执行,即:每次加入一个handler,然后拿出来,对其进行处理,然后再拿出另一个,再进行处理

例子一:这个例子仅仅是对线程对象进行操作的测试

Java代码 
package org.hualang.handler;  
 
import android.app.Activity;  
import android.os.Bundle;  
import android.os.Handler;  
import android.view.View;  
import android.widget.Button;  
 
public class HandlerTest extends Activity {  
      
    private Button mybutton1;  
    private Button mybutton2;  
    @Override 
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
          
        mybutton1 = (Button)findViewById(R.id.mybutton1);  
        mybutton2 = (Button)findViewById(R.id.mybutton2);  
          
        mybutton1.setOnClickListener(new Button.OnClickListener()  
        {  
 
            @Override 
            public void onClick(View arg0) {  
                /** 
                 * 调用Handler的post方法,将要执行的线程对象添加到 
                 * 线程队列中 
                 */ 
                handler.post(updateThread);  
            }  
              
        });  
        mybutton2.setOnClickListener(new Button.OnClickListener()  
        {  
 
            @Override 
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                handler.removeCallbacks(updateThread);  
            }  
              
        });    
          
    }  
    //创建Handler对象  
    Handler handler = new Handler();  
    /** 
     * 将要执行的操作卸载写入线程对象的run()方法当中 
     */ 
    Runnable updateThread = new Runnable()  
    {  
        public void run()  
        {  
            System.out.println("更新线程");  
            //在run方法内部,执行postXX的方法,每隔3秒会执行一次  
            handler.postDelayed(updateThread, 3000);  
        }  
    };  


package org.hualang.handler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;

public class HandlerTest extends Activity {
   
private Button mybutton1;
private Button mybutton2;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        mybutton1 = (Button)findViewById(R.id.mybutton1);
        mybutton2 = (Button)findViewById(R.id.mybutton2);
       
        mybutton1.setOnClickListener(new Button.OnClickListener()
        {

@Override
public void onClick(View arg0) {
/**
* 调用Handler的post方法,将要执行的线程对象添加到
* 线程队列中
*/
handler.post(updateThread);
}
       
        });
        mybutton2.setOnClickListener(new Button.OnClickListener()
        {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handler.removeCallbacks(updateThread);
}
       
        }); 
       
    }
    //创建Handler对象
    Handler handler = new Handler();
    /**
     * 将要执行的操作卸载写入线程对象的run()方法当中
     */
    Runnable updateThread = new Runnable()
    {
    public void run()
    {
    System.out.println("更新线程");
    //在run方法内部,执行postXX的方法,每隔3秒会执行一次
    handler.postDelayed(updateThread, 3000);
    }
    };
}

运行结果如下:


玩转Android---组件篇---Handler的使用(1)_第2张图片


程序解释:首先创建一个Handler对象,然后创建一个继承自Runnable接口的线程

程序首先点击按钮“开始”,于是会马上执行post方法,将执行的线程对象添加到线程队列中,这时会马上执行

Java代码 
public void run()  
        {  
            System.out.println("更新线程");  
            //在run方法内部,执行postXX的方法,每隔3秒会执行一次  
            handler.postDelayed(updateThread, 3000);  
        } 

public void run()
    {
    System.out.println("更新线程");
    //在run方法内部,执行postXX的方法,每隔3秒会执行一次
    handler.postDelayed(updateThread, 3000);
    }

然后,执行postDelayed方法,由于里面设置的间隔时间,所以每3秒会调价一个handler对象到线程队列中,并且一直执行,直到点击“结束”按钮,调用removeCallbacks方法将其从线程队列中移除





例子2:下面的例子将简单的对线程对象和消息对象进行处理

Java代码 
package org.hualang.handlertest2;  
 
import android.app.Activity;  
import android.os.Bundle;  
import android.os.Handler;  
import android.os.Message;  
import android.view.View;  
import android.widget.Button;  
import android.widget.ProgressBar;  
 
public class HandlerTest2 extends Activity {  
    private ProgressBar bar = null;  
    private Button start = null;  
    @Override 
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        bar = (ProgressBar)findViewById(R.id.progress1);  
        start = (Button)findViewById(R.id.start);  
        start.setOnClickListener(new Button.OnClickListener()  
        {  
 
            @Override 
            public void onClick(View v) {  
                bar.setVisibility(View.VISIBLE);  
                handler.post(handlerThread);  
            }  
              
        });  
    }  
    /** 
     * 使用匿名内部类来复写hanlder当中的hanldrMessage方法 
     * 这里的msg对象就是从线程部分发送过来的对象 
     */ 
    Handler handler = new Handler()  
    {  
        public void handleMessage(Message msg)  
        {  
            bar.setProgress(msg.arg1);  
            handler.post(handlerThread);  
        }  
    };  
    //线程类,该类使用的是匿名内部类的方式进行声明  
    Runnable handlerThread = new Runnable()  
    {  
        int i = 0;  
        public void run()  
        {  
            System.out.println("开始线程");  
            i = i + 10;  
            /** 
             * 得到一个消息对象,Message类是由android操作系统提供 
             * obtainMessage方法用来得到Message对象 
             */ 
            Message msg = handler.obtainMessage();  
            /** 
             * Message中有个成员变量,即msg独享的arg1参数 
             * 将其值设置为i。用arg1或arg2这两个成员变量传递 
             * 消息,优点是系统性能消耗较少 
             */ 
            msg.arg1 = i;  
            try {  
                //当前线程休眠1秒  
                Thread.sleep(5000);  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
            /** 
             * 发送一个消息,用sendMessage是将msg加入到消息 
             * 队列中。而post是将线程加入到线程队列中 
             */ 
            handler.sendMessage(msg);  
            if( i == 100)  
            {  
                /** 
                 * 如果i=100的时候,就将线程对象 
                 * 从handler当中移除 
                 */ 
                handler.removeCallbacks(handlerThread);  
                bar.setVisibility(View.GONE);  
            }  
        }  
    };  


package org.hualang.handlertest2;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;

public class HandlerTest2 extends Activity {
    private ProgressBar bar = null;
    private Button start = null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        bar = (ProgressBar)findViewById(R.id.progress1);
        start = (Button)findViewById(R.id.start);
        start.setOnClickListener(new Button.OnClickListener()
        {

@Override
public void onClick(View v) {
bar.setVisibility(View.VISIBLE);
handler.post(handlerThread);
}
       
        });
    }
    /**
     * 使用匿名内部类来复写hanlder当中的hanldrMessage方法
     * 这里的msg对象就是从线程部分发送过来的对象
     */
    Handler handler = new Handler()
    {
    public void handleMessage(Message msg)
    {
    bar.setProgress(msg.arg1);
    handler.post(handlerThread);
    }
    };
    //线程类,该类使用的是匿名内部类的方式进行声明
    Runnable handlerThread = new Runnable()
    {
    int i = 0;
    public void run()
    {
    System.out.println("开始线程");
    i = i + 10;
    /**
    * 得到一个消息对象,Message类是由android操作系统提供
    * obtainMessage方法用来得到Message对象
    */
    Message msg = handler.obtainMessage();
    /**
    * Message中有个成员变量,即msg独享的arg1参数
    * 将其值设置为i。用arg1或arg2这两个成员变量传递
    * 消息,优点是系统性能消耗较少
    */
    msg.arg1 = i;
    try {
    //当前线程休眠1秒
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/**
* 发送一个消息,用sendMessage是将msg加入到消息
* 队列中。而post是将线程加入到线程队列中
*/
handler.sendMessage(msg);
if( i == 100)
{
/**
* 如果i=100的时候,就将线程对象
* 从handler当中移除
*/
handler.removeCallbacks(handlerThread);
bar.setVisibility(View.GONE);
}
    }
    };
}
 

main.xml

Xml代码 
<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
<ProgressBar 
    android:id="@+id/progress1" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:visibility="gone" 
    style="?android:attr/progressBarStyleHorizontal" 
/> 
<Button 
    android:id="@+id/start" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:gravity="center" 
    android:text="点击我" 
/> 
</LinearLayout> 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<ProgressBar
android:id="@+id/progress1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
style="?android:attr/progressBarStyleHorizontal"
/>
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="点击我"
/>
</LinearLayout>

运行结果:

玩转Android---组件篇---Handler的使用(1)_第3张图片

玩转Android---组件篇---Handler的使用(1)_第4张图片


程序说明:

1、当点击按钮后,会执行按钮的onClick方法中的

Java代码 
bar.setVisibility(View.VISIBLE);  
handler.post(handlerThread); 

bar.setVisibility(View.VISIBLE);
handler.post(handlerThread); 将进度条显示出来,并且将线程对象加入到线程队列中

2、线程对象对先打印出一个“开始线程”,然后i的值增加10,然后从系统中获取一个Message对象

3、将i赋给Message对象的参数arg1

4、当前线程休眠5秒,然后通过sendMessage方法发送一个Message对象发送到消息队列中

5、然后再执行,通过handleMessage方法设置进度条的值,并且将其加入到进程队列中

Java代码 
Handler handler = new Handler()  
    {  
        public void handleMessage(Message msg)  
        {  
            bar.setProgress(msg.arg1);  
            handler.post(handlerThread);  
        }  
    }; 

Handler handler = new Handler()
    {
    public void handleMessage(Message msg)
    {
    bar.setProgress(msg.arg1);
    handler.post(handlerThread);
    }
    }; 6、循环执行,直到i=100,进度条隐藏,并将线程对象从线程队列中取出

你可能感兴趣的:(android)