异步任务处理---AsyncTask
2016-03-29 22:19
239 查看
今天学习了AsyncTask的基本用法,现在进行一个总结:
首先要知道为什么异步任务:
1、Android单线程模型
2、 耗时的操作要放在非主线程中进行,避免主线程堵塞
其次要知道AsyncTask的作用:
1、在子线程中更新UI
2、封装、简化异步操作
接下来看下AsyncTask的基本用法:
由于AsyncTask是一个抽象类,所以如果我们想使用它,就必须创建一个子类去继承它,在继承时我们必须为AsyncTask类指定三个泛型参数,如果传入Void,则表示不传入参数
1、Params:在执行时传入要传入的参数,可用于在后台任务中使用
2、Progress:后台任务执行时,如果需要在界面上显示当前的进度,则使用指定的泛型作为进度单位
3、Result:当任务执行执行完毕后,如果需要对结果进行返回,使用这里指定的泛型作为返回值类型
然后我们需要构建AsyncTask子类的回调方法:
onPrexecute()执行后台操作前调用,一般执行初始化操作,在doInBackground方法前执行
doInBackground(Params…)必须重写,在这里执行异步任务;耗时操作写在这里,可调用publishProgress(Progress…)方法返回当前的执行进度
onProgressUpdate(Progress…)当在doInBackground调用doInBackground()后很快被调用对UI操作,这个可以不写(没有在doInBackground中调用)
onPostExecute(Result):当doInBackground方法结束执行,系统自动调用该方法,接收的值就是doInBackground最后返回的值;
说下使用AsyncTask的注意事项
1、必须在UI线程中创建AsyncTask实例
2、必须在UI线程中调用AsyncTask的execute()方法
3、重写的四个方法是系统自动调用的,不要手动去调用
4、每个AsyncTask只能被执行一次,多次调用将会引发异常
下面开始实例:使用AsyncTask加载图片
首选我们创建布局:image.xml用于显示图片IMageView和加载进度ProgressBar
新建活动ImageTest
写完活动之后立马注册活动,养成好习惯;
最后在主活动里面点击Button实现加载图片,剩下的点击Button就省略了,很简单。
看下运行效果:
1、MainActivity主界面
2、加载过程中ProgressBar显示界面
3、加载成功图片显示界面
最后说下AsyncTask的取消:
AsyncTaskc是通过线程池执行的,如果前面的线程没有执行完,再去点击开启一个新的线程的时候就会出现空白,即新线程并没有执行,而是等待上一个线程执行完之后才开始执行的;那么怎么解决这个问题呢?
需要通过让AsyncTask的声明周期和activity的声明周期保持一致,在activity的onpause方法中加入如下代码:
仅仅写这些事不够的,因为.cancel方法只是对该线程进行标示,并没有取消该线程,还要加上下面的代码
具体的参考代码,下载地址:AsyncTask小例子
首先要知道为什么异步任务:
1、Android单线程模型
2、 耗时的操作要放在非主线程中进行,避免主线程堵塞
其次要知道AsyncTask的作用:
1、在子线程中更新UI
2、封装、简化异步操作
接下来看下AsyncTask的基本用法:
由于AsyncTask是一个抽象类,所以如果我们想使用它,就必须创建一个子类去继承它,在继承时我们必须为AsyncTask类指定三个泛型参数,如果传入Void,则表示不传入参数
1、Params:在执行时传入要传入的参数,可用于在后台任务中使用
2、Progress:后台任务执行时,如果需要在界面上显示当前的进度,则使用指定的泛型作为进度单位
3、Result:当任务执行执行完毕后,如果需要对结果进行返回,使用这里指定的泛型作为返回值类型
然后我们需要构建AsyncTask子类的回调方法:
onPrexecute()执行后台操作前调用,一般执行初始化操作,在doInBackground方法前执行
doInBackground(Params…)必须重写,在这里执行异步任务;耗时操作写在这里,可调用publishProgress(Progress…)方法返回当前的执行进度
onProgressUpdate(Progress…)当在doInBackground调用doInBackground()后很快被调用对UI操作,这个可以不写(没有在doInBackground中调用)
onPostExecute(Result):当doInBackground方法结束执行,系统自动调用该方法,接收的值就是doInBackground最后返回的值;
说下使用AsyncTask的注意事项
1、必须在UI线程中创建AsyncTask实例
2、必须在UI线程中调用AsyncTask的execute()方法
3、重写的四个方法是系统自动调用的,不要手动去调用
4、每个AsyncTask只能被执行一次,多次调用将会引发异常
下面开始实例:使用AsyncTask加载图片
首选我们创建布局:image.xml用于显示图片IMageView和加载进度ProgressBar
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:padding="16dp" android:layout_height="match_parent"> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" /> <ProgressBar android:id="@+id/progrssBar" android:visibility="gone" android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
新建活动ImageTest
package com.asynctask.css.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.net.URL;//手动导入 import java.io.InputStream; import java.net.URLConnection; /** * Created by css on 2016/3/28. */ public class ImageTest extends Activity { private ImageView mImageView; private ProgressBar mProgressBar; MyAsynvTask mtask; //定义静态的String类型的URL用于存储要加载图片的地址 private static String URL = "http://pic.mmfile.net/2013/08/1315595G7-2.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.image); mImageView = (ImageView) findViewById(R.id.image); mProgressBar = (ProgressBar) findViewById(R.id.progrssBar); //当调用execute之后,进行异步操作 mtask = new MyAsynvTask(); mtask.execute(URL); } // 新建内部类MyAsynvTask继承AsyncTask,设置传递进去的参数, // 1、第一个参数表示加载图片的地址,所以传入String, // 2、第二个参数表示不需要显示返回进度,使用Void, // 3、第三个参数表示最后返回Bitmap class MyAsynvTask extends AsyncTask<String,Void,Bitmap> { // 1、系统调用该方法,对异步操作进行初始化操作,这里显示ProgressBar @Override protected void onPreExecute() { super.onPreExecute(); mProgressBar.setVisibility(View.VISIBLE); } // 2、开始真正的异步操作处理,都在子线程中处理,放置任意的耗时操作,最后返回指定的类型 @Override protected Bitmap doInBackground(String... params) { String url = params[0];//可以传递不止一个参数进来,以数组的形式存在,取出对应的URL Bitmap bitmap = null; URLConnection connection ; //定义网络连接对象 InputStream is; //用于获取数据的输入流 //访问网络的费时操作 try { connection = new URL(url).openConnection(); //此处需要手动导入URL包,获取网络连接对象 is = connection.getInputStream(); //获取输入流 BufferedInputStream bis = new BufferedInputStream(is); //加入睡眠时间,晚点执行 // try { // Thread.sleep(3000); // } catch (InterruptedException e) { // e.printStackTrace(); // } //使用BitmapFactory的decodeStream方法可以很方便的把bis输入流转换为Bitmap bitmap = BitmapFactory.decodeStream(bis); is.close();//关闭输入流 bis.close(); } catch (IOException e) { e.printStackTrace(); } //将bitmap作为返回值传递到onPostExecute中,在onPostExecute进行UI更新 return bitmap; } // 3、运行在主线程,任意进行UI操作onPostExecute在本方法中操作UI,把图像设置到ImageView @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); mProgressBar.setVisibility(View.GONE); //隐藏ProgressBar mImageView.setImageBitmap(bitmap); //显示图片 } } }
写完活动之后立马注册活动,养成好习惯;
<activity android:name=".ImageTest"></activity>
最后在主活动里面点击Button实现加载图片,剩下的点击Button就省略了,很简单。
看下运行效果:
1、MainActivity主界面
2、加载过程中ProgressBar显示界面
3、加载成功图片显示界面
最后说下AsyncTask的取消:
AsyncTaskc是通过线程池执行的,如果前面的线程没有执行完,再去点击开启一个新的线程的时候就会出现空白,即新线程并没有执行,而是等待上一个线程执行完之后才开始执行的;那么怎么解决这个问题呢?
需要通过让AsyncTask的声明周期和activity的声明周期保持一致,在activity的onpause方法中加入如下代码:
@Override protected void onPause() { super.onPause(); if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) { //cancel方法只是将AsyncTask标记为cancel状态,并不是真正的取消线程的执行 mTask.cancel(true); } }
仅仅写这些事不够的,因为.cancel方法只是对该线程进行标示,并没有取消该线程,还要加上下面的代码
if(isCancelled()) { break; }
具体的参考代码,下载地址:AsyncTask小例子
相关文章推荐
- NYOJ 题目239 月老的难题 (二分图最大匹配-匈牙利算法模板)
- 在art.dialog中加载ztree
- Go语言学习四:函数和类
- 初学者svn项目发布和下载
- 对于电梯调度的想法
- iOS GDataXMLNode的配置步骤
- 2016腾讯校园招聘模拟考试(2016.03.25)
- 2016SDAU课程练习一1008 Problem I
- 用优雅的方式解决重复点击的困扰
- Android UI模板设计---TopBar(标题栏)
- CentOS系统资源监控软件四大软件htop,top,ps,dstat
- 项目经理打分
- 排序算法之快速选择排序
- 2016腾讯校园招聘模拟考试(2016.03.25)
- java学习笔记-IO流
- HDU 4283 You Are the One(区间DP)
- 【bzoj4196】[Noi2015]软件包管理器
- 《Linux内核分析》第六周学习笔记
- 作业4
- 软件工程_4th weeks