在android中,有很多功能是不能放在onCreate或者onStart方法里面,因为这些功能相对
来说费时比较长,比如说下载一个文件,下载的过程比较长,但是如果写在Activity中,
那么这段时间Activity是完全没有响应的,那么就可以将这种处理大量数据或者耗时比较
长的东西放在一个单独的线程中来完成,即Activity是一个线程,而下载的是在另外一个
线程,那么这样就可以使得下载跟Activity之间互不影响,从而得到了良好的用户体验
这里有两种队列,一种是线程队列,就是用postXX方法或者removeCallbacks方法对线程对象的操作。另一种是消息队列,用sendMessage和handleMessage方法来对消息对象进行处理
handler采用的是一个消息队列的方式,每一个handler都有一个与之关联的消息队列,而且是先进先出的方式执行,即:每次加入一个handler,然后拿出来,对其进行处理,然后再拿出另一个,再进行处理
例子一:这个例子仅仅是对线程对象进行操作的测试
- packageorg.hualang.handler;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.view.View;
- importandroid.widget.Button;
- publicclassHandlerTestextendsActivity{
- privateButtonmybutton1;
- privateButtonmybutton2;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mybutton1=(Button)findViewById(R.id.mybutton1);
- mybutton2=(Button)findViewById(R.id.mybutton2);
- mybutton1.setOnClickListener(newButton.OnClickListener()
- {
- @Override
- publicvoidonClick(Viewarg0){
- /**
- *调用Handler的post方法,将要执行的线程对象添加到
- *线程队列中
- */
- handler.post(updateThread);
- }
- });
- mybutton2.setOnClickListener(newButton.OnClickListener()
- {
- @Override
- publicvoidonClick(Viewv){
- //TODOAuto-generatedmethodstub
- handler.removeCallbacks(updateThread);
- }
- });
- }
- //创建Handler对象
- Handlerhandler=newHandler();
- /**
- *将要执行的操作卸载写入线程对象的run()方法当中
- */
- RunnableupdateThread=newRunnable()
- {
- publicvoidrun()
- {
- System.out.println("更新线程");
- //在run方法内部,执行postXX的方法,每隔3秒会执行一次
- handler.postDelayed(updateThread,3000);
- }
- };
- }
运行结果如下:
程序解释:首先创建一个Handler对象,然后创建一个继承自Runnable接口的线程
程序首先点击按钮“开始”,于是会马上执行post方法,将执行的线程对象添加到线程队列中,这时会马上执行
- publicvoidrun()
- {
- System.out.println("更新线程");
- //在run方法内部,执行postXX的方法,每隔3秒会执行一次
- handler.postDelayed(updateThread,3000);
- }
然后,执行postDelayed方法,由于里面设置的间隔时间,所以每3秒会调价一个handler对象到线程队列中,并且一直执行,直到点击“结束”按钮,调用removeCallbacks方法将其从线程队列中移除
例子2:下面的例子将简单的对线程对象和消息对象进行处理
- packageorg.hualang.handlertest2;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.view.View;
- importandroid.widget.Button;
- importandroid.widget.ProgressBar;
- publicclassHandlerTest2extendsActivity{
- privateProgressBarbar=null;
- privateButtonstart=null;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- bar=(ProgressBar)findViewById(R.id.progress1);
- start=(Button)findViewById(R.id.start);
- start.setOnClickListener(newButton.OnClickListener()
- {
- @Override
- publicvoidonClick(Viewv){
- bar.setVisibility(View.VISIBLE);
- handler.post(handlerThread);
- }
- });
- }
- /**
- *使用匿名内部类来复写hanlder当中的hanldrMessage方法
- *这里的msg对象就是从线程部分发送过来的对象
- */
- Handlerhandler=newHandler()
- {
- publicvoidhandleMessage(Messagemsg)
- {
- bar.setProgress(msg.arg1);
- handler.post(handlerThread);
- }
- };
- //线程类,该类使用的是匿名内部类的方式进行声明
- RunnablehandlerThread=newRunnable()
- {
- inti=0;
- publicvoidrun()
- {
- System.out.println("开始线程");
- i=i+10;
- /**
- *得到一个消息对象,Message类是由android操作系统提供
- *obtainMessage方法用来得到Message对象
- */
- Messagemsg=handler.obtainMessage();
- /**
- *Message中有个成员变量,即msg独享的arg1参数
- *将其值设置为i。用arg1或arg2这两个成员变量传递
- *消息,优点是系统性能消耗较少
- */
- msg.arg1=i;
- try{
- //当前线程休眠1秒
- Thread.sleep(5000);
- }catch(InterruptedExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
- /**
- *发送一个消息,用sendMessage是将msg加入到消息
- *队列中。而post是将线程加入到线程队列中
- */
- handler.sendMessage(msg);
- if(i==100)
- {
- /**
- *如果i=100的时候,就将线程对象
- *从handler当中移除
- */
- handler.removeCallbacks(handlerThread);
- bar.setVisibility(View.GONE);
- }
- }
- };
- }
main.xml
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns: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>
运行结果:
程序说明:
1、当点击按钮后,会执行按钮的onClick方法中的
- bar.setVisibility(View.VISIBLE);
- handler.post(handlerThread);
将进度条显示出来,并且将线程对象加入到线程队列中
2、线程对象对先打印出一个“开始线程”,然后i的值增加10,然后从系统中获取一个Message对象
3、将i赋给Message对象的参数arg1
4、当前线程休眠5秒,然后通过sendMessage方法发送一个Message对象发送到消息队列中
5、然后再执行,通过handleMessage方法设置进度条的值,并且将其加入到进程队列中
- Handlerhandler=newHandler()
- {
- publicvoidhandleMessage(Messagemsg)
- {
- bar.setProgress(msg.arg1);
- handler.post(handlerThread);
- }
- };
6、循环执行,直到i=100,进度条隐藏,并将线程对象从线程队列中取出
