Android-异步任务介绍及面试题
2015-07-07 18:24
676 查看
Android-异步任务
一 什么是AsyncTask
Android为了减低异步操作的开发难度,结合Handle和线程池,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,
顾名思义就是异步任务,他具有可以在后台执行耗时操作,同时可以将
执行的进度与UI进行同步的优点
因为Handle实际上就是两个线程之间的桥梁,但是数据的传递是单向的
Handle机制如下图:
![](http://img.blog.csdn.net/20150707181818618)
而AsyncTask机制如下:
![](http://img.blog.csdn.net/20150707181851173)
二 如何使用AsyncTask
AsyncTask定义三种泛型类型Params,Progress和Result:
Params:启动任务执行的输入参数,比如HTTP请求的URL
Progress:后台任务执行的百分比
Result:后台执行任务最终返回的结果,比如String
三 AsyncTask的主要方法:
必选方法:
doInBackground(Params…)
后台执行,比较耗时的操作都可以放在这里。
注意这里不能直接操作URL,此方法在后台线程执行,完成任务的主要工作
通常需要较长的时间。在执行的过程中可以调用publicProgress来更新进度条
onPostExecute(Result)
相当于handle处理UI的方式,在这里面可以使用doInBackground方法得到的结果处理操作UI
此方法在主线程执行,执行的结果作为此方法的参数返回值
可选方法:
onProgressUpdate(Progress…)
可以使用进度条增加用户体验,此方法在主线程执行,用于显示进度对话框
onPreExecute()
这是最终用户调用Execute时的接口,当任务执行之前开始调用的方法,可以在这里显示进度条的对话框
onCanceled()
用户调用取消时,要做的操作
AsyncTask的三个状态:Pending,runing,finish
四 AsyncTask的实现原理
1,AsyncTask为何必须在主线程中创建:
因为会用到sHandle
private static final InternalHandler sHandler = new InternalHandler();
该变量为静态变量,每次使用前都会建立,所以若不设定在主线程中创建,
则会产生很多的Task,系统返回的时候不确定返回哪一个
2,execute只能调用一次并且必须在主线程中执行
**3,自己不要调用**onPreExecute(),onPostExecute(),doInBackGround(),onProgressUpdate()这些方法
由系统自行调用
附上AsyncTask源代码:
http://pan.baidu.com/s/1hq6c95i
4,使用场合:
使用AsyncTask:任务可以被终止,并需要不断和使用
使用Handle:任务需要多次重复执行,并且和UI交互较少时
四 检测程序是否需要使用多线程或AsyncTask
常用到的类如下图:
![](http://img.blog.csdn.net/20150707182151535)
检测代码如下,结果是程序启动弹出对话框
面试题:
1,Handle和AsyncTask谁更加占用资源
AsyncTask多余Handle
AsyncTask:Handle 线程池(比Handle多创建一个线程池)
Handle:Handle
所以AsyncTask内存占用更多
2,AsyncTask是多线程吗?
不是,见前面的定义
一 什么是AsyncTask
Android为了减低异步操作的开发难度,结合Handle和线程池,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,
顾名思义就是异步任务,他具有可以在后台执行耗时操作,同时可以将
执行的进度与UI进行同步的优点
因为Handle实际上就是两个线程之间的桥梁,但是数据的传递是单向的
Handle机制如下图:
而AsyncTask机制如下:
二 如何使用AsyncTask
AsyncTask定义三种泛型类型Params,Progress和Result:
Params:启动任务执行的输入参数,比如HTTP请求的URL
Progress:后台任务执行的百分比
Result:后台执行任务最终返回的结果,比如String
三 AsyncTask的主要方法:
必选方法:
doInBackground(Params…)
后台执行,比较耗时的操作都可以放在这里。
注意这里不能直接操作URL,此方法在后台线程执行,完成任务的主要工作
通常需要较长的时间。在执行的过程中可以调用publicProgress来更新进度条
onPostExecute(Result)
相当于handle处理UI的方式,在这里面可以使用doInBackground方法得到的结果处理操作UI
此方法在主线程执行,执行的结果作为此方法的参数返回值
可选方法:
onProgressUpdate(Progress…)
可以使用进度条增加用户体验,此方法在主线程执行,用于显示进度对话框
onPreExecute()
这是最终用户调用Execute时的接口,当任务执行之前开始调用的方法,可以在这里显示进度条的对话框
onCanceled()
用户调用取消时,要做的操作
AsyncTask的三个状态:Pending,runing,finish
四 AsyncTask的实现原理
1,AsyncTask为何必须在主线程中创建:
因为会用到sHandle
private static final InternalHandler sHandler = new InternalHandler();
该变量为静态变量,每次使用前都会建立,所以若不设定在主线程中创建,
则会产生很多的Task,系统返回的时候不确定返回哪一个
2,execute只能调用一次并且必须在主线程中执行
**3,自己不要调用**onPreExecute(),onPostExecute(),doInBackGround(),onProgressUpdate()这些方法
由系统自行调用
附上AsyncTask源代码:
http://pan.baidu.com/s/1hq6c95i
4,使用场合:
使用AsyncTask:任务可以被终止,并需要不断和使用
使用Handle:任务需要多次重复执行,并且和UI交互较少时
四 检测程序是否需要使用多线程或AsyncTask
常用到的类如下图:
检测代码如下,结果是程序启动弹出对话框
package com.chengzhi.androidstrictmode; import java.io.OutputStream; import android.os.Build; import android.os.Bundle; import android.os.StrictMode; import android.os.StrictMode.ThreadPolicy.Builder; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; import android.view.Menu; @TargetApi(Build.VERSION_CODES.GINGERBREAD) @SuppressLint("NewApi") public class MainActivity extends Activity { //开发者模式 private static final boolean DEVELOPER_MODE = true; @TargetApi(Build.VERSION_CODES.GINGERBREAD) @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { //检测代码 if (DEVELOPER_MODE) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyDialog() .build()); //这个代码也可以 /*StrictMode.ThreadPolicy _policy = new StrictMode.ThreadPolicy.Builder() .detectAll().penaltyDeath().detectDiskReads().detectDiskWrites().detectNetwork().build(); StrictMode.setThreadPolicy(_policy); */ } super.onCreate(savedInstanceState); processIoAction(); } //在主线程中创建文件流会引发StrictMode的异常 private void processIoAction() { OutputStream out = null; try { out = openFileOutput("test", MODE_WORLD_WRITEABLE); out.write(0); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally { try { out.close(); } catch (Exception e2) { // TODO: handle exception } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
面试题:
1,Handle和AsyncTask谁更加占用资源
AsyncTask多余Handle
AsyncTask:Handle 线程池(比Handle多创建一个线程池)
Handle:Handle
所以AsyncTask内存占用更多
2,AsyncTask是多线程吗?
不是,见前面的定义
相关文章推荐
- 互联网笔试面试专题
- 九月十月百度人搜,阿里巴巴,腾讯华为小米搜狗笔试面试八十题
- 阿里面试题目总结
- (剑指Offer)面试题8:旋转数组的最小数字
- [.Net码农].net 枚举(Enum)使用总结
- 黑马程序员——java基础---IO流(第20天)
- 黑马程序员——正则表达式-整理笔记
- Android-多线程和异步概述及面试题
- Android-Handle详细介绍及面试题
- 黑马程序员——Java基础-整理笔记
- 面试题46:求1+2+...+n
- 关于淘汰85%查看面试官百度开发者面对的问题
- List,Set,Map(面试时的尴尬)
- 面试题44:扑克牌的顺子
- 黑马程序员安卓Android52期 46期 35期就业班视频
- 黑马程序员——Java基础——模板方法模式、多态
- 2015年java面试题
- 黑马程序员—Java继承
- 开始我的职业生涯
- sql常见面试题 (我觉得太好了)