Android中的多线程-Handler
程序员文章站
2022-04-19 15:05:32
对于UI线程中比较耗时的工作,开启一个子线程来处理这些工作: 首先创建一个Thread对象,然后调用start( )方法启动新的子线程。使用子线程解决异步执行带来的新问题: 在Android中,只有UI线程(即主线程)才可以更新主UI界面,而其子线程不能更新UI视图。使用多线程实现:Thread+HandlerHandler定义在主线程中(UI线程中);Handler充当主线程和子线程之间交互的中介:Handler在新启动的子线程中发送消息; Handler在主线程中获取并处理子线程...
对于UI线程中比较耗时的工作,开启一个子线程来处理这些工作: 首先创建一个Thread对象,然后调用start( )方法启动新的子线程。
使用子线程解决异步执行带来的新问题: 在Android中,只有UI线程(即主线程)才可以更新主UI界面,而其子线程不能更新UI视图。
使用多线程实现:Thread+Handler
Handler定义在主线程中(UI线程中);
Handler充当主线程和子线程之间交互的中介:
- Handler在新启动的子线程中发送消息;
- Handler在主线程中获取并处理子线程所发送的消息。
Handler的使用方法
重要的类:
- UI线程:创建UI线程时,初始化一个Looper对象以及与其关联的MessageQueue;
- Handler:发送与处理信息,在当前线程中有一个Looper对象;
- Message:Handler接收与处理的消息对象;
- MessageQueue:消息队列,管理Message;
- Looper:管理MessageQueue, 取出Message分发给对应的Handler处理,每个线程只有一个Looper。
Handler类的常用方法如下表所列:
★ 基本流程 - 创建Handler,并添加handleMessage方法。
使用自定义的匿名子类的方法创建Handler对象,并重写handleMessage方法实现消息的处理。
Handler handler = new Handler() {
public void handleMessage (Message msg) {
switch (msg.what) {
case MSG_CURRENT: // TODO
break;
}
}
};
★ 基本流程 - 创建Thread对象,在Thread对象的run方法中发送消息。
使用自定义的匿名子类的方法创建Thread对象,并重写run方法实现消息的参数设置和添加到消息队列中等操作。
Thread backgroundThread = new Thread() {
public void run() {
Message msg = handler.obtainMessage();
msg.what = MSG_CURRENT;
handler.sendMessage(msg);
}
};
★ 基本流程 - 启动Thread对象:
backgroundThread.start();
示例(求斐波那契数):
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private EditText etInput = null;
private TextView tvOutput = null;
private Handler mainHandler = null;
private Handler workHandler = null;
private final int WORK_TO_MAIN = 1;
private final int MAIN_TO_WORK = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etInput = findViewById(R.id.et_input);
tvOutput = findViewById(R.id.tv_output);
// 在UI主线程创建Handler
mainHandler = new Handler() {
// 当Handler在消息队列中获取到消息时被调用
@Override
public void handleMessage(Message msg) {
Log.e("Handler",
Thread.currentThread().getName()
+ ":4收到数据:" + msg);
switch (msg.what) {
case WORK_TO_MAIN:
tvOutput.setText((long)msg.obj+"");
tvOutput.setBackgroundColor(
Color.rgb(255,0,0));
break;
}
}
};
MyThread thread = new MyThread();
thread.start();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String strInput = etInput.getText().toString();
int n = Integer.parseInt(strInput);
Message msg = new Message();
msg.obj = n;
msg.what = MAIN_TO_WORK;
workHandler.sendMessage(msg);
Log.e("Handler",
Thread.currentThread().getName()
+ ":3发送数据:" + msg);
}
});
}
// 自定义的线程类
private class MyThread extends Thread {
@Override
public void run() {
Looper.prepare();
workHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.e("Handler",
Thread.currentThread().getName()
+ ":1收到数据:" + msg);
switch (msg.what) {
case MAIN_TO_WORK:
int n = (int)msg.obj;
long answer = fib(n);
Message msgAnswer = new Message();
msgAnswer.obj = answer;
msgAnswer.what = WORK_TO_MAIN;
mainHandler.sendMessage(msgAnswer);
Log.e("Handler",
Thread.currentThread().getName()
+ ":2发送数据:" + msgAnswer);
break;
}
}
};
Looper.loop();
}
}
// 求第n项的斐波那契数为多少,1=1, 2=1, 3=2, 4=3, 5=5, 6=8 ...
private long fib(int n) {
if(n==1 || n==2)
return 1;
else
return fib(n-1) + fib(n-2);
}
}
运行结果:
本文地址:https://blog.csdn.net/qq_43573997/article/details/107284619
推荐阅读
-
Android 中ScrollView嵌套GridView,ListView的实例
-
Android 中RecyclerView通用适配器的实现
-
Android的HTTP多线程下载示例代码
-
centos7中安装Android SDK的方法步骤
-
详解Android 8.1.0 Service 中 弹出 Dialog的方法
-
Python中多线程thread与threading的实现方法
-
android在异步任务中关闭Cursor的代码方法
-
Android加载大分辨率图片到手机内存中的实例方法
-
android轻松管理安卓应用中的log日志 发布应用时log日志全部去掉的方法
-
详解Java编程中的反射在Android开发中的应用