您的位置:首页 > 职场人生

Android-异步任务介绍及面试题

2015-07-07 18:24 676 查看
Android-异步任务

一 什么是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是多线程吗?

不是,见前面的定义
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: