首页 > 代码库 > android异步任务图片下载(进度条提示进度)

android异步任务图片下载(进度条提示进度)

一、AsyncTask介绍

Android提供了几种在其他线程中访问UI线程的方法。

Activity.runOnUiThread( Runnable )   View.post( Runnable )   View.postDelayed( Runnable, long )   Hanlder   

这些类或方法同样会使你的代码很复杂很难理解。然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。

为了解决这个问题,Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。不需要借助线程和Handler即可实现。

AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。

◆Params 启动任务执行的输入参数,比如HTTP请求的URL。

◆Progress 后台任务执行的百分比。

◆Result 后台执行任务最终返回的结果,比如String。

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。

子类化AsyncTask

实现AsyncTask中定义的下面一个或几个方法

onPreExecute()

   该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。

doInBackground(Params...)

将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。

onProgressUpdate(Progress...)

在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。

onPostExecute(Result)

在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.

为了正确的使用AsyncTask类,以下是几条必须遵守的准则:

  1) Task的实例必须在UI thread中创建

  2) execute方法必须在UI thread中调用

  3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法

  4) 该task只能被执行一次,否则多次调用时将会出现异常

针对主线程和AsyncTask子线程的调用关系如下图:

1>主线程调用AsynTask子类实例的execute()方法后,首先会调用onPreExecute()方法。onPreExecute()在主线程中运行,可以用来写一些开始提示代码。
2>之后启动新线程,调用doInBackground()方法,进行异步数据处理。
3>处理完毕之后异步线程结束,在主线程中调用onPostExecute()方法。onPostExecute()可以进行一些结束提示处理。
补充:在doInBackground()方法异步处理的时候,如果希望通知主线程一些数据(如:处理进度)。这时,可以调用publishProgress()方法。这时,主线程会调用AsynTask子类的onProgressUpdate()方法进行处理。
各个函数间数据的传递
通过上面的调用关系,我们就可以大概看出一些数据传递关系。如下:
  execute()向doInBackground()传递。
  doInBackground()的返回值会传递给onPostExecute()。
  publishProgress()向progressUpdate()传递。
 
要点:为了调用关系明确及安全,AsynTask类在继承时要传入3个泛型。第一个泛型对应execute()向doInBackground()的传递类型。第二个泛型对应doInBackground()的返回类型和传递给onPostExecute()的类型。第三个泛型对应publishProgress()向progressUpdate()传递的类型。
传递的数据都是对应类型的数组,数组都是可变长的哦。可以根据具体情况使用。

二、图片异步下载举例说明

1.首先定义一个简单布局:

 

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:tools="http://schemas.android.com/tools" 3     android:layout_width="match_parent" 4     android:layout_height="match_parent" 5     android:paddingBottom="@dimen/activity_vertical_margin" 6     android:paddingLeft="@dimen/activity_horizontal_margin" 7     android:paddingRight="@dimen/activity_horizontal_margin" 8     android:paddingTop="@dimen/activity_vertical_margin" 9     tools:context=".MainActivity" >10 11     <Button12         android:id="@+id/btndownload"13         android:layout_width="wrap_content"14         android:layout_height="wrap_content"15         android:layout_alignParentBottom="true"16         android:layout_centerHorizontal="true"17         android:text="DOWNLOAD" />18 19     <EditText20         android:id="@+id/texturl"21         android:layout_width="wrap_content"22         android:layout_height="wrap_content"23         android:layout_above="@+id/btndownload"24         android:layout_centerHorizontal="true"25         android:ems="10" >26 27         <requestFocus />28     </EditText>29 30     <ImageView31         android:id="@+id/imageView1"32         android:layout_width="wrap_content"33         android:layout_height="wrap_content"34         android:layout_alignParentTop="true"35         android:layout_centerHorizontal="true"36         android:layout_above="@id/texturl"37         android:src="http://www.mamicode.com/@drawable/ic_launcher" />38 39 </RelativeLayout>

 

 

 

2.别忘了加上网络访问权限

 

1     <uses-sdk2         android:minSdkVersion="8"3         android:targetSdkVersion="18" />4     <uses-permission android:name="android.permission.INTERNET"/>

 

 

