您的位置:首页 > 理论基础 > 计算机网络

android开发异步加载网络数据AsyncTask的使用

2015-12-04 15:26 621 查看
一、异步任务加载网络数据:

在android中提供了一个异步任务的类AsyncTask,简单来说,这个类中的任务是运行在后台线程中的,并可以将结果放到UI线程中进行处理,它定义了三种
泛型,分别是Params、Progress和Result,分别表示请求的参数、任务的进度和获得的结果数据。

1、使用原因:

1)其中使用了线程池技术,而且其中的方法很容易实现调用。

2)可以调用相关的方法,在开启子线程前和后,进行界面的更新。

3)一旦任务多了,不用每次都new新的线程,可以直接使用。

2、执行的顺序:

onPreExecute()【执行前开启】---》doInBackground(Object...
params)---》onProgressUpdate(Object... values)---》onPostExecut
e(Object result)

3、执行过程:

当一个异步任务开启后,执行过程如下:

1)onPreExecute();

这个方法是执行在主线程中的。这不操作是用于准备好任务的,作为任务加载的准备工作。建议在这个方法中弹出一个对话框。

2)doInBackground(Object...
params);

这个方法是执行在子线程中的。在onPreExecute();方法执行完后会立即执行这个方法在方法中可以执行耗时的操作。需要将请求的
参数传递进来,发送给服务器,并将或取到的数据返回,数据会传给最后一步中;这些值都将被放到主线程中,也可以不断地传递给下一步的
onProgressUpdate();中进行更新。可以通过不断地调用publishProgress();将数据(或进度)不断传递给onProgressUpdate();方法,进行不
断更新界面。

3)onProgressUpdate(Object...
values);

这个方法是执行在主线程中的。publishProgress();在doInBackground(Object...
params);中被调用后,才开始执行的这个方法, 他在何时被开启的是不确定的,在执行这个方法的过程中,doInBackground(Object... params);方法是仍在执行的即子线程还在执行着。

4)onPostExecute(Object
result);

这个方法是执行在主线程中的。当后台的子线程执行完毕后才调用的这个方法。doInBackground(Object...
params);返回的结果会 作为参数被传递过来。可以在这个方法中进行数据处理界面更新的操作。

5)execute();

最后创建 AsyncTask的自定义类,开启异步任务。asyncTask.execute(params);

4、实现原理:

1)线程池的创建:

在创建了AsyncTask的时候,会默认创建一个线程池ThreadPoolExecutor,并默认创建出5个线程放入到线程池中,最多可放128个线程;且这个线程池是公共的
唯一一份儿

2)任务的执行:

在execute();中,会执行run方法,当执行完run方法后,会调用scheduleNext();不断的从双端队列中轮询,获取下一个任务并据需放到一个子线程中执行,知道异
步任务执行完成。

3)消息的处理:

在执行完onPreExecute()方法之后执行了doInBackground(Object...
params);方法,然后就不断的发送请求获取数据;在这个AsyncTask中 维护了一个InternalHandler的类,这个类是继承Handler的,获取的数据是通过Handler进行处理和发送的。在q其handlerMessage();方法中, 将消息传给onProgressUpdate(Object...
values);进行进度的更新,也就可以将结果发送到主线程中进行界面的更新了。

5、需要注意的是:
1)这个AsyncTask类必须有子类进行调用
2)虽然是放在子线程中执行的操作,但是不建议做特别耗时的操作,如果操作过于耗时建议使用线程池ThreadPoolExecutor和FutureTask

贴出代码:

NetOperator.java

package vic.wong.main;

//模拟网络环境

public class NetOperator {

public void operator(){

try {

//休眠1秒

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

ProgressBarAsyncTask .java

package vic.wong.main;

import android.os.AsyncTask;

import android.widget.ProgressBar;

import android.widget.TextView;

/**

* 生成该类的对象,并调用execute方法之后

* 首先执行的是onProExecute方法

* 其次执行doInBackgroup方法

*

*/

public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String> {

private TextView textView;

private ProgressBar progressBar;

public ProgressBarAsyncTask(TextView textView, ProgressBar progressBar) {

super();

this.textView = textView;

this.progressBar = progressBar;

}

/**

* 这里的Integer参数对应AsyncTask中的第一个参数

* 这里的String返回值对应AsyncTask的第三个参数

* 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改

* 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作

*/

@Override

protected String doInBackground(Integer... params) {

NetOperator netOperator = new NetOperator();

int i = 0;

for (i = 10; i <= 100; i+=10) {

netOperator.operator();

publishProgress(i);

}

return i + params[0].intValue() + "";

}

/**

* 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)

* 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置

*/

@Override

protected void onPostExecute(String result) {

textView.setText("异步操作执行结束" + result);

}

//该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置

@Override

protected void onPreExecute() {

textView.setText("开始执行异步线程");

}

/**

* 这里的Intege参数对应AsyncTask中的第二个参数

* 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行

* onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作

*/

@Override

protected void onProgressUpdate(Integer... values) {

int vlaue = values[0];

progressBar.setProgress(vlaue);

}

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