关于AsyncTask应该掌握的一切

AsyncTask是android为了方便处理子线程和UI线程的交互而封装的一个类,它内部的实现是Thread+Handler。

AsyncTask泛型类型:
AsyncTask是一个抽象类,当我们要使用AsyncTask时,需要创建一个类继承自AsyncTask类,并且至少重写其中的一个方法——doInBackground(),在继承时为AsyncTask类指定三个泛型参数:
1. Params: 这个泛型指定在执行AsyncTask时需要传入的参数,可用于在后台任务中使用;比如HTTP请求的URL
2. Progress: 异步任务执行时将执行的进度返回给UI线程的参数类型,作为执行进度单位,如Integer类型
3. Result: 异步任务执行完成后返回给UI线程的结果的类型

需要重写的几个方法
1. onPreExecute()
该方法是在执行异步任务之前的时候执行,并且是在UI线程当中执行的,通常我们在这个方法里做一些UI控件的初始化的操作,比如显示一个进度条对话框或一些控件的实例化等。
2. doInBacnground()
该方法是一个抽象方法,必须实现。它在onPreExecute()方法执行完后,立即调用,并且是在工作线程中执行,当任务执行完成后,通过return将结果返回,如果AsyncTask第三个参数是void类型,可以不返回执行任务结果。在该方法中不能执行更新UI的操作,如果要执行更新UI操作,则可以调用publishProgress()方法完成,这是一个final类型的方法,不能重新,只能调用,用来通知更新UI,当调用该方法时, onProgressUpdate(Progress…)方法将会被调用。
3. onProgressUpdate()
UI线程中执行,当doInBackground()方中调用publishProgress(Progress…)后调用。在异步任务执行的时候,有时需要将执行的进度返回给我们的UI界面,例如下载一张网络图片,我们需要时刻显示其下载的进度,就可以使用这个方法来更新我们的进度。
4. onPostExecute(Result)
当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如说提醒任务执行的结果,以及关闭掉进度条对话框等。

取消任务
通过调用cancel(boolean)方法可以取消正在执行的任务,当调用该方法时,onCancelled(Object)方法将在doInBackground(Object[])方法返回时得到调用,为了确保任务可以尽快的取消,我们应当在doInBackground()方法中检查isCancelled()的返回值是否为true。
需要注意的是,cancel(boolean)方法有一个boolean参数,参数名为mayInterruptIfRunning,意思是正在执行的是否可以打断,如果为true,表示这个任务将会被打断,否则的话,正在执行的任务将会继续执行,直到完成。
NOTE:但是有时候调用了cancel(true)会发现依然无法取消任务。因为如果doInBackground()有不可打断的方法,则会失效。比如这个BitmapFactory.decodeStream() IO操作。但是你可以提前关闭IO流并捕获这样操作抛出的异常。但是这样会使得cancel()方法没有任何意义。

AsyncTask必须要遵循的原则
1. AsyncTask实例必须在UI线程实例化
2. execute(Params…)方法必须在UI线程调用
3. 不要手动调用onPreExecute(),onPostExecute(Result),doInBackground(Params…),onProgressUpdate(Progress…)方法。
4. AsyncTask任务只能被执行一次,即只能调用一次execute方法,多次调用时将会出现异常
5. AsyncTask不是被设计为解决非常耗时操作的,耗时上限为几秒钟,如果要做长耗时操作,强烈建议使用Executor,ThreadPoolExecutor以及FutureTask。
NOTE:AsyncTask不能完全取代线程,在一些逻辑较为复杂或者需要在后台反复执行的逻辑就可能需要线程来实现了。

任务执行顺序
当第一次推出AsyncTask时,它是在一个后台线程中串行执行的。从Android 1.6开始,改为了线程池,允许多个任务并发的执行。从3.0开始,AsyncTask又被设计为单任务执行,主要是为了避免并发带来的应用错误。但是这个版本并没有完全禁止多任务执行,如果需要并发执行任务,可以通过executeOnExecutor()来实现。

AsyncTask源码分析
可以参考下面博客:
http://stackvoid.com/understanding-AsyncTask-in-Android/
http://blog.csdn.net/guolin_blog/article/details/11711405

AsyncTask导致的内存泄露
如果在Android中使用非静态内部AsyncTask类,由于内部类会持有外部类的一个引用,因此当Activity销毁时,由于AsyncTask正在执行任务,并没有销毁,那么此时AsyncTask持有Activity引用,导致Activity无法被回收,产生内存泄露。

猜你喜欢

转载自blog.csdn.net/hsk256/article/details/49847391
今日推荐