本文为慕课网Android教学视频自学整理,原视频连接:http://www.imooc.com/learn/377
AsyncTask作用:
将耗时操作放在非主线操作中进行(保证了Android的单线程模型且避免了ANR(应用程序无响应)),在子线程中更新UI,封装、简化了异步操作。
构建AsyncTask子类的参数:
AsyncTask<Params,Progress,Result>是一个抽象类,通常作为父类被继承,继承AsyncTask需要指定以下三个泛型参数:
- Params:启动任务时输入的参数类型。
- Progress:后台任务执行中返回进度值得了类型。
- Result:后台执行任务完成后返回结果的类型。
构建AsyncTask子类回调方法:
- doinBackground:异步执行后台线程将要完成的任务。(为必须重写的方法,所有耗时操作都将在此进行)。
- onPreExecute:执行后台耗时操作前被调用,通常用于用户完成一些初始化操作。
- onPostExecute:当doinBackgroug()完成后,系统会自动调用该方法,并将doinBackgroud方法返回的值传给该方法(即展示doinBackground的处理结果)。
- onProgressUpdate:在doinBackground()方法中调用publishiProgress()方法更新任务的执行进度后就会触发该方法。(可以清楚了解当前耗时操作的完成进度)
调用顺序:onPreExecute-->doinBackground--(publishiProgress-->onProgressUpdate)-->onPostExecute
代码步骤:(加载网络图片、实现进度条、取消AsyncTask)
在显示一张网络图片的时候需要在异步处理中下载图像并在UI线程中设置图像。
MainActivity
public class MainActivity extends Activity {
public Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyAsyncTask task = new MyAsyncTask();
task.execute();
button = (Button) findViewById(R.id.button);
}
public void loadImage(View view){
startActivity(new Intent(this,ImageTask.class));
}
public void loadProgress(View view){
startActivity(new Intent(this,ProgressBarTest.class));
}
}
MyAsyncTask
package com.example.administrator.asynctask;
import android.os.AsyncTask;
/**
* Created by Administrator on 2016/8/16.
*/
public class MyAsyncTask extends AsyncTask<Void,Void,Void> {
@Override
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
ImageTask(加载网络图片)
ublic class ImageTask extends Activity {
private ImageView imageView;
private ProgressBar progressBar;
private static String URL ="http://pic37.nipic.com/20140103/14882888_145146566000_2.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);//完成AsyncTask的调用
}
class MyAsyncTask extends AsyncTask<String,Void,Bitmap>{//<url类型,进度值类型,返回值类型>
@Override
protected Bitmap doInBackground(String... params/*可变长数组*/) {
//获取传递进来的参数
String url = params[0]/*取出对应URL*/;
Bitmap bitmap = null;
URLConnection connection;//定义网络连接对象
InputStream inputStream;//用于获取数据的输入流
try {
connection = new URL(url).openConnection();//此时手动导包URL,将url传递到URL方法并调用openConnection()以获取网络连接对象
inputStream = connection.getInputStream();//获取输入流
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
bitmap = BitmapFactory.decodeStream(bufferedInputStream);//decodeStream将输入流解析成bitmap
//以上方法将url对应的图像解析成为bitma
inputStream.close();
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
//将bitmap作为返回值
return bitmap;
}
@Override
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);//显示进度条
super.onPreExecute();
}
@Override
protected void onPostExecute(Bitmap bitmap) {//操作UI,设置图像
super.onPostExecute(bitmap);
progressBar.setVisibility(View.GONE);
imageView.setImageBitmap(bitmap);
}
}
ProgressBarTask(实现进度条、取消AsyncTask)
package com.example.administrator.asynctask;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ProgressBar;
/**
* Created by Administrator on 2016/8/16.
*/
public class ProgressBarTest extends Activity {
private ProgressBar mprogressBar;
private MyAsyncTask mAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progressbar);
mprogressBar = (ProgressBar) findViewById(R.id.pb);
mAsyncTask = new MyAsyncTask();
mAsyncTask.execute();
}
@Override
protected void onPause() {
super.onPause();
if (mAsyncTask!=null&&mAsyncTask.getStatus()== AsyncTask.Status.RUNNING){
mAsyncTask.cancel(true);//cancel方法只是将对应的AsyncTask标记为cancel状态,并不是真正的取消线程的执行。
}
}
class MyAsyncTask extends AsyncTask<Void,Integer,Void>{
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i < 100 ;i ++){
if (isCancelled()){
break;
}
publishProgress(i);
try { //模拟进度更新
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (isCancelled()){
return;
}
//获取进度更新值
mprogressBar.setProgress(values[0]);
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.administrator.asynctask.MainActivity"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button"
android:text="ImageTask"
android:onClick="loadImage"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ProgressTask"
android:onClick="loadProgress"/>
</LinearLayout>
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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
android:id="@+id/progressbar"/>
</RelativeLayout>
progressbar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/ap
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/pb"
android:layout_centerInParent="true"
/>
</RelativeLayout>
AndroidManefest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.administrator.asynctask">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ImageTask"></activity>
<activity android:name=".ProgressBarTest"></activity>
</application>
</manifest>