• Handler消息传递机制——Handler类简洁


          Handler类的主要作用有两个:

    • 在新启动的线程中发送消息。
    • 在主线程中获取、处理消息。

         上面的说法很简单,只要分成两步即可:在新启动的线程中发送消息;然后在主线程上获取、并处理消息。但这个过程涉及一个问题:新启动的线程何时发送消息呢?主线程何时去获取并处理消息呢?这个时机显然不好控制。

         为了让主程序能“适时”地处理新启动的线程所发送的消息,显然只能通过回调的方式来实现——开发者只要重写Handler类中处理消息的方法,当新启动的线程发送消息时,消息会发送到与之关联的MessageQueue,而Handler会不断地从MessageQueue中获取并处理消息——这将导致Handler类中处理消息的方法被回调。

         Handler类包含如下方法用于发送、处理消息。

    • void handleMessage(Message msg):处理消息的方法。该方法通常用于被重写。
    • final boolean  hasMessages(int what):检查消息队列中是否包含what属性为指定值的消息。
    • final boolean  hasMessages(int what,Object object):检查消息队列中是否包含what属性为指定值且object属性为指定对象的消息。
    • sendEmptyMessage(int what):发送空消息。
    • final boolean sendEmptyMessageDelayed(int what,long delayMillis):指定多少毫秒之后发送空消息。
    • final boolean sendMessage(Message msg):立即发送消息。
    • final boolean sendMessageDelayed(Message msg,long delayMillis):指定多少毫秒之后发送消息。

         借助于上面这些方法,程序可以方便地利用Handler来进行消息传递。

          实例:自动播放动画

          上面的程序通过一个新线程来周期性地修改ImageView所显示的图片,通过这种方式来开发一个动画效果。该程序的界面布局代码非常简单,程序只是在界面布局中定义了ImageView组件,界面布局文件如下。

           

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:gravity="center_horizontal">
    <!-- 定义ImageView组件 -->
        <ImageView
            android:id="@+id/show"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleType="center"/>
    
    </LinearLayout>

          接下来主程序使用java.util.Timer来周期性地执行指定任务,程序代码如下。

           

    package com.example.studyevent;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.app.Activity;
    import android.view.Menu;
    import android.widget.ImageView;
    
    public class HandlerTest extends Activity {
      //定义周期性显示的图片的ID
        int[] imageIds=new int[]{
                R.drawable.java,
                R.drawable.ee,
                R.drawable.ajax,
                R.drawable.xml,
                R.drawable.classic
        };
        int currentImageId=0;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_handler_test);
            final ImageView show=(ImageView)findViewById(R.id.show);
            final Handler myHandler=new Handler(){
    
                @Override
                public void handleMessage(Message msg) {
                    // TODO Auto-generated method stub
                    //如果该消息是本程序所发送的
                    if(msg.what==0x1233)
                    {
                        //动态地修改所显示的图片
                        show.setImageResource(imageIds[currentImageId++%imageIds.length]);
                    }
                }
            };
            //定义一个计时器,该计时器周期性的执行指定任务
            new Timer().schedule(new TimerTask(){
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    //发送空消息
                    myHandler.sendEmptyMessage(0x1233);
                }
            }, 0,1200);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.handler_test, menu);
            return true;
        }
    
    }

          上面的程序中下面的粗体字代码通过Timer周期性地执行指定任务,Timer对象可调度TimerTask对象,TimerTask对象的本质就是启动一条新线程,由于Android不允许在新线程中访问Activity里面的界面组件,因此程序只能在新线程里发送一条消息,通知系统更新ImageView组件。

           上面的程序的第一段粗体字代码重写了Handler的handleMessage(Message msg)方法,该方法用于处理消息——当新线程发送消息时,该方法会被自动回调,handleMessage(Message msg)方法依然位于主线程,所以可以动态地修改ImageView组件的属性。这就实现了本程序所要达到的效果;由新线程来周期性地修改ImageView的属性,从而实现动画效果。运行上面的程序可看到应用程序中5张图片交替显示的动画效果。

  • 相关阅读:
    文本切换器(TextSwitcher)的功能和用法
    图像切换器(ImageSwitcer)的功能与用法
    ViewSwitcher的功能与用法
    HTTP协议-get请求与post请求的区别
    HTTP协议缓存
    HTTP协议详解
    Vue.js----更换头像不实时更新问题
    Vue.js----date与时间戳的转换(unixTime)Moment.js让日期处理变得更简单
    Let's Encrypt 免费通配 https 签名证书 安装方法
    小程序Openid 获取,服务器 encryptedData 解密 遇到的坑
  • 原文地址:https://www.cnblogs.com/wolipengbo/p/3409302.html
Copyright © 2020-2023  润新知