Handler总结

本文介绍了Android中处理耗时任务的方法,通过使用Handler、线程队列和消息队列来实现良好的用户体验。提供了两个实例,展示了如何在Activity中执行后台任务并更新UI。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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

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

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



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

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

Java代码收藏代码
  1. packageorg.hualang.handler;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.os.Handler;
  5. importandroid.view.View;
  6. importandroid.widget.Button;
  7. publicclassHandlerTestextendsActivity{
  8. privateButtonmybutton1;
  9. privateButtonmybutton2;
  10. @Override
  11. publicvoidonCreate(BundlesavedInstanceState){
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.main);
  14. mybutton1=(Button)findViewById(R.id.mybutton1);
  15. mybutton2=(Button)findViewById(R.id.mybutton2);
  16. mybutton1.setOnClickListener(newButton.OnClickListener()
  17. {
  18. @Override
  19. publicvoidonClick(Viewarg0){
  20. /**
  21. *调用Handler的post方法,将要执行的线程对象添加到
  22. *线程队列中
  23. */
  24. handler.post(updateThread);
  25. }
  26. });
  27. mybutton2.setOnClickListener(newButton.OnClickListener()
  28. {
  29. @Override
  30. publicvoidonClick(Viewv){
  31. //TODOAuto-generatedmethodstub
  32. handler.removeCallbacks(updateThread);
  33. }
  34. });
  35. }
  36. //创建Handler对象
  37. Handlerhandler=newHandler();
  38. /**
  39. *将要执行的操作卸载写入线程对象的run()方法当中
  40. */
  41. RunnableupdateThread=newRunnable()
  42. {
  43. publicvoidrun()
  44. {
  45. System.out.println("更新线程");
  46. //在run方法内部,执行postXX的方法,每隔3秒会执行一次
  47. handler.postDelayed(updateThread,3000);
  48. }
  49. };
  50. }

运行结果如下:



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

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

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

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

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

Java代码收藏代码
  1. packageorg.hualang.handlertest2;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.os.Handler;
  5. importandroid.os.Message;
  6. importandroid.view.View;
  7. importandroid.widget.Button;
  8. importandroid.widget.ProgressBar;
  9. publicclassHandlerTest2extendsActivity{
  10. privateProgressBarbar=null;
  11. privateButtonstart=null;
  12. @Override
  13. publicvoidonCreate(BundlesavedInstanceState){
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.main);
  16. bar=(ProgressBar)findViewById(R.id.progress1);
  17. start=(Button)findViewById(R.id.start);
  18. start.setOnClickListener(newButton.OnClickListener()
  19. {
  20. @Override
  21. publicvoidonClick(Viewv){
  22. bar.setVisibility(View.VISIBLE);
  23. handler.post(handlerThread);
  24. }
  25. });
  26. }
  27. /**
  28. *使用匿名内部类来复写hanlder当中的hanldrMessage方法
  29. *这里的msg对象就是从线程部分发送过来的对象
  30. */
  31. Handlerhandler=newHandler()
  32. {
  33. publicvoidhandleMessage(Messagemsg)
  34. {
  35. bar.setProgress(msg.arg1);
  36. handler.post(handlerThread);
  37. }
  38. };
  39. //线程类,该类使用的是匿名内部类的方式进行声明
  40. RunnablehandlerThread=newRunnable()
  41. {
  42. inti=0;
  43. publicvoidrun()
  44. {
  45. System.out.println("开始线程");
  46. i=i+10;
  47. /**
  48. *得到一个消息对象,Message类是由android操作系统提供
  49. *obtainMessage方法用来得到Message对象
  50. */
  51. Messagemsg=handler.obtainMessage();
  52. /**
  53. *Message中有个成员变量,即msg独享的arg1参数
  54. *将其值设置为i。用arg1或arg2这两个成员变量传递
  55. *消息,优点是系统性能消耗较少
  56. */
  57. msg.arg1=i;
  58. try{
  59. //当前线程休眠1秒
  60. Thread.sleep(5000);
  61. }catch(InterruptedExceptione){
  62. //TODOAuto-generatedcatchblock
  63. e.printStackTrace();
  64. }
  65. /**
  66. *发送一个消息,用sendMessage是将msg加入到消息
  67. *队列中。而post是将线程加入到线程队列中
  68. */
  69. handler.sendMessage(msg);
  70. if(i==100)
  71. {
  72. /**
  73. *如果i=100的时候,就将线程对象
  74. *从handler当中移除
  75. */
  76. handler.removeCallbacks(handlerThread);
  77. bar.setVisibility(View.GONE);
  78. }
  79. }
  80. };
  81. }

main.xml

Xml代码收藏代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <ProgressBar
  8. android:id="@+id/progress1"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"
  11. android:visibility="gone"
  12. style="?android:attr/progressBarStyleHorizontal"
  13. />
  14. <Button
  15. android:id="@+id/start"
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:gravity="center"
  19. android:text="点击我"
  20. />
  21. </LinearLayout>

运行结果:





程序说明:

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

Java代码收藏代码
  1. bar.setVisibility(View.VISIBLE);
  2. handler.post(handlerThread);

将进度条显示出来,并且将线程对象加入到线程队列中

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

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

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

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

Java代码收藏代码
  1. Handlerhandler=newHandler()
  2. {
  3. publicvoidhandleMessage(Messagemsg)
  4. {
  5. bar.setProgress(msg.arg1);
  6. handler.post(handlerThread);
  7. }
  8. };

6、循环执行,直到i=100,进度条隐藏,并将线程对象从线程队列中取出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值