面试题记录第五节——Asynctask

来源:互联网 发布:彩云数据 编辑:程序博客网 时间:2024/06/06 03:23

一、问:Asynctask是什么?

答:它是Android提供的一个抽象类,他本质上就是一个封装了线程池和handler的异步框架,主要是来执行异步任务的,由于它内部继承了handler,所以他可以在工作线程和UI线程中随意切换。

注意:Asynctask能够让你避免使用线程类thread和handler直接处理后台操作,他可以把运算好的结果交给UI 线程来显示,不过Asynctask只能做一些耗时较短的操作,如果我们要做耗时较长的操作,我们还是尽量使用线程池。

推荐博客:http://blog.csdn.net/liuhe688/article/details/6532519


二、问:Asynctask又是如何使用的呢?

答:他有三个重要的参数,五个重要的方法

  • 1、三个参数
    三种泛型类型分别代表:
public abstract class AsyncTask<Params, Progress, Result> { }第一个:“启动任务执行的输入参数”。第二个:“后台任务执行的进度”。第三个:“后台计算结果的类型”。
  • 2、五个方法

第一种:execute(params…params):执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行(必须在UI线程中调用)

第二种:nPreExecute(),在execute(Params… params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记(也可以理解为初始化数据)。

第三种:doInBackground(Params… params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress… values)来更新进度信息。

第四种:onProgressUpdate(Progress… values),在调用publishProgress(Progress… values)时,此方法被执行,直接将进度信息更新到UI组件上。

第五种:onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。


三、问:Asynctask的内部原理?

答:三个方面来说

1、Asynctask的本质是一个静态的线程池,Asynctask派生出的子类可以显现不同的异步任务,这些任务都是提交到静态的线程池中执行。

2、线程池中的工作线程执行doinbackground(mparams)方法来执行异步操作。

3、当任务状态改变后,工作线程会向UI线程发送消息,Asynctask内部的internalHandler相应这些消息,并调用相关的回调。


四、问:Asynctask的注意事项?

答:

一、内存泄露。和handler造成的问题一样。非静态内部类持有外部类的匿名引用,导致外部activity像被内存回收,由于非静态内部类还持有外部类的引用,导致外部类不能被系统回收,造成内存泄露。

解决方法:
1、谁为静态内部类。
2、非静态内部类使用弱引用。
3、在destroy方法中finish。

二、生命周期

如果在外部类被销毁的时候,没有执行onCancelled方法,这有可能让我们的activity在销毁之前导致崩溃。因为Asynctask正在处理某些view。但是activity不存在了,所以就会崩溃。

三、结果丢失
假如说,activity被系统回收或者横竖屏切换,导致activity被重新创建,而之前运行的Asynctask会持有之前activity的引用,但是这个引用已经无效,所以这个时候,你调用onpostExecute()方法去更新界面就会失败,因为结果已经丢失。


五、问:为什么AsyncTask只能执行一次?

答:应该说同一时间段内,只执行一次,防止对同一件事进行操作,造成的混乱。我们知道异步的线程执行的顺序很大程度上是不确定的,有可能先执行的最后执行完成,后执行的反而先完成。如果在同一时间段内,执行多个线程这里就会出现混乱。


六、问:什么是并行,什么是串行,两者的区别是什么?

答:在android1.6版本之前,Asynctask都是串行,也就是他会把所有任务,一串一串的放在线程池中。但是在1.6到2.3的版本中,它改成了并行。为了维护系统的稳定,2.3版本后又改回了串行,但是还是可以执行并行的,建议使用串行。