Android有进度条异步任务下载图片

首先在AndroidMainifest中添加上网权限

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

布局文件activity_main.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" >

    <ImageView
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_height="280dp" />

    <Button
        android:id="@+id/btn"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:text="下载图片" />

</LinearLayout>

Activity代码:

public class MainActivity extends Activity{

	private Button button;
	
	private ImageView imageView;
	
	private ProgressDialog progressDialog;
	
	private final String IMATH_PATH = "http://image16-c.poco.cn/best_pocoers/20141010/11092014101016572228935421.jpg";
	
	private AsyncTask<String, Integer, byte[]> task;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button = (Button)findViewById(R.id.btn);
		imageView = (ImageView)findViewById(R.id.img);
		progressDialog = new ProgressDialog(this);
		progressDialog.setTitle("提示信息");
		progressDialog.setMessage("正在下载中,请稍后");
		progressDialog.setOnCancelListener(new OnCancelListener() {
			
			@Override
			public void onCancel(DialogInterface arg0) {
				// TODO Auto-generated method stub
				task.cancel(true);
			}
		});
		progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		button.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				task = new MyAsyncTask().execute(IMATH_PATH);
			}
		});
		
		
	}

	
   class MyAsyncTask extends AsyncTask<String, Integer, byte[]>{

	   @Override
	protected void onPreExecute() {
		// TODO Auto-generated method stub
		super.onPreExecute();
		progressDialog.setProgress(0);
		progressDialog.show();
	}
	 
	   @Override
	protected void onProgressUpdate(Integer... values) {
		// TODO Auto-generated method stub
		super.onProgressUpdate(values);
		progressDialog.setProgress(values[0]);
	}
	   
	@Override
	protected byte[] doInBackground(String... params) {
		// TODO Auto-generated method stub
		HttpClient httpClient = new DefaultHttpClient(); 
		HttpGet httpGet = new HttpGet(params[0]);
		byte[] image = new byte[]{};
		try{
			HttpResponse httpResponse = httpClient.execute(httpGet);
			HttpEntity httpEntity = httpResponse.getEntity();
			InputStream inputStream = null;
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
			if(httpEntity !=null && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
				long file_length = httpEntity.getContentLength();
				long total_length = 0;
				int length = 0;
				byte[] data = new byte[1024];
				inputStream = httpEntity.getContent();
				while(-1 != (length = inputStream.read(data))){
					total_length += length;
					byteArrayOutputStream.write(data, 0, length);
					int progress = ((int)(total_length/(float)file_length)*100);
					publishProgress(progress);
				}
			}
			image = byteArrayOutputStream.toByteArray();
			inputStream.close();
			byteArrayOutputStream.close();
		}catch(Exception e){
			 e.printStackTrace();
		}
		finally{
			httpClient.getConnectionManager().shutdown();
		}
		return image;
	}
	
	@Override
	protected void onPostExecute(byte[] result) {
		// TODO Auto-generated method stub
		super.onPostExecute(result);
		Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
		imageView.setImageBitmap(bitmap);
		progressDialog.dismiss();
	}
	   
   }

}

讲解:

syncTask:异步任务,从字面上来说,就是在我们的UI主线程运行的时候,异步的完成一些操作。AsyncTask允许我们的执行一个异步的任务在后台。我们可以将耗时的操作放在异步任务当中来执行,并随时将任务执行的结果返回给我们的UI线程来更新我们的UI控件。通过AsyncTask我们可以轻松的解决多线程之间的通信问题。

怎么来理解AsyncTask呢?通俗一点来说,AsyncTask就相当于Android给我们提供了一个多线程编程的一个框架,其介于Thread和Handler之间,我们如果要定义一个AsyncTask,就需要定义一个类来继承AsyncTask这个抽象类,并实现其唯一的一个 doInBackgroud 抽象方法。要掌握AsyncTask,我们就必须要一个概念,总结起来就是: 3个泛型,4个步骤。

3个泛型指的是什么呢?我们来看看AsyncTask这个抽象类的定义,当我们定义一个类来继承AsyncTask这个类的时候,我们需要为其指定3个泛型参数:

AsyncTask <Params, Progress, Result>
  • Params: 这个泛型指定的是我们传递给异步任务执行时的参数的类型
  • Progress: 这个泛型指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型
  • Result: 这个泛型指定的异步任务执行完后返回给UI线程的结果的类型

 我们在定义一个类继承AsyncTask类的时候,必须要指定好这三个泛型的类型,如果都不指定的话,则都将其写成Void,例如:

AsyncTask <Void, Void, Void>

4个步骤:当我们执行一个异步任务的时候,其需要按照下面的4个步骤分别执行

  • onPreExecute(): 这个方法是在执行异步任务之前的时候执行,并且是在UI Thread当中执行的,通常我们在这个方法里做一些UI控件的初始化的操作,例如弹出要给ProgressDialog
  • doInBackground(Params... params): 在onPreExecute()方法执行完之后,会马上执行这个方法,这个方法就是来处理异步任务的方法,Android操作系统会在后台的线程池当中开启一个worker thread来执行我们的这个方法,所以这个方法是在worker thread当中执行的,这个方法执行完之后就可以将我们的执行结果发送给我们的最后一个 onPostExecute 方法,在这个方法里,我们可以从网络当中获取数据等一些耗时的操作
  • onProgressUpdate(Progess... values): 这个方法也是在UI Thread当中执行的,我们在异步任务执行的时候,有时候需要将执行的进度返回给我们的UI界面,例如下载一张网络图片,我们需要时刻显示其下载的进度,就可以使用这个方法来更新我们的进度。这个方法在调用之前,我们需要在 doInBackground 方法中调用一个 publishProgress(Progress) 的方法来将我们的进度时时刻刻传递给 onProgressUpdate 方法来更新
  • onPostExecute(Result... result): 当我们的异步任务执行完之后,就会将结果返回给这个方法,这个方法也是在UI Thread当中调用的,我们可以将返回的结果显示在UI控件上

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。