Android 多线程开发介绍
2017-04-10 16:23
337 查看
Android 多线程
为什么要多线程开发?因为默认的我们的任务是在主线程(UI线程)这一单线程模式下执行的,如果主线程执行过于繁重,耗时的操作时,将会阻塞线程, 一旦线程被阻塞,将无法分派任何事件,包括绘图事件。 从用户的角度来看,应用显示为挂起。 更糟糕的是,如果 UI 线程被阻塞超过几秒钟时间(目前大约是 5 秒钟),用户就会看到一个让人厌烦的“应用无响应”(ANR)
对话框。如果引起用户不满,他们可能就会决定退出并卸载此应用。
因此我们需要新建线程,把耗时的任务放在子线程(非UI线程)中。
一、线程的创建
有两种方式:
1.继承Thread类,实现run()方法
class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // 执行耗时操作 . . . } }
PrimeThread p = new PrimeThread(143); p.start();
2.实现Runnable接口,并重写run()方法。并创建实例用做Thread的构造函数。
class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { //执行耗时操作 . . . } }
PrimeRun p = new PrimeRun(143); new Thread(p).start();
二、线程间通信
耗时任务在子线程执行完成后,要把结果显示出来。
例如,以下代码演示了一个点击侦听器从单独的线程下载图像并将其显示在 ImageView中:
public void onClick(View v) { new Thread(new Runnable() { public void run() { Bitmap b = loadImageFromNetwork("http://example.com/image.png"); mImageView.setImageBitmap(b); } }).start(); }
猛一看可能觉得是正常的,但是运行的话,就会出问题,崩溃。原因是,不能在子线程更新UI。
解决方法:1.Activity.runOnUiThread(Runnable)
2.View.post(Runnable)
3.View.postDelayed(Runnable,
long)
例如,你可以通过使用
View.post(Runnable)方法修复上述代码:
public void onClick(View v) { new Thread(new Runnable() { public void run() { final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png"); mImageView.post(new Runnable() { public void run() { mImageView.setImageBitmap(bitmap); } }); } }).start(); }
4.Handler异步消息处理
Handler mHandler =new Handler(){
handleMessage(Message message){
//更新UI
...
}
}
new Thread(new Runnable(){
//耗时操作
...
mHandler.sendMessage();
});
5.AsyncTask
AsyncTask允许对用户界面执行异步操作。 它会先阻塞工作线程中的操作,然后在 UI
线程中发布结果,而无需您亲自处理线程和/或处理程序。
要使用它,必须创建
AsyncTask的子类并实现
doInBackground()回调方法,该方法将在后台线程池中运行。
要更新 UI,应该实现
onPostExecute()以传递
doInBackground()返回的结果并在
UI 线程中运行,以便您安全地更新 UI。 稍后,您可以通过从 UI 线程调用
execute()来运行任务。
例如,您可以通过以下方式使用
AsyncTask来实现上述示例:
public void onClick(View v) { new DownloadImageTask().execute("http://example.com/image.png"); } private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { protected Bitmap doInBackground(String... urls) { return loadImageFromNetwork(urls[0]); } protected void onPostExecute(Bitmap result) { mImageView.setImageBitmap(result); } }
现在 UI 是安全的,代码也得到简化,因为任务分解成了两部分:一部分应在工作线程内完成,另一部分应在 UI 线程内完成。
下面简要概述了 AsyncTask 的工作方法
可以使用泛型指定参数类型、进度值和任务最终值
方法
doInBackground()会在工作线程上自动执行
onPreExecute()、
onPostExecute()和
onProgressUpdate()均在
UI 线程中调用
doInBackground()返回的值将发送到
onPostExecute()
您可以随时在
doInBackground()中调用
publishProgress(),以在
UI 线程中执行
onProgressUpdate()
您可以随时取消任何线程中的任务
相关文章推荐
- Android开发--多线程中的Handler机制/Looper的介绍
- Android开发--多线程中的Handler机制/Looper的介绍
- Android系统防火墙开发一(1)功能介绍
- Android开发视频教程之十九(Content Provider初步介绍)
- Android开发_多线程详解(九)
- 《智能设备艺术、科技、文化作品实例开发与设计》android开发系列介绍
- Android 插件化开发——入门知识、介绍流派、技术困境、未来方向(总结)
- iOS开发多线程篇—多线程简单介绍
- android开发之多线程实现方法概述
- 用Kotlin开发Android应用(I):介绍
- 《智能设备艺术、科技、文化作品实例开发与设计》android开发系列介绍---1.2琴类作品:吉他
- iOS开发多线程----简单介绍篇
- Android游戏开发之数据库SQLite 详细介绍(十七)
- android开发中TableLayout的一些属性介绍
- Android上的OpenGLES程序--开发环境介绍
- Android游戏开发之数据库SQLite 详细介绍(八)
- 使用PHP开发Android应用程序技术介绍
- Android网络开发之基本介绍
- Android开发之WebService介绍---WebService(一)
- PhoneGap 在 Android 上的插件开发方法介绍