3.进入到MainActivity进入主要代码编写

  1 package com.example.android_asynctask_download;  2   3 import java.io.ByteArrayOutputStream;  4 import java.io.IOException;  5 import java.io.InputStream;  6   7 import org.apache.http.HttpResponse;  8 import org.apache.http.HttpStatus;  9 import org.apache.http.client.HttpClient; 10 import org.apache.http.client.methods.HttpGet; 11 import org.apache.http.impl.client.DefaultHttpClient; 12  13 import android.os.AsyncTask; 14 import android.os.Bundle; 15 import android.app.Activity; 16 import android.app.ProgressDialog; 17 import android.graphics.Bitmap; 18 import android.graphics.BitmapFactory; 19 import android.view.Menu; 20 import android.view.View; 21 import android.view.View.OnClickListener; 22 import android.widget.Button; 23 import android.widget.EditText; 24 import android.widget.ImageView; 25  26 public class MainActivity extends Activity { 27  28     private Button button; 29     private ImageView imageView; 30     private EditText texturl; 31     private String pic_pathString = "http://b.hiphotos.baidu.com/image/h%3D1200%3Bcrop%3D0%2C0%2C1920%2C1200/sign=165d5bcf9f16fdfac76cc2ec84bfb737/bf096b63f6246b60bd811290e9f81a4c500fa243.jpg"; 32     private ProgressDialog progressDialog; 33  34     @Override 35     protected void onCreate(Bundle savedInstanceState) { 36         super.onCreate(savedInstanceState); 37         setContentView(R.layout.activity_main); 38  39         button = (Button) this.findViewById(R.id.btndownload); 40         imageView = (ImageView) this.findViewById(R.id.imageView1); 41         texturl = (EditText) this.findViewById(R.id.texturl); 42         texturl.setText(pic_pathString); 43         progressDialog = new ProgressDialog(this); 44         progressDialog.setTitle("提示信息"); 45         progressDialog.setMessage("正在下载,请稍后..."); 46         progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 47         button.setOnClickListener(new OnClickListener() { 48  49             @Override 50             public void onClick(View v) { 51                 // TODO Auto-generated method stub 52                 pic_pathString = texturl.getText().toString(); 53                 new mytask().execute(pic_pathString); 54             } 55         }); 56  57     } 58  59     public class mytask extends AsyncTask<String, Integer, Bitmap> { 60         @Override 61         protected void onPreExecute() { 62             // TODO Auto-generated method stub 63             // super.onPreExecute(); 64             progressDialog.show(); 65         } 66  67         @Override 68         protected Bitmap doInBackground(String... params) { 69 //            // TODO Auto-generated method stub 70 //            Bitmap bitmap = null; 71 //            HttpClient httpClient = new DefaultHttpClient(); 72 //            HttpGet httpGet = new HttpGet(params[0]); 73 //            try { 74 //                HttpResponse httpResponse = httpClient.execute(httpGet); 75 //                if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 76 //                    byte[] data = http://www.mamicode.com/EntityUtils.toByteArray(httpResponse> 77 //                            .getEntity()); 78 //                    bitmap = BitmapFactory 79 //                            .decodeByteArray(data, 0, data.length); 80 //                } 81 //            } catch (ClientProtocolException e) { 82 //                // TODO Auto-generated catch block 83 //                e.printStackTrace(); 84 //            } catch (IOException e) { 85 //                // TODO Auto-generated catch block 86 //                e.printStackTrace(); 87 //            } 88 // 89 //            return bitmap; 90              91             //完成对图片的下载和进度数值的更新 92             Bitmap bitmap = null; 93             ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 94             InputStream inputStream = null; 95             try { 96                 HttpClient httpClient = new DefaultHttpClient(); 97                 HttpGet httpGet = new HttpGet(params[0]); 98                 HttpResponse httpResponse = httpClient.execute(httpGet); 99                 if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {100                     inputStream = httpResponse.getEntity().getContent();101                     //先要获得文件的总长度102                     long file_length = httpResponse.getEntity().getContentLength();103                     int len = 0;104                     byte[] data = http://www.mamicode.com/new byte[128];105                     int total_length = 0;106                     while ((len = inputStream.read(data)) != -1) {107                         total_length+=len;108                         int value = http://www.mamicode.com/(int)((total_length/(float)file_length)*100);109                         publishProgress(value);110                         outputStream.write(data, 0, data.length);111                     }112                     byte[] result = outputStream.toByteArray();113                     bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);114                 }115             } catch (Exception e) {116                 // TODO: handle exception117             }finally{118                 if(inputStream != null)119                 {120                     try {121                         inputStream.close();122                     } catch (IOException e) {123                         // TODO Auto-generated catch block124                         e.printStackTrace();125                     }126                 }127             }128                     129             return bitmap;            130         }131 132         @Override133         protected void onProgressUpdate(Integer... values) {134             // TODO Auto-generated method stub135              //super.onProgressUpdate(values);136             progressDialog.setProgress(values[0]);137         }138 139         @Override140         protected void onPostExecute(Bitmap result) {141             // TODO Auto-generated method stub142             // super.onPostExecute(result);143             progressDialog.dismiss();144             imageView.setImageBitmap(result);145         }146 147     }148 149     @Override150     public boolean onCreateOptionsMenu(Menu menu) {151         // Inflate the menu; this adds items to the action bar if it is present.152         getMenuInflater().inflate(R.menu.main, menu);153         return true;154     }155 156 }

 

在手机上运行的样子:

谢谢耐心阅读,希望对您有些帮助。