android开发笔记(一)消息机制

本文章是学习尚硅谷android系列视频中的《消息机制与异步任务》章节所记载的笔记。

Message:消息

  • 可理解为线程间通讯的数据单元,可通过message携带需要的数据
  • 创建对象:Message.obtain(what)
  • 封装数据:

public int what  //id标识

public int arg1

public int arg2

public Object obj

Handler:处理器

  • Handler是Message的处理器,同时也负责消息的发送和移除工作
  • 发送即时消息:sendMessage(Message msg)
  • 发送延时消息:sendMessageDelayed(Message msg,long time)(实际是延时处理不是延时发送)
  • 处理消息:handleMessage(Message msg)(回调方法)
  • 移除还未处理的消息:removeMessages(int what)

MessageQueue:消息队列

  • 用来存放通过Handler发送的消息
  • 它是一个按Message的when排序的优先级队列

Looper(钩子):循环器

  • 负责循环取出MessageQueue里面的当前需要处理的Message
  • 交给对应的Handler进行处理
  • 处理完后,将Message缓存到消息池中,以备复用

Handler的基本使用步骤:

  1. 创建Handler成员变量对象,并重写handleMessage(Message msg)方法
  2. 在分/主线程创建Message对象
  3. 使用Handler对象发送Message
  4. 在handleMessage(Message msg)中处理消息
activity代码:

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.HashMap;

public class MainActivity extends AppCompatActivity {
    private String address = "https://www.sojson.com/open/api/weather/json.shtml?";
    ProgressDialog progressDialog;
    private Button button;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }

    private void initViews(){
        progressDialog = new ProgressDialog(this);
        progressDialog.setTitle("加载中...");
        progressDialog.setCancelable(true);
        textView = findViewById(R.id.textView);
        button = findViewById(R.id.button);
        button.setOnClickListener(onClickListener);
    }

    View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.button:
                    getWeather();
                    break;
            }
        }
    };

    @SuppressLint("HandlerLeak")
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(progressDialog != null && progressDialog.isShowing()){
                progressDialog.dismiss();
            }
            textView.setText(msg.getData().getString("weather"));
        }
    };


    private void getWeather(){
        progressDialog.show();
        new Thread(new Runnable() {
            @Override
            public void run() {
                HashMap<String,String> map = new HashMap<>();
                map.put("city","成都");
                String result = HttpNetTool.requestGet(map,address);
                Message message = Message.obtain(handler,1);
                Bundle bundle = new Bundle();
                bundle.putString("weather",result);
                message.setData(bundle);
                handler.sendMessage(message);
            }
        }).start();
    }
}





xml代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="获取天气"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

权限:

    <uses-permission android:name="android.permission.INTERNET"/>

Handler的小DEMO:

Activity代码:

package com.atguigu.l05_handler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 使用Handler的小DEMO
 * @author 张晓飞
1. 手动增加/减少
2. 自动增加/减少
3. 限制数字的最大和最小值 [1,20]
4. 限制Button可操作性
 */
public class HandlerDemoActivity extends Activity implements OnClickListener {

	private static final int WHAT_INCREASE = 1;
	private static final int WHAT_DECREASE = 2;
	
	
	private TextView tv_demo_number;
	private Button btn_demo_increase;
	private Button btn_demo_decrease;
	private Button btn_demo_pause;
	
