您的位置:首页 > 移动开发 > Android开发

Android笔记----AsyncTask异步消息处理机制

2016-10-07 20:09 716 查看
引入:

还是那个问题:Android的单线程模型原则只能在主线程更新UI.

如果要在非主线程中更新UI,除了用Handler之外,还有一种封装得很好的机制AsyncTask

源码解释: AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate(操作) threads and/or handlers.

AsyncTask可以帮助我们在后台通过新线程执行操作并且把结果返回给UI线程.比起handlers它的封装性更高.

AsyncTask

参数引入:

Params

传入参数,给后台任务使用.比如我们要加载一个图片Url,则Params可以是String类型.

Progress(进度)

可以作为doInBackground执行的进度反映.

Result

任务执行完成,返回给主线程.

使用:

假如要执行耗时操作,例如加载一个网页图片或者登陆验证等

Step 1. 我们可以新建一个类继承自AsyncTask

Step 2. 重写AsyncTask的方法:

onPreExecute()

该方法用于耗时操作之前所做的准备,例如加载图片或者登陆操作之前显示进度条.

doInBackground(Params…)

该方法主要进行耗时操作,即启动新线程(已经自动封装)执行你要的操作.

注意的是该方法常伴随着publishProgress(Progress…) 语句, 该方法可以调用并且传递参数Progress给第三个方法onProgressUpdate(Progress…)

onProgressUpdate(Progress…) 根据publishProgress传递的参数获取当前耗时操作的进度.

onPostExecute(Result)

当耗时操作完成的时候,该方法会被调用,

当你执行到这个方法的时候,此时已经处于UI线程了,此时可以放心的进行UI操作,其中Result作为返回结果,完全可以作为UI界面的更新.

简单代码示例:

我们通过一个小程序来测试AsyncTask的处理机制:

利用异步操作处理加载图片,在图片加载完成之后返回给UI线程并执行更新.

新建类ImageLoad继承自Activity

创建内部类MyAsyncTask 继承自AsyncTask

package com.example.asynctask_test;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;

public class ImageLoad extends Activity {

private ImageView imageView ;
private ProgressBar progressbar;
private static String url =
"http://img.mp.itc.cn/upload/20160320/3f7f53242afc44cb9e858ddb5a2334c9_th.jpg";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image);
imageView = (ImageView) findViewById(R.id.image);
progressbar = (ProgressBar) findViewById(R.id.progressbar);
//开启异步线程操作
new MyAsyncTask().execute(url);
}

//内部类
class MyAsyncTask extends AsyncTask<String, Void, Bitmap>{

@Override
protected void onPreExecute() {
super.onPreExecute();
//线程开始之前,显示进度条(一直转圈)
progressbar.setVisibility(View.VISIBLE);
}

@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
//doInBackground完成之后执行根据返回的图片(result)更新UI
//主线程
progressbar.setVisibility(View.GONE);
imageView.setImageBitmap(result);

}

@Override
protected Bitmap doInBackground(String... params ) {
//取出参数作为URL
String url = params[0];
Bitmap bitmap = null;
URLConnection connection;
InputStream is; //由connection获取InputStream
try {
connection = new URL(url).openConnection();
is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
//通过decodeStream解析输入流
bitmap = BitmapFactory.decodeStream(bis);
is.close();
bis.close();
//为了显示进度条,睡眠3秒
Thread.sleep(3000);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
//返回解析的Bitmap
return bitmap;
}
}

}


ImageLoad布局文件 image.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/image"/>

<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
/>

</RelativeLayout>


一开始我们把进度条设置为GONE(区别于invisible,GONE隐藏并且释放空间),当进入加载活动(doInbackground()执行之前)在onPreExecute()中进度条设置显示
progressbar.setVisibility(View.VISIBLE);


在耗时操作完成后(图片加载完毕),在onPreExecute()执行
progressbar.setVisibility(View.GONE);
表示图片加载完成

运行结果:



代码来源:

iMooc网教程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: