androidhandler(androidhandler用法)

本篇文章给大家谈谈androidhandler,以及androidhandler用法对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Android 为什么使用Handler

在Android的UI开发中,我们经常会使用Handler来控制主UI程序的界面变化。有关Handler的作用,我们总结为:与其他线程协同工作,接收其他线程的消息并通过接收到的消息更新主UI线程的内容。

我们假设在一个UI界面上面,有一个按钮,当点击这个按钮的时候,会进行网络连或穗拆接,并把网络上的一个字符串拿族让下来显示到界面上的一个 TextView上面,这时就出现了一个问题,如果这个网络连接的延迟过大,可能是10秒钟甚至更长,那我们的界面将处于一直假死状态,而如果这段时间超 过5秒钟的话,程序会出现异常。

这时我们会想到使用线程来完成以上工作,即当按钮被按下的时候新开启一个线程来完成网络连接工作,并把得到的结果更新到UI上面。但是,这时候又会 出现另一个问题,在Android中,主线程是非线程安全的,也就是说UI的更新只能在本线程中完成,其他线程无法直接对主线程进行操作。

为了解决以上问题,Android设计了Handler机制,由Handler来负责与子线程进行通讯,从而让子线程与主线程之间建立起协作的桥梁,使Android的UI更新的问题得到完美的解决。接下来举例来诠释Handler的基本使用方法。

Handler的工作原理

一般情况下,在主线程中我们绑定了Handler,并衫枣在事件触发上面创建新的线程用于完成某些耗时的操作,当子线程中的工作完成之后,会对Handler发送一个完成的信号,而Handler接收到信号后,就进行主UI界面的更新操作。

2

Handler与子线程协作实例

1、创建Handler实现类,在主UI所在类中的内部类

class MyHandler extends Handler {

public MyHandler() { }

public MyHandler(Looper L) {

super(L);

}

// 重写handleMessage方法,接受数据并更新UI

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

//此处根据msg内容进行UI操作

}

}

2、子线程的实现

class MyThread implements Runnable {

public void run() {

Message msg = new Message();

Bundle b = new Bundle();

b.putString("cmd", "update");

msg.setData(b);

MainActivity.this.myHandler.sendMessage(msg);

//通知Handler更新UI

}

}

通过以上的两个实现,我们只需要在MainActivity中声明MyHandler实例对象就可以完成线程之间的通讯和界面的更新操作。

MyHandler myHandler = newMyHandler();

Android中Handler的使用方法

Handler在Android中主要是负责发送和处销空理消息。它的主要用途大致是下面两个:

1)按计划发送消息或执行某个Runnanble;

2)从其他线程中发送来的消息放入消息队列中,避免线程冲突(常见于更新UI线程)

学写一下,在UI线程中,系统斗山已经有一个Activity来处理了,你可以再起若干个Handler来处理。在实例化Handler的时候,只要有Handler的指针,任何线程也都可以sendMessage。

Handler对于Message的处理是异步处理的。一个Looper 只有处理完一条Message才会读取下一条,所以消息的处理是阻塞形式的(handleMessage()方法里不应该有耗时操作,可以将耗时操作放在其他线程执行,操作完后发送Message(通过sendMessges方法),然后由handleMessage()更新亏销瞎UI)。

根据对视频的学习写了一个通过Button控件启动进度条(类似于下载等操作)的程序,简单介绍一下,有两个Button控件,一个是开始,点击之后会显示一个进度条以每次十分之一的进度进行(一开始是隐藏的),另一个是停止,可以中断进度。

java代码:

1 package zzl.handleactivity;

2

3 import android.app.Activity;

4 import android.os.Bundle;

5 import android.os.Handler;

6 import android.os.Message;

7 import android.view.Gravity;

8 import android.view.View;

9 import android.view.View.OnClickListener;

10 import android.widget.Button;

11 import android.widget.ProgressBar;

12 import android.widget.Toast;

13

