• Handler消息机制


    Handler的定义:
              主要接受子线程发送的数据, 并用此数据配合主线程更新UI.
              解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。  如果此时需要一个耗时的操作,例如: 联网读取数据,    或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,,会收到Android系统的一个错误提示  "强制关闭".  这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的. 这个时候,Handler就出现了.,来解决这个复杂的问题 ,    由于Handler运行在主线程中(UI线程中),  它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI。

    本程序功能: 利用Handler实现时间和图片的持续更新  

    xml文件:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical" 
     6     android:gravity="center_horizontal">
     7 
     8     <ImageView 
     9         android:id="@+id/iv"
    10         android:layout_width="wrap_content"
    11         android:layout_height="wrap_content"
    12         android:src="@drawable/ic_launcher"/>
    13     <TextView 
    14         android:id="@+id/tv"
    15         android:layout_width="wrap_content"
    16         android:layout_height="wrap_content"
    17        />
    18 </LinearLayout>
    View Code

    java代码如下:

      1 import java.text.SimpleDateFormat;
      2 import java.util.Date;
      3 import java.util.Timer;
      4 import java.util.TimerTask;
      5 
      6 import android.annotation.SuppressLint;
      7 import android.app.Activity;
      8 import android.os.Bundle;
      9 import android.os.Handler;
     10 import android.os.Message;
     11 import android.widget.ImageView;
     12 import android.widget.TextView;
     13 
     14 @SuppressLint("SimpleDateFormat")
     15 public class HanderActivity extends Activity {
     16     // 控制时间的更新
     17     private static final int Time = 1;
     18     // 控制图片的更新
     19     private static final int Imge = 2;
     20     private ImageView iv;
     21     private TextView tv;
     22     private int index = 0;
     23     private int[] sorce = { R.drawable.img1, R.drawable.img2, R.drawable.img3,
     24             R.drawable.img4, R.drawable.img5, R.drawable.img6, R.drawable.img7,
     25             R.drawable.img8 };
     26     private SimpleDateFormat format = new SimpleDateFormat(
     27             "yyyy年-MM月-dd日  HH时:mm分:ss秒");
     28 
     29     /* (non-Javadoc)
     30      * @see android.app.Activity#onCreate(android.os.Bundle)
     31      */
     32     @SuppressLint("HandlerLeak")
     33     @Override
     34     protected void onCreate(Bundle savedInstanceState) {
     35         super.onCreate(savedInstanceState);
     36         setContentView(R.layout.activity_hander);
     37         iv = (ImageView) findViewById(R.id.iv);
     38         tv = (TextView) findViewById(R.id.tv);
     39 
     40         
     41         // Android应用中,我们页面都是主线程或UI线程中进行呈现,如果我们在我们UI线程中进行耗时性操作的话,我们UI线程就会出现ANR(Application
     42         // not respose),所以我们要子线程中进行耗时性操作内容,但是这样有不容易触及我们UI控件,所以Android提供了Handler,用于在主线程和子线程之间传递和接受消息
     43         
     44 
     45         final Handler hander = new Handler() {
     46             //重写handlerMessage()方法
     47             @Override
     48             public void handleMessage(Message msg) {
     49                 if (msg.what == Time) {
     50                     Bundle data = msg.getData();
     51                     String time = data.getString("time");
     52                     tv.setText(time);
     53                 } else if (msg.what == Imge) {
     54                     Bundle data = msg.getData();
     55                     int image = data.getInt("img");
     56                     iv.setImageResource(sorce[image]);
     57                 }
     58             }
     59 
     60         };
     61         //    开启一个子线程,用于进行耗时的操作,完成后向hander发送数据
     62         //此线程是控制时间更新的
     63         new Thread() {
     64             public void run() {
     65                 while (true) {
     66                     Message msg = new Message();
     67                     //指定类型
     68                     msg.what = Time;
     69                     Bundle b = new Bundle();
     70                     //向Bundle中放入数据
     71                     b.putString("time", format.format(new Date()));
     72                     //指定数据
     73                     msg.setData(b);
     74                     //向handler发送数据
     75                     hander.sendMessage(msg);
     76                     try {
     77                         //每隔一秒更新一次时间
     78                         sleep(1000);
     79                     } catch (InterruptedException e) {
     80                         e.printStackTrace();
     81                     }
     82                 }
     83             };
     84 
     85         }.start();
     86         
     87         /**开启一个定时器,用于定时更新图片的。
     88          *第一个参数:类似Runnable接口
     89             第二个参数:第一次执行延迟多久
     90             第三个参数:就是以后执行的周期,多长时间执行一次
     91          */
     92         new Timer().schedule(new TimerTask() {
     93 
     94             @Override
     95             public void run() {
     96                 /**防止数组下标越界,如果达到最大值让index重新置为0,*/
     97                 if (index == sorce.length) {
     98                     index = 0;
     99                 }
    100                 Message msg = new Message();
    101                 msg.what = Imge;
    102                 Bundle b = new Bundle();
    103                 b.putInt("img", index);
    104                 msg.setData(b);
    105                 hander.sendMessage(msg);
    106                 index++;
    107 
    108             }
    109         }, 0, 1000);
    110 
    111     }
    112 
    113 }

      运行的效果是:图片和时间每隔一秒就会变化一次。

  • 相关阅读:
    使用terraform管理Proxmox VE资源
    Terraform Aliyun 创建ecs, kubernetes 实例
    如何在cmd中启动redis
    图片二维码解析URL
    Python爬取百度图片
    Python 爬取b站专栏图片
    python之JS逆向—破解头条抖音登录协议
    python 连接 mongodb 获取部分字段数据并换行写入txt文件
    列表套字典三者匹配对应关系
    python线程池 ThreadPoolExecutor 的用法及实战
  • 原文地址:https://www.cnblogs.com/dj168/p/handler.html
Copyright © 2020-2023  润新知