zoukankan      html  css  js  c++  java
  • Handler的使用(一)

    Handler的定义(感觉讲得挺好的):主要接受子线程发送的数据, 并用此数据配合主线程更新UI.

    解释: 
      当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程), 主线程为管理界面中的UI控件,进行事件分发, 比如说, 你要是点击一个Button,Android会分发事件到Button上,来响应你的操作.如果此时需要一个耗时的操作,例如: 联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭".这个时候我们需要把这些耗时的操作,放在一个子线程中。
      更新UI只能在主线程中更新,子线程中操作是危险的。这个时候,Handler就出现了。Android提供了Handler作为主线程和子线程的纽带。同时,Handler对象初始化后,就默认与对它初始化的进程的消息队列(该消息队列由Looper控制)绑定。Handler可以把消息和Runnble对象发送到与Handler对象所关联的消息队列中去。
      ps:不管是消息还是Runnable对象,都是发送到所在线程的消息队列中,不存在所谓的线程队列...不知道为什么别人总是说Handler绑定两个队列(消息队列,线程队列)?

    1.传递Message:

    如果在子线程中有关于UI的操作,那么就需要把数据消息作为一个Message对象发送到消息队列中,然后,由Handler中的handlerMessge方法处理传过来的数据信息,并操作UI。
    首先handler通过obtainMessage获取消息对象,然后通过sendMessage方法发送消息对象到消息队列中,再调用handleMessage方法处理消息。
    ps:(调用sendMessage方法送入消息队列后,会自动调用handleMessage方法)

    2.传递Runnable对象:

    1. 先创建一个handler对象
    2. 创建一个Runnable对象,将要执行的动作写入线程的run中 
    3. 调用handler的post方法把将Runnable对象加入到消息队列中

    方法作用:
    (1)post方法的作用:将Runnable对象加入到消息队列中.
      Google Android文档中的Post()方法:将Runnable对象r添加到消息队列中。这个Runnable对象运行在handler绑定的线程上。
      原文:Causes the Runnable r to be added to the message queue. The runnable will be run on the thread to which this handler is attached.
    (2)removeCallbacks方法的作用:从消息队列中将Runnable对象删除

    通过以下实例来演示操作,创建项目步骤:

    step1:新建android工程,命名为HandlerTest。

    step2:设置布局文件main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello" />
        
        <Button 
            android:id="@+id/button1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="开始"/>
        
        <Button 
            android:id="@+id/button2"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="结束"/>
        
        <ProgressBar 
            android:id="@+id/bar1"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"/>
        
    </LinearLayout>

    step3:设计主类HandlerTest.java

      1 package com.cb.handler;
      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.View;
      8 import android.view.View.OnClickListener;
      9 import android.widget.Button;
     10 import android.widget.ProgressBar;
     11 
     12 public class HandlerTest extends Activity {
     13     private ProgressBar mProgressBar;
     14     private Button mStartButton;
     15     private Button mEndButton;
     16     
     17     @Override
     18     public void onCreate(Bundle savedInstanceState) {
     19         super.onCreate(savedInstanceState);
     20         setContentView(R.layout.main);
     21         
     22         mProgressBar = (ProgressBar)findViewById(R.id.bar1);
     23         mStartButton = (Button)findViewById(R.id.button1);
     24         mEndButton = (Button)findViewById(R.id.button2);
     25 
     26         //开始按钮触发事件
     27         mStartButton.setOnClickListener(new OnClickListener() {
     28             
     29             @Override
     30             public void onClick(View v) {
     31                 mProgressBar.setVisibility(View.VISIBLE);
     32                 updateBarHandler.post(updateThread);
     33             }
     34         });
     35         
     36         //结束按钮触发事件      
     37         mEndButton.setOnClickListener(new OnClickListener() {
     38             
     39             @Override
     40             public void onClick(View v) {
     41                 updateBarHandler.removeCallbacks(updateThread);
     42                 mProgressBar.setVisibility(View.GONE);
     43             }
     44         });
     45     }
     46     
     47     //使用匿名内部类来复写handleMessage方法
     48     Handler updateBarHandler = new Handler(){
     49 
     50         @Override
     51         //handleMessage方法的作用:从消息队列中取出消息对象
     52         public void handleMessage(Message msg) {
     53             mProgressBar.setProgress(msg.arg1);
     54             //post方法的作用:将Runnable对象加入到消息队列中.
     55             updateBarHandler.post(updateThread);
     56         }
     57         
     58     };
     59     
     60     //线程类,使用匿名内部类来声明
     61     Runnable updateThread = new Runnable() {
     62         int i = 0;
     63         @Override
     64         public void run() {
     65             i = i + 10;
     66             
     67             //得到一个消息对象,Message类是由android提供
     68             Message msg = updateBarHandler.obtainMessage();
     69             
     70             //将msg对象的arg1参数设置为i,用arg1.arg2两个成员变量传递消息,优点是系统性能消耗较少
     71             msg.arg1 = i;
     72 
     73             try {
     74                 Thread.sleep(1000);
     75             } catch (Exception e) {
     76                 e.printStackTrace();
     77             }
     78             
     79             /*Pushes a message onto the end of the message queue after all pending messages before the current time. 
     80              * It will be received in handleMessage, in the thread attached to this handler.
     81              * 说明调用sendMessage方法加入消息后,会调用handleMessage方法.
     82              */
     83             
     84             //sendMessage方法的作用:将消息加入到消息队列中
     85             updateBarHandler.sendMessage(msg);
     86             
     87             if (i == 100) {
     88                 //removeCallbacks方法的作用:将Runnable对象从消息队列中移除
     89                 updateBarHandler.removeCallbacks(updateThread);
     90             }
     91             if (i > 100) {
     92                 //i的值大于100时,设置进度条不可见
     93                 mProgressBar.setVisibility(View.GONE);
     94                 
     95                 //将i置0,那么重新点开始按钮时,进度条也重新开始执行
     96                 i = 0; 
     97             }
     98         }
     99     };
    100 }

    step4:执行结果如下

  • 相关阅读:
    SQL中关于日期的常用方法
    HTMLDOM中三种元素节点、属性节点、文本节点的测试案例
    MySQL工具:管理员必备的10款MySQL工具
    The GPG keys listed not correct
    Atitit. 真正的全中国文字attilax易语言的特点以及范例
    Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27
    Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27
    Atitit .jvm 虚拟机指令详细解释
    Atitit .jvm 虚拟机指令详细解释
    Atitit.java jna  调用c  c++ dll的原理与实践  总结  v2  q27
  • 原文地址:https://www.cnblogs.com/chenbin7/p/2497173.html
Copyright © 2011-2022 走看看