Android学习之Asynctask异步操作

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>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值