赞
踩
Android中UI线程对于开发者和用户来说都是最主要接触到的线程。一般来说为了UI流畅、不卡顿,耗时操作是不推荐放在UI线程中的。但是耗时操作的需求又是存在的,这时候就需要用到多线程编程了,新建一条子线程去处理耗时操作。这篇文章将对相关内容进行简单介绍。
Android应用大部分都是用Java开发的,所以Java中的一些多线程编程方式在Android里也是可以使用的。
这是最基本的多线程操作:
// 定义继承自Thread的类
class MyThread extends Thread {
// 重写run方法
public void run() {
// TODO
}
}
MyThread t = new MyThread();
t.start(); // 创建新线程并启动,线程启动后会运行其中run方法
// new MyThread().start(); // 直接启动方式
前面用的是继承的方式,只能继承一个类,所以更加常见的是使用下面这种方式:
// 定义类来实现Runnable接口
class MyRunnable implements Runnable {
// 实现接口中的run方法
public void run() {
// TODO
}
}
Thread t = new Thread(new MyRunnable());
t.start(); // 创建新线程,线程启动后会运行其中run方法
// new MyThread().start(); // 直接启动方式
很多时候也可以直接使用匿名内部类方式:
// 匿名内部类方式
Thread t = new Thread(new Runnable(){
public void run() {
// TODO
}
});
t.start();
上面演示中在子线程中每隔1000ms执行一次操作,如果只是需要这种定时任务的话使用定时器更加方便些:
// import java.util.Timer;
// import java.util.TimerTask;
Timer timer = new Timer(); // Timer用来调度运行TimerTask对象
// 一个Timer可以调度多个TimerTask
TimerTask task = new TimerTask() {
public void run() {
// TODO
}
};
// timer.schedule(task, 2000); // 延迟2000ms后运行一次task
timer.schedule(task, 2000, 1000); // 延迟2000ms后运行一次task,然后每隔1000ms重复运行task
Android中子线程是不能更新UI的,但很多时候又需要子线程处理一些耗时操作,然后根据操作结果来更新UI。针对这个业务需求Android中又提供了一些多线程机制。
Handler本身并不是多线程,它只是提供一种机制,使一个线程可以发送消息给另一个线程,通常默认情况下就是子线程发送消息给UI线程,这样UI线程就可以根据接收到的消息来做对应的处理,比如更新UI元素等。
Handler通常和前面Java的多线程方式结合使用。下面是个简单的演示:
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class MainActivity extends AppCompatActivity { // 声明Handler对象并重写handleMessage方法 @SuppressLint("HandlerLeak") private final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // 收到消息时会触发handleMessage方法 // 这个Handler对象在哪个线程,handleMessage方法就在哪个线程执行 TextView text = findViewById(R.id.text); text.setText(msg.obj.toString()); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Timer().schedule(new TimerTask() { public void run() { Message message = new Message(); // 新建消息 message.obj = new Date(System.currentTimeMillis()); // 填充消息内容 handler.sendMessage(message); // 发送消息 } }, 2000, 2000); // 每两秒触发一次定时器子线程 } }
上面演示中子线程可以创建 Message
对象,这个对象中可以保存 obj
等很多东西。通过 Handler
对象的一些方法,比如上面 sendMessage()
方法可以将 Message
发送给 Handler
所在线程。在 Handler
所在线程中会有 MessageQueue
用来接收这些 Message
,还有 Looper
进行消息处理,最终调用 Handler
对象的 handleMessage()
方法。在UI线程中 MessageQueue
和 Looper
默认都会自动创建的。
现在的Android版本中上面这样的使用方式会被认为可能引起Activity泄漏,可以改用下面方式:
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; import java.lang.ref.WeakReference; import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class MainActivity extends AppCompatActivity { private static class MyHandler extends Handler { //弱引用持有MainActivity , GC 回收时会被回收掉 private final WeakReference<MainActivity> weakReference; public MyHandler(MainActivity activity) { this.weakReference = new WeakReference(activity); } @Override public void handleMessage(Message msg) { MainActivity activity = weakReference.get(); if (activity != null) { TextView text = activity.findViewById(R.id.text); text.setText(msg.obj.toString()); } } } private final MyHandler myHandler = new MyHandler(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Timer().schedule(new TimerTask() { public void run() { Message message = new Message(); message.obj = new Date(System.currentTimeMillis()); myHandler.sendMessage(message); } }, 2000, 2000); } }
AsyncTask是Android另一个用来异步更新UI的方式,现在(API level 30,Android 11)已被弃用,这里就不再进行介绍了。
多线程的基础操作是比较简单的,相对复杂的线程间同步互斥等的问题先不在这里展开,使用时注意下不同线程对同一个资源操作的问题即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。