Android中的Handle(句柄)

lookingFor 2020-06-20

一、Handle(句柄)是什么?

(1)、结合线程所在消息队列来更新用户界面(UI)的一套消息处理机制 

(2)、Handle消息传递机制流程图

Android中的Handle(句柄)

由以上可知:主线程无法处理时间比较繁长的任务,需要子线程进行处理,而子线程无法进行用户界面(UI)更新,需要使用handler来传递消息给主线程,让主线程完成用户界面(UI)更新。由于主线程和子线程进行不同的时间工作,所以需要用MessageQueue来存放子线程的消息,让Looper取出消息交给主线程响应。

二、Handle(句柄)有什么用?

 接受子线程发送的数据, 并用此数据配合主线程更新用户界面(UI),用于线程间的通讯。通俗点的解释:当一个应用程序打开的时,Android系统首先会开启一个主线程(即UI线程)。UI线程主要是管理界面上的那些控件,如:文本框,编辑框,按钮等。当点击一个按钮时,用户界面(UI)线程就会分发事件到按钮上,以此来响应接下来的操作(如要绘制一个图,显示一个美女等等)。而如果这个图特复杂,或者这个美女画质特别高(一般画质特别高,即像素特别高,也就是同样大小的方块中,像素点特别特别的多,简单点就是这张图片特别大),此时线程就会为了这个而进行计算,如果5秒钟内还没有计算完的话,界面就会出现假死现象,因为Android系统的Acitivity响应时间为5秒,超过了就要出问题(弹出一个“强制关闭”的对话框)。如果我们把这种耗时的操作放在子线程,就要好的多了。当子线程计算完了(不管花了多久),此时只要发一个消息给主线程,告诉它计算完了,准备好了,那么主线程就可以直接进行绘制或者显示了。为什么不干脆绘制或者将显示的工作放在子线程中进行呢?因为界面只有一个,而这个界面的有关操作已经纳入了主线程中,所以如果子线程要去更改界面的内容的话,就会出现问题。也就是说更新UI只能在主线程中。而Handler的作用就是接收子线程完成耗时操作反馈回来的信息,并用此数据配合主线程更新用户界面(UI)。文艺点的解释:一个正在唱歌的女郎(主线程用户界面(UI)),语音播报(按了一个按钮之类的)下一个节目是吉它表演(按钮的监听事件),此时这个吉它就要后台的人来为她准备,因为她正在唱着歌呢。这时后台的人发现吉它找不到了(耗时操作),怎么办?时间是很宝贵的,如果继续唱歌,难免会被会质疑的,因此,当她唱完歌时,只能跳到下下个节目跳舞的表演(主线程继续往下走),而后台的人则拼命的去找吉它(使用子线程进行耗时操作)。终于,后台的人告诉她“吉它”找到了(收到子线程的反馈信息)。她立马结束了当前的节目。因为之前连表演了好几个节目(不耗时的操作),但人们最期待的还是它的吉它表演。于是,她拿上后台给她的吉它开始表演起吉它演奏来(进行主线程更新操作)。

三、Handle(句柄)咋么用?

(1)、新建Handle如下所示 

private  Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg)  {
     super.handleMessage(msg);
    }
   };

(2)、从子线程中发出消息如下所示 

Message message=handler.obtainMessage();
message.what=1;
message.arg1=i;
message.obj="倒计时:";
handler.sendMessage(message);

(3)、在Handler中捕获所需消息,实现响应。如下所示 。

private  Handler handler=new Handler()
{
    @Override
    public void handleMessage(Message msg) 
 {
     super.handleMessage(msg);
     int arg1=msg.arg1;
     String info= (String) msg.obj;
     if (msg.what==1)
   {
      textView.setText(info+arg1);
     }
     if (arg1==0)
   {
      textView.setText("完成");
     }
    }
   };

 使用Handler和线程制作简单的计时器如下所示

(4)、逻辑编程文件MainActivity.java如下所示

package com.example.HandleDemo;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
   public class ThreadActivity extends AppCompatActivity implements View.OnClickListener {
    private Button button;
    private TextView textView;
    private EditText editText;
    private int num1;
    private String num;
    private  Handler handler=new Handler()
 {
     @Override
     public void handleMessage(Message msg) 
  {
      super.handleMessage(msg);
      int arg1=msg.arg1;
      String info= (String) msg.obj;
      if (msg.what==1)
    {
       textView.setText(info+arg1);
      }
      if (arg1==0)
    {
       textView.setText("完成");
      }
     }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) 
 {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_thread);
     BlindID();
    }
    private void BlindID() 
 {
     button=findViewById(R.id.theradbtn);
     textView=findViewById(R.id.theradtext);
     editText=findViewById(R.id.theradedtext);
     button.setOnClickListener(this);
    }
    @Override
    public void onClick(View view) 
 {
     switch (view.getId())
   {
      case R.id.theradbtn:
                          num=editText.getText().toString();
                          num1=Integer.parseInt(num);
                          textView.setText("倒计时:"+num1);
                          new Thread(new Runnable() 
                       {
                           @Override
                           public void run()
                        {
                            for (int i=num1;i >=0;i--)
                         {
                             try
                           {
                              Thread.sleep(1000);
                             } 
                             catch (InterruptedException e) 
                           {
                              e.printStackTrace();
                             }
                           Message message=handler.obtainMessage();
                           message.what=1;
                           message.arg1=i;
                           message.obj="倒计时:";
                           handler.sendMessage(message);
                          }
                         }
                        }).start();
                         break;
     }
   }
}

(5)、用户界面布局文件activity_main.xml如下所示

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  tools:context="com.example.HandleDemo.ThreadActivity">
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="输入计时时间:"
      android:textSize="20sp"/>
    <EditText
      android:id="@+id/theradedtext"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:hint="请输入数字"
      android:numeric="integer"/>
  </LinearLayout>
  <View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="#000"/>
  <TextView
    android:id="@+id/theradtext"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="倒计时:**"
    android:textSize="20sp"
    android:gravity="center"/>
  <Button
    android:id="@+id/theradbtn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="开始计时"/>
</LinearLayout>

(6)、字符串资源文件strings.xml如下所示

(7)、R.java文件如下所示

(8)、功能清单配置文件AndroidManifest.xml如下所示

(9)、效果图如下所示

Android中的Handle(句柄)

相关推荐