	private Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			//得到当前显示的数值
			int number = Integer.parseInt(tv_demo_number.getText().toString());
			switch (msg.what) {
			case WHAT_INCREASE:
				//限制number<=20
				if(number==20) {
					//设置暂停不能操作
					btn_demo_pause.setEnabled(false);
					Toast.makeText(HandlerDemoActivity.this, "已经达到最大值", 0).show();
					return;
				}
				
				number++;
				tv_demo_number.setText(number+"");
				//发送增加的延迟消息
				handler.sendEmptyMessageDelayed(WHAT_INCREASE, 1000);
				break;
			case WHAT_DECREASE:
				//限制number>=1
				if(number==1) {
					//设置暂停不能操作
					btn_demo_pause.setEnabled(false);
					Toast.makeText(HandlerDemoActivity.this, "已经达到最小值", 0).show();
					return;
				}
				number--;
				tv_demo_number.setText(number+"");
				//发送减少的延迟消息
				handler.sendEmptyMessageDelayed(WHAT_DECREASE, 1000);
				break;
			default:
				break;
			}
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_handler_demo);
		init();
	}

	private void init() {
		tv_demo_number = (TextView) findViewById(R.id.tv_demo_number);
		btn_demo_increase = (Button) findViewById(R.id.btn_demo_increase);
		btn_demo_decrease = (Button) findViewById(R.id.btn_demo_decrease);
		btn_demo_pause = (Button) findViewById(R.id.btn_demo_pause);
		
		btn_demo_increase.setOnClickListener(this);
		btn_demo_decrease.setOnClickListener(this);
		btn_demo_pause.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		if(v==btn_demo_increase) {//自动增加  what =1
			//限制Button可操作性
			btn_demo_increase.setEnabled(false);
			btn_demo_decrease.setEnabled(true);
			btn_demo_pause.setEnabled(true);
			
			//停止减少(移除未处理的减少的消息)
			handler.removeMessages(WHAT_DECREASE);
			//发消息(增加)
			handler.sendEmptyMessage(WHAT_INCREASE);
		} else if(v==btn_demo_decrease) {//自动减少 what=2
			//限制Button可操作性
			btn_demo_increase.setEnabled(true);
			btn_demo_decrease.setEnabled(false);
			btn_demo_pause.setEnabled(true);
			
			//停止增加(移除未处理的增加的消息)
			handler.removeMessages(WHAT_INCREASE);
			
			//发消息(减少)
			handler.sendEmptyMessage(WHAT_DECREASE);
		} else if(v==btn_demo_pause) {//暂停
			
			//限制Button可操作性
			btn_demo_increase.setEnabled(true);
			btn_demo_decrease.setEnabled(true);
			btn_demo_pause.setEnabled(false);
			
			//停止增加/减少(移除未处理的减少/增加的消息)
			handler.removeMessages(WHAT_INCREASE);
			handler.removeMessages(WHAT_DECREASE);
		}
	}
}

XML代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_demo_number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="10"
        android:textColor="#ff0000" 
        android:textSize="20sp"/>

    <Button
        android:id="@+id/btn_demo_increase"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="自动增加" />

    <Button
        android:id="@+id/btn_demo_decrease"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="自动减少" />

    <Button
        android:id="@+id/btn_demo_pause"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="暂停" 
        android:enabled="false"/>

</LinearLayout>

Handler原理:

源码简单解析:

Message:

属性:

  • public int what;//标识(id)
  • public int arg1;//保存int数据
  • public int arg2;//保存int数据
  • public Object obj;//保存任意数据
  • long when;//记录应该被处理的时间值
  • Handler target;//处理message的handler的引用,也就是发消息的handler
  • Runnable callback;//用来处理消息的回调器
  • Message next;//指向下一个Message,用来形成一个链表
  • private static Message sPool;//用来缓存处理过的Message对象,以便复用

方法:

  • public static Message obtain();//它利用了Message中的消息池(sPool) 

Handler:

方法:

  • sendMessage(Message msg);//发送即时消息
  • sendMessageDelayed(Message msg,long delayMillis);//发送延时消息
  • sendEmptyMessage(int what);//发送即时得空消息
  • sendEmptyMessageDelayed(int what,long delayMillis);//发送空的延时消息
  • sendMessageAtTime(Message msg,long uptimeMillis);//
  • removeMessages(int what);//移除还未处理的消息
  • handleMessage(Message msg);//处理消息的回调

MessageQueue:

方法:

  • enqueueMessage(Message msg,long when);//将Message添加到队列中,根据when来排序

Looper:

方法:

  • loop();//核心方法

final Looper me = myLooper();//得到Looper对象

final MessageQueue queue = me.mQueue;//得到消息对列对象

for(;;){

                    Message  msg = queue.next();//可能处于等待状态,但是不会阻塞主线程

                    ......

                    msg.target.dispatchMessage(msg);//调用Handler去分发消息,并处理消息

                    msg.recycle();//回收message

}

 

猜你喜欢

转载自blog.csdn.net/wangsangun/article/details/81835769