android Handler消息传递机制

三世轮回 提交于 2020-12-14 03:57:13

  出于性能优化的考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI,可能导致线程安全问题。为了解决这个问题,Android制定了一条简单的规则:只允许UI线程修改Activity的UI组件。

  当一个程序第一次启动时,Activity会同时启动一条主线程,主线程主要负责处理与UI相关的事件,如用户的按键操作、用户触摸屏幕的事件及屏幕绘制事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。

  Android的消息传递机制是另一种形式的“事件处理”,这种机制主要为解决Android应用的多线程问题---Android平台只允许UI线程修改Activity里的UI组件,这就会导致新启动的线程无法动态改变界面组件的属性值。但实际在开发中,尤其是涉及动画的游戏开发中,需要让新启动的线程周期性的改变界面组件的属性值,这就需要借助于Handler的消息传递机制

  Handler类主要作用有两个

  ---在新启动的线程中发送消息;

  ---在主线程中获取、处理消息。

  上面的说法看上去很简单,似乎只分成两步:在新线程中发送消息,然后再主线程中获取并处理消息即可。但过程中涉及一个问题,新启动的线程何时发送消息?主线程又何时处理消息?时机如何控制?

  为了解决处理消息问题,只能通过回调的方式来实现---重写Handler类的handleMessage()方法。 当新启动的线程发送消息时,消息会发送到与之关联的MessageQueue,而Handler会不断从MessageQueue中获取并处理消息--这将导致Handler中处理消息的方法被回调。

 

计算质数实例:

package com.example.calprime;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

private static final String DATA_NUM = "num";
private static final String RESULT_KEY = "result_key";

EditText editText;
MyThread myThread;
TextView result;

class MyThread extends Thread {

public Handler mHandler;

@Override
public void run() {
// super.run();
Looper.prepare();
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0x110) {
int num = msg.getData().getInt(DATA_NUM);
List<Integer> nums = new ArrayList<>();

//计算从2开始到num的所有质数
for (int i = 2; i <= num; i++) {
//用i除以从2开始,到i的平方根的所有数
boolean isadd = true;
for (int j = 2; j <= Math.sqrt(i); j++) {
//如果可以整除,则不是质数
if (i != 2 && i % j == 0) {
isadd = false;
continue;
}
}
if (isadd) {
nums.add(i);
}
}

//Toast显示
Toast.makeText(MainActivity.this, nums.toString(), Toast.LENGTH_LONG).show();
Message message = new Message();
message.what = 0x111;
Bundle bundle = new Bundle();
bundle.putString(RESULT_KEY, nums.toString());
message.setData(bundle);
mUiHandler.sendMessage(message);
}
}
};
Looper.loop();
}
}

Handler mUiHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0x111) {
result.setText(msg.getData().getString(RESULT_KEY));
}
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.edit);
result = findViewById(R.id.result);
myThread = new MyThread();
myThread.start();
}

public void cal(View view) {
Message message = new Message();
message.what = 0x110;
Bundle bundle = new Bundle();
bundle.putInt(DATA_NUM, Integer.parseInt(editText.getText().toString()));
message.setData(bundle);
myThread.mHandler.sendMessage(message);
}
}

运行结果:



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!