Asynctask是Android中封装好了一个执行异步操作的抽象类。在执行一些耗时操作时可以借助该类来实现。相当于线程和Handler消息机制的一种封装。

一、Asybctask的基本用法。

Asybctask是一个抽象类,要使用它,可以定义一个子类继承它,在继承中会出现三个参数。

1、Params 该参数是执行AsyncTask时需要传入的参数类型,可以用于后台任务中使用,若不需要传入参数,那么就设置为Viod(注意V是大写的)。

2、Progress 该参数是后台任务执行时,若果需要在界面上显示当前的进度,则使用这里指定的泛型类型作为进度单位。

3、Resuit 任务执行完毕,需要返回的结果的类型。

若不需要三个泛型参数的任意一个,都应给用Void代替。

下面就来实现一个加载进度条的操作Demo:

异步任务实现加载进度条、

public class MyAsynctask extends AsyncTask<Void, Integer, String>{
@Override
/*最先执行的回调函数*/
protected void onPreExecute() {
super.onPreExecute();
Mylog.d("--------onPreExecute-------");
}

@Override
/*执行异步任务的回调方法 子线程中执行*/
protected String doInBackground(Void... params) { //Void... params 动态数组 子线程中执行
Mylog.d("--------doInBackground-------");
for(int i = 1;i <= 100; i++){
publishProgress(i);//异步操作中的参数传递方法。调用一次就会执行一次onProgressUpdate()回调函数
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String result = "下载完成";
return result;
}

@Override
/*执行异步任务中时要调用的回调函数 UI线程中执行
* 当 doInBackground方法中调用了publishProgress()方法时才会执行onProgressUpdate()方法*/
protected void onProgressUpdate(Integer... values) { //UI线程中执行,更新空间操作
super.onProgressUpdate(values);
Mylog.d("--------onProgressUpdate-------");
int progress = values[0]; //参数是动态数组,所以要先接收
mSeekBar.setProgress(progress);
mProgressTxt.setText(""+progress);
}

@Override
/*异步操作结束时调用的回调函数 UI线程中执行
* */
protected void onPostExecute(String result) { // 最后的结果
super.onPostExecute(result);
Mylog.d("--------onPostExecute-------");
mProgressTxt.setText(result);
}
}
这里面有几个方法,onPreExecute()是在执行了构造方法后调用的方法。接下来是doInBackground(),这个方法时在子线程中进行的,不能执行控件更新操作,这里面执行后台耗时操作。里面有一个动态数组的参数,也就是构造AsyncTask时需要传入的参数,类型为Void。

接下来是onProgressUpdate()方法,该方法是在异步任务执行中,若doInBackground()中调用了publishProgress()传递参数过来,那么传递一次,onProgressUpdate()就执行一次。这些的前提都要是在构造AsyncTask指定了Progress参数类型部位空的情况下。简单的说这个Progress类型就是异步任务执行中传递参数的类型,也就是在doInBackground()方法里通过publishProgress(参数)传递给onProgressUpdate()方法。由于onProgressUpdate()是在UI主线程中执行,所以可以在里面执行更新ui控件的操作。

最后是onPostExecute()这个方法,这个方法是异步任务执行完成后返回的数据。前提也要是在构造AsyncTask时设置了第三个参数Rusilt类型。这个方法就可以得到doInBackground()返回的结果。

构造好子类后就是怎么运用AsyncTask子类了。AsyncTask子类对象直接调用execute()方法。就可以开启该异步任务了。execute()里对应的参数就是构造AsyncTask子类时设定的参数类型。

<span style="white-space:pre"></span>MyAsynctask myAsynctask = new MyAsynctask();
myAsynctask.execute(); //开始加载


下面是用线程加Handler实现加载进度条的Demo:

/*handler更新控件*/
public void startByThread(){
new Thread(new Runnable() {
@Override
public void run() {
for(int i = 1;i <= 100;i++){
mSeekBar.setProgress(i);
Message msg = Message.obtain();
msg.obj = i;
msg.what = 1;
mHandler.sendMessage(msg); //发送一个消息就应该Message.obtain()一个消息。也就是这两个方法配套出现。
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Message msg = Message.obtain();
msg.what = 2;
msg.obj = "加载完成";
mHandler.sendMessage(msg);
}
}).start();
}

最后贴上运行效果。



这里还有异步操作实现了从网络中下载图片的Demo:

从网络获取图片的方法:访问网络资源需要在AndroidManifest文件中设置权限

<uses-permission android:name="android.permission.INTERNET"/>

/*连接网络取数据*/
public Bitmap getPicture(String URLpath){
try {
URL url = new URL(URLpath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream in = conn.getInputStream(); //将对应地址的图片读入流
Bitmap bitmap = BitmapFactory.decodeStream(in); //将流转化为Bitmap对象。
return bitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

按钮事件用的匿名内部类实现。

<span style="white-space:pre"></span>String urlPath = "http://img4.imgtn.bdimg.com/it/u=52754568,3369504778&fm=23&gp=0.jpg";
new AsyncTask<String, Void, Bitmap>(){
@Override
protected Bitmap doInBackground(String... params) {
return getPicture(params[0]); //下载图片
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
mImg.setImageBitmap(result);
}

}.execute(urlPath);

实现效果就是上面展示的效果。最后贴上所有Demo。

activity:

package asynctask;
/**
* 异步任务。线程和Handler的封装
*/
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import mylog.Mylog;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

import com.example.call.R;

public class AsynctaskActivity extends Activity implements OnClickListener{
private TextView mProgressTxt;
private SeekBar mSeekBar;
private Button mThreadStartBtn,mAsyncTaskStartBtn,mDownloadPrictureBtn;
private ImageView mImg;

private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch(msg.what){
case 1:
mProgressTxt.setText(""+msg.obj);
break;
case 2:
mProgressTxt.setText(""+msg.obj);
}
};};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.asynctask_main_layout);
initView();
}

public void initView(){
mProgressTxt = (TextView) findViewById(R.id.show_progress_txt);
mSeekBar = (SeekBar) findViewById(R.id.asynctask_seekbar);
mThreadStartBtn = (Button) findViewById(R.id.thread_start_btn);
mImg = (ImageView) findViewById(R.id.downloadpicture_img);
mThreadStartBtn.setOnClickListener(this);
mAsyncTaskStartBtn = (Button) findViewById(R.id.asybctask_start_btn);
mAsyncTaskStartBtn.setOnClickListener(this);
mDownloadPrictureBtn = (Button) findViewById(R.id.asybctask_downloadPicture_btn);
mDownloadPrictureBtn.setOnClickListener(this);


}

@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.thread_start_btn:
startByThread();
break;
case R.id.asybctask_start_btn:
MyAsynctask myAsynctask = new MyAsynctask();
myAsynctask.execute(); //开始加载
break;
case R.id.asybctask_downloadPicture_btn:
String urlPath = "http://img4.imgtn.bdimg.com/it/u=52754568,3369504778&fm=23&gp=0.jpg";
new AsyncTask<String, Void, Bitmap>(){
@Override
protected Bitmap doInBackground(String... params) {
return getPicture(params[0]); //下载图片
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
mImg.setImageBitmap(result);
}

}.execute(urlPath);
break;
}
}


