android中handler如何使用

android中的handler如何使用... android中的handler如何使用 展开
 我来答
匿名用户
2015-03-27
展开全部
  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="http://schemas.android.com/apk/res/android"

  2 xmlns:tools="http://schemas.android.com/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();
千锋教育
2015-10-10 · 做真实的自己 用良心做教育
千锋教育
千锋教育专注HTML5大前端、JavaEE、Python、人工智能、UI&UE、云计算、全栈软件测试、大数据、物联网+嵌入式、Unity游戏开发、网络安全、互联网营销、Go语言等培训教育。
向TA提问
展开全部
1、调用函数getOf_getOn();
2、异步获取数据
public void getOf_getOn() {
new Thread(new Runnable() {
@Override
public void run() {

List<HashMap<String, String>> listOut = new ArrayList<HashMap<String, String>>();
// 从数据库中异步获取数据
listOut = paymentManager.checkPremissions(errorlist_menu.this,
userID, txtTitle.getText().toString());
Message msg = new Message();
msg.obj = listOut;
msg.what = 1;
handlerinformationtest.sendMessage(msg);
}
}).start();
}
3、异步接收数据
Handler handlerinformationtest = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);

if (msg.what == 1) {
List<HashMap<String, String>> list = (List<HashMap<String, String>>) msg.obj;
if (list.size() > 0) {
HashMap<String, String> hashMapOut = new HashMap<String, String>();
hashMapOut = list.get(0);
gsft_id = hashMapOut.get("Gsft_id");
gsft_flag = hashMapOut.get("Gsft_flag");
}

}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式