14 public class Handler_01 extends Activity {

15

16 //声明变量

17 private Button startButton=null;

18 private Button endButton=null;

19 private ProgressBar firstBar=null;

20 private Toast toast=null;

21 @Override

22 protected void onCreate(Bundle savedInstanceState) {

23 super.onCreate(savedInstanceState);

24 setContentView(R.layout.main);

25

26 //根据ID获取对象

27 startButton =(Button)findViewById(R.id.startButton);

28 endButton=(Button)findViewById(R.id.endButton);

29 firstBar=(ProgressBar)findViewById(R.id.firstBar);

30 //给对象设置动作监听器

31 startButton.setOnClickListener(new StartButtonListener());

32 endButton.setOnClickListener(new EndButtonListener());

33 }

34

35 class StartButtonListener implements OnClickListener{

36

37 @Override

38 public void onClick(View v) {

39 // TODO Auto-generated method stub

40 //一开始执行,加入到消息队列,不延迟,

41 //然后马上执行run方法

42 firstBar.setVisibility(View.VISIBLE);

43 firstBar.setMax(100);

44 handler.post(upRunnable);

45 toast=Toast.makeText(Handler_01.this, "运行开始", Toast.LENGTH_SHORT);

46 toast.setGravity(Gravity.CENTER, 0, 0);

47 toast.show();

48 }

49 }

50 class EndButtonListener implements OnClickListener{

51

52 @Override

53 public void onClick(View v) {

54 // TODO Auto-generated method stub

55 //停止

56 handler.removeCallbacks(upRunnable);

57 System.out.println("It's time to stop...");

58 }

59 }

60

61 //创建handler对象,在调用post方法

62 //异步消息处理:将下载或者处理大数据等等单独放到另一个线程

63 //更好的用户体验

64 Handler handler=new Handler(){

65

66 @Override

67 public void handleMessage(Message msg){

68 firstBar.setProgress(msg.arg1);

69 firstBar.setSecondaryProgress(msg.arg1+10);

70 //handler.post(upRunnable);

71 if(msg.arg1=100) {

72 handler.post(upRunnable); //将要执行的线程放入到队列当中

73 }else {

74 handler.removeCallbacks(upRunnable);

75 }

76 }

77 };

78

79 //声明线程类:实现Runnable的接口

80 Runnable upRunnable=new Runnable() {

81

82 int i=0;

83 @Override

84 public void run() {//程序的运行状态

85 // TODO Auto-generated method stub

86 //postDelayed方法:把线程对象加入到消息队列中

87 // 隔2000ms(延迟)

88 System.out.println("It's time to start...");

89 i=i+10;

90 //获取Message消息对象

91 Message msg=handler.obtainMessage();

92 //将msg对象的arg1(还有arg2)对象的值设置

93 //使用这两个变量传递消息优点:系统消耗性能较少

94 msg.arg1=i;

95 try{

96 //设置当前显示睡眠1秒

97 Thread.sleep(1000);

98 }catch(InterruptedException e){

99 e.printStackTrace();

100 }

101 //将msg对象加入到消息队列当中

102 handler.sendMessage(msg);

103 if(i==100){//当值满足时,将线程对象从handle中剔除

104 handler.removeCallbacks(upRunnable);

105 firstBar.setVisibility(View.GONE);

106 //临时弹出

107

108 toast=Toast.makeText(Handler_01.this, "运行结束", Toast.LENGTH_SHORT);

109 toast.setGravity(Gravity.CENTER, 0, 0);

110 toast.show();

111 }

112 }

113 };

114 }

main.xml

1 LinearLayout xmlns:android=""

2 xmlns:tools=""

3 android:orientation="vertical"

4 android:layout_width="match_parent"

5 android:layout_height="match_parent"

6 tools:context=".Handler_01"

7

8 ProgressBar

9 android:id="@+id/firstBar"

10 style="?android:attr/progressBarStyleHorizontal"

11 android:layout_width="200dp"

12 android:layout_height="wrap_content"

13 android:visibility="gone"/

14

15 Button

16 android:id="@+id/startButton"

17 android:layout_width="wrap_content"

18 android:layout_height="wrap_content"

