我们都知道AsyncTask是为了异步而生
所以为什么要异步任务:
A: android是单线程模型
B: 耗时操作要放在非主线程中执行
首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。
因为我今天只看了异步的AsyncTask所以这篇就只涉及到AsyncTask:
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.
看一下构建AsyncTsak子类的参数
AsyncTsak <Params,progress,Result>
AsyncTsak 是一个抽象类
通常用于被继承 继承AsyncTsak需要指定如下三个泛型参数:
Params:启动任务时输入参数的类型。
progress: 后台任务执行中返回进度值得类型
Result: 后台执行任务完成后返回结果的类型
构建AsyncTsak之类的回调方法:
doInBackground():必须重写的,异步执行后台线程将要完成的任务 所有的耗时操作都在这里
onPreExecute():执行后台耗时操作之前被调用通常用户完成一些初始化操作
onPostExecute():当doInBackground()完成后 系统会自动调用onPostExecute()方法 并将doInBackground()方法返回的值传给这个方法
onProgressUpdate():在doInBackground()方法中调用publishProgress()方法更新任务的执行进度后,就会触发这个方法
所以我创建了一段代码我们来看一下他的执行顺序
public class MyAsyncTask extends AsyncTask {
@Override
protected void onProgressUpdate(Object[] values) {
Log.e("qwe","onProgressUpdate");
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Object o) {
Log.e("qwe","onPostExecute");
super.onPostExecute(o);
}
@Override
protected void onPreExecute() {
Log.e("qwe","onPreExecute");
super.onPreExecute();
}
@Override
//必须实现的方法
protected Object doInBackground(Object[] params) {
Log.e("qwe","doInBackground");
return null;
}
}
这段代码运行控制台的截图是这样的
清楚的看到 调用顺序是onPostExecute——doInBackground——onPostExecute和我们说的一样啦 就是先初始化然后doInBackground然后把结果传递到onPostExecute去更新UI
对 还有一个方法我们没有见到onProgressUpdate 因为我们并没有调用他啊 所以现在我们在
doInBackground中加入这个方法
@Override
//必须实现的方法
protected Object doInBackground(Object[] params) {
publishProgress();
Log.e("qwe","doInBackground");
return null;
}
运行结果就是这样啦
清楚的看到 调用顺序是onPostExecute——doInBackground——onProgressUpdate ——onPostExecute
大概就这么多 要看一个例子:
网络操作是很耗时的也很不稳定的 禁止在主线程中进行网络操作
、所以例子就是
异步操作—下载图像 在UI线程—设置图像
提前准备一张图片 我就用上面结果的截图吧
url在这里:https://img-blog.csdn.net/20160729204939361
package com.example.katherine_qj.asynctask;
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;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
/**
* Created by Katherine-qj on 2016/7/29.
*/
public class ImageTest extends Activity {
private ImageView imageView;
private ProgressBar progressBar;
private static String url = "https://img-blog.csdn.net/20160729204939361";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_asyncatask);
InitView();
//设置传递进去的参数
new MyAsycTaskImage().execute(url);
}
public void InitView() {
imageView = (ImageView)findViewById(R.id.image);
progressBar = (ProgressBar)findViewById(R.id.progressbar);
}
class MyAsycTaskImage extends AsyncTask<String,Void,Bitmap>{
@Override
protected Bitmap doInBackground(String... params) {
//传入的是一个可变数组
String url = params[0];//取出传递进来的对应的url;
Bitmap bitmap = null;
URLConnection connection ;
InputStream is ;
try {
connection = new URL(url).openConnection();
is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bitmap = BitmapFactory.decodeStream(bis);//通过decodeStream方法解析输入流
bis.close();//以上都是访问网络的耗时操作
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);//显示进度条
}
@Override
protected void onPostExecute(Bitmap bitmap) {//操作UI显示图像
super.onPostExecute(bitmap);
imageView.setImageBitmap(bitmap);
progressBar.setVisibility(View.GONE);
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
}
结果就是 进度条转一会然后图片就加载出来了
例子很简单 但是方法基本都用到了包括了
注意
1.要加联网权限:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
2.AsyncTask在主线程中创建和调用
3.重写四个方法 系统自己调用而不是手动调用
4 只能被调用一次
5.还有就是如果要结束这个AsyncTask
要先把当前这个AsyncTask标记为cancel状态 然后在每一个
逻辑中去判断这个状态如果是cancel就做相应的处理
发送cancel请求将这个AsyncTask标记为cancel状态,并
没有真正取消
over!
这就是今天下午学到的东西 大概总结下来就这些了
感觉学了这么久还是啥都不会
好焦急
所以明天也好好学习吧
嗯 要加油