/*连接网络取数据*/
public Bitmap getPicture(String URLpath){
try {
URL url = new URL(URLpath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream in = conn.getInputStream(); //将对应地址的图片读入流
Bitmap bitmap = BitmapFactory.decodeStream(in); //将流转化为Bitmap对象。
return bitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

/*handler更新控件*/
public void startByThread(){
new Thread(new Runnable() {
@Override
public void run() {
for(int i = 1;i <= 100;i++){
mSeekBar.setProgress(i);
Message msg = Message.obtain();
msg.obj = i;
msg.what = 1;
mHandler.sendMessage(msg); //发送一个消息就应该Message.obtain()一个消息。也就是这两个方法配套出现。
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Message msg = Message.obtain();
msg.what = 2;
msg.obj = "加载完成";
mHandler.sendMessage(msg);
}
}).start();
}

/*Asybctack启动加载方式
* AsyncTask<Void, Integer, String>
* 第一个参数 params为调用execute()传进来的参数类型 Void表示无参数
* 第二个参数Progress为在异步操作执行中传递的参数类型。在doInBackground()中调用publishProgress()就可以将参数传递给onProgressUpdate()方法,从而更新UI控件
* 第三个参数 result是异步操作执行完成返回的参数类型
* */
public class MyAsynctask extends AsyncTask<Void, Integer, String>{
@Override
/*最先执行的回调函数*/
protected void onPreExecute() {
super.onPreExecute();
Mylog.d("--------onPreExecute-------");
}

@Override
/*执行异步任务的回调方法 子线程中执行*/
protected String doInBackground(Void... params) { //Void... params 动态数组 子线程中执行
Mylog.d("--------doInBackground-------");
for(int i = 1;i <= 100; i++){
publishProgress(i);//异步操作中的参数传递方法。调用一次就会执行一次onProgressUpdate()回调函数
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String result = "下载完成";
return result;
}

@Override
/*执行异步任务中时要调用的回调函数 UI线程中执行
* 当 doInBackground方法中调用了publishProgress()方法时才会执行onProgressUpdate()方法*/
protected void onProgressUpdate(Integer... values) { //UI线程中执行,更新空间操作
super.onProgressUpdate(values);
Mylog.d("--------onProgressUpdate-------");
int progress = values[0]; //参数是动态数组,所以要先接收
mSeekBar.setProgress(progress);
mProgressTxt.setText(""+progress);
}

@Override
/*异步操作结束时调用的回调函数 UI线程中执行
* */
protected void onPostExecute(String result) { // 最后的结果
super.onPostExecute(result);
Mylog.d("--------onPostExecute-------");
mProgressTxt.setText(result);
}
}
}

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/show_progress_txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<SeekBar
android:id="@+id/asynctask_seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>

<Button
android:id="@+id/thread_start_btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="线程加handler方式加载进度"/>

<Button
android:id="@+id/asybctask_start_btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="asybctask加载进度"/>


<Button
android:id="@+id/asybctask_downloadPicture_btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="asybctask网路下载图片"/>

<ImageView
android:id="@+id/downloadpicture_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</LinearLayout>




更多相关文章

  1. Android Studio 检测内存泄漏与解决方法
  2. C#/Java 调用WSDL接口及方法
  3. Javadoc转换chm帮助文档的四种方法总结
  4. 最新Eclipse配置Android开发环境SDK 并安装JellyBean 4.3的方法
  5. Android 两种制作圆形/圆角图片的方法
  6. 在android中运行java main方法
  7. android studio 无法调试安装到小米手机解决方法
  8. OpenGL es 2.0使用shadow mapping方法制作阴影时,阴影穿透实体现
  9. Android studio Run 出现 红叉 AndroidRunConfigurationType 问

随机推荐

  1. 详解PHP中PHP-FPM是什么?有什么用?
  2. 带你了解php的三个常用框架:thinkphp、yaf
  3. PHP解析XML的几种方法(附代码)
  4. 示例Ajax异步传输与PHP实现交互
  5. 一起看看php实现购物车产品删除功能(2)
  6. 详解PHP基础算法:冒泡、选择、插入、快速
  7. php之接口与前端数据交互实现示例代码
  8. 一起看看php实现产品加入购物车功能(1)
  9. 了解php操作redis的几种常用方法
  10. 几款你绝对不知道的PHP集成开发环境软件