19 android:text="@string/start" /

20

21 Button

22 android:id="@+id/endButton"

23 android:layout_width="wrap_content"

24 android:layout_height="wrap_content"

25 android:text="@string/end" /

26

27 /LinearLayout

总结:

1)当点击开始或者运行结束的时候,都会通过调用Toas弹出临时窗口,Toast.makeText(Handler_01.this, "运行结束", Toast.LENGTH_SHORT),这一句一开始总是执行出错,原因在于必须调用它的show方法才可以显示出来,还可以通过设置它的位置来显示;

2)在xml中 android:text="@string/end",则需要在layout下的string文件中敲写相应的代码

3)原本代码有一些瑕疵,就是没有下面这一段代码:

1 if(msg.arg1=100) {

2 handler.post(upRunnable); //将要执行的线程放入到队列当中

3 }else {

4 handler.removeCallbacks(upRunnable);

5 }

这样就导致了upRunnable的run方法出现了死循环,这样,虽然程序UI本身没有问题,但是内部却又很大的缺陷

这是因为

1 if(i==100){//当值满足时,将线程对象从handle中剔除

2 handler.removeCallbacks(upRunnable);

3 firstBar.setVisibility(View.GONE);

4 toast=Toast.makeText(Handler_01.this, "运行结束", Toast.LENGTH_SHORT);

5 toast.setGravity(Gravity.CENTER, 0, 0);

6 toast.show();

7 }

这一段代码看似是把upRunnable线程从线程对象队列中移除,但是再次之前又前执行了handler.sendMessage(msg);这句代码

从而导致下面的代码又被执行到

1 public void handleMessage(Message msg){

2 firstBar.setProgress(msg.arg1);

3 firstBar.setSecondaryProgress(msg.arg1+10);

4

5 }

这样肯定会使upRunnable线程重新加入到线程对象队列中,updateThread的run方法重复执行,这就导致了死循环。所以必须加上之前的那段代码,通过判断来控制循环终止。并且run方法中的if(i==100)的那段代码也是可以不用的,不过我是写了一些其他代码就懒得优化了,这是后话了。

4) 刚刚大家看到我们可以通过敲写System.out.println在logcat中显示,一开始eclipse编译器中是没有,这是如何显示出来的?

大家可以再window的show view中找到logCat(deprecated)通过下图中绿色的“+”添加出来

然后显示内容的时候,选择右上角“V D I W E ”的I就可以比较清晰的显示出来了,当然你也可以选择另外一个logCat来显示,方法类似。

5)实际上,Handler在默认情况下,和调用它的Activity是处于同一个线程的。 上述Handler的使用示例中,虽然声明了线程对象,但是在实际调用当中它并没有调用线程的start()方法,而是直接调用当前线程的run()方法。

如果要实现调用另一个新的线程,只要注释post方法,然后加上这样两段代码即可: Thread t = new Thread(r); t.start();

Android的handler机制的原理?

Android的handler机制的原理分为异步通信准备,消息发送,消息循环,消息处理。

1、异步通信准备

在主线程中创建处理器对象(Looper)、 消息队列对象(Message Queue)和Handler对象。

2、消息入队

工作线程通过Handler发送消息(Message) 到消息队列(Message Queue)中。

3、消息循环

消息出队: Looper循环取出消息队列(Message Queue) 中的的消息(Message)。

消息分发: Looper将取出的消息 (Message) 发送给创建该消息的处理者(Handler)。

4、消息处宴贺世理

处晌肢理者(Handler) 接收处理器(Looper) 发送过来的消息(Message),根据消息(Message) 进行U操作。

handler的作用

handler是android线程之间的消息机制,拍携主要的作用是将一个任务切换到指定的线程中去执行,(准确的说是切换到构成handler的looper所在的线程中去出处理)android系统中的一个例子就是主线程中的所有操作都是通过主线程中的handler去处理的。

Handler的运行需要底层的 messagequeue和 looper做支撑。

[img]

关于androidhandler和androidhandler用法的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

标签列表