Android必学——AsyncTask

第一章  AsyncTask的基本构成java

为是么要异步任务android

1)Android单线程模型网络

2)耗时操做放在非主线程中执行异步

 

AsyncTask为什么而生async

1)子线程中跟新UIide

2)封装、简化异步操做post

 

 

public class MyAsyncTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {//必须重写,其余方法没有规定必须重写
        // TODO 自动生成的方法存根
        Log.d("TAG", "doInBackground");
        publishProgress();//输入的参数会在onProgressUpdate()方法中获取到
        return null;
    }

    @Override
    protected void onPreExecute() {
        // TODO 自动生成的方法存根
        super.onPreExecute();
        Log.d("TAG", "onPreExecute");
    }

    @Override
    protected void onPostExecute(Void result) {
        // TODO 自动生成的方法存根
        super.onPostExecute(result);
        Log.d("TAG", "onPostExecute");
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        Log.d("TAG", "onProgressUpdate");
}
}
//另类
MyAsyncTask task=new MyAsyncTask();
task.execute();//相似线程中的start()方法

Ps:顺序:onPreExecute()->doInBackground(Params...)->调用publishProgress(Progress...)->onProgressUpdate(Progress...)->doInBackground(Params...)执行结束->onPostExecute(Result)

 

第二章  AsyncTask的使用示例url

网络操做做为不稳定的废时操做,从android 4.0开始就被严禁放入主线程中
一般采用在异步线程处理下载图像
在UI线程设置图像

ProgressBar XML属性 visibility="gone"可设置为默认状态下为隐藏
VISIBLE:设置控件可见
INVISIBLE:设置控件不可见
GONE:设置控件隐藏

而INVISIBLE和GONE的主要区别是:当控件visibility属性为INVISIBLE时,界面保留了view控件所占有的空间;而控件属性为GONE时,界面则不保留view控件所占有的空间。
URLConnection connection //定义网络对象<br>
ImputString is//定义用于获取数据的输入流<br>
connection=new URL(url).openConnection();//获取网络链接对象<br>
is= connection.getInputStream();//得到输入流<br>
BufferedInputStream bis=new BufferedInputStream(is);//封装输入流<br>
bitmap=BitmapFactory.decodeStram(bis);将输入流解析成bitmap<br>
is.close();<br>
bis.close();//关闭输入流<br>
1.获取传递进来的参数值<br>
string url=params[0];<br>
2.访问网的操做<br>
创建链接--设置输入流--封装输入流--decode输出流,转化为所须要的文件--关闭输入流和封装流
最后将所须要的文件返回

上述方法是写在doInBackground()里面的。spa

 

经过OnProExcute方法和onPostExcute方法操做UI设置图像
mProgressBar.setVisbility(View.VISIBLE)显示进度条
onPostExcute(BitMap bitmap)//bitmap为doingbackground方法返回的一个bitmap
在Main方法中,调用MyAsycTask的execute方法传入(URL)
经过AsyncTask的实例调用execute方法就能够开启AsyncTask的异步操做,在execute方法中传入一个或多个参数做为咱们doingbackground方法中所传进来的一个参数
在AsyncTask的OnPreExecute方法中调用初始化的方法,在后台启动异步操做提示用户等待,调用真正的doingBackGround方法开始真正的异步处理,这里的整个方法都是如今子线程之中,在这个方法中进行全部的耗时操做,并将所要返回的值返回到咱们所设定的值的类型中,在OnpostExecute方法中得到咱们所返回的结果,onPostExcute方法也运行在主线程之中从而咱们能够对UI进行操做,这就是AsyncTask所要调用的整个流程

在Mainfest中开通所要访问的网络权限

 

onPreExecute() 显示进度条
onPostExcute()隐藏进度条 均可以访问UI线程
mytask.execute(args)中传入的参数就是doInBackground中的参数
onPreExecute--加载进度条
doInBackGround--下载网络数据(耗时操做)
onPostExecute--显示图片

与UI线程通讯
在onPreExecute()方法中
mProgressBar.setVisibility(View.VISIBLE);//显示进度条

在onPostExectute(Bitmap bitmap)方法中,参数是doInBackground()方法返回的参数
mProgressBar.setVisibility(View.GONE);//将进度条隐藏
mImageView.setImageBitmap(bitmap);//将图片设置为解析出来的网络图片

而后在onCreate方法中
new MyAsyncTask().execute(URL);//开启AsyncTask的异步线程操做,设置传递进去的参数

 

第三章  AsyncTask模拟进度条线程

在AsyncTask的doInBackground()方法中调用publishProgress()方法能够将咱们处理任务的进度反馈处理,
咱们这个时候就是用AsyncTask的onProgressUpdate()方法来承接咱们传出来的进度,注意,因为在AsyncTask中,
只有doInBackground()方法是工做在子线程中的,因此咱们能够放心地在onProgressUpdate()方法中更新UI

for(int i=0;i<100;i++){
publishProgress(i);
try{
Thread.sleep(300);
} catch(InterruptedException e){
e.printStackTrace();
}
}

onProgressUpdate(Integer...values){
super.onProgressUpdate(values);
//获取进度更新值
mProgressBar.setProgress(values[0]);
}
AsyncTask默认状况下会等待前一个线程执行完毕后再执行下一个线程,要取消该机制,可让AsyncTask和Activity的生命周期保持一致
protected void onPause(){
super.onPause();
if(mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING){
//只是发送了一个取消请求,将AsyncTask标记为cancel状态,但未真正取消线程的执行
//实际上JAVA语言没办法粗暴地直接中止一个正在运行的线程
mTask.cancel(true);
}
}

因此须要在doInBackground方法和onProgressUpdate方法中增长isCancelled()方法进行判断,标记为cancel的,则跳出循环,尽快结束当前线程的剩余操做,开始下一个线程

AsyncTask实现的机制:底层经过线程池来做用的,当咱们一个线程没有执行完毕时,后面的线程是没法执行的;
调用cancel方法去cancel一个asynctask线程,并无将这个线程直接中止掉,只是给这个asynctask发送了一个cancel请求,将它标识为cancel状态;
在java中是没法直接将一个线程粗暴地中止掉,咱们必须等一个线程执行完毕后才能作后面的操做。(需经过状态值判断去跳出子线程的循环操做)

只有doInBackground是在非UI线程中执行
mytask!=null&&mytask.getStatus()== AsyncTask.Status.RUNNING
ansystask 即便cancel设置为true 也不能当即取消,只是将状态设为取消
故在doInBackground和onUpdatexx的时候检测isCancled()是否是true

 

doInBackground()方法运行在非主线程,其余三个方法运行在主线程,因此能够在doInBackground作异步操做,在其余三个方法中更新UI。
正是由于有了onProgressUpdate()和onPostExcute()方法,才能够在异步处理的过程当中更新UI。
相关文章
相关标签/搜索