zoukankan      html  css  js  c++  java
  • 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     <Button
    12         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     <EditText
    20         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     <ImageView
    31         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="@drawable/ic_launcher" />
    38 
    39 </RelativeLayout>

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

    1     <uses-sdk
    2         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 = 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 = new byte[128];
    105                     int total_length = 0;
    106                     while ((len = inputStream.read(data)) != -1) {
    107                         total_length+=len;
    108                         int value = (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 exception
    117             }finally{
    118                 if(inputStream != null)
    119                 {
    120                     try {
    121                         inputStream.close();
    122                     } catch (IOException e) {
    123                         // TODO Auto-generated catch block
    124                         e.printStackTrace();
    125                     }
    126                 }
    127             }
    128                     
    129             return bitmap;            
    130         }
    131 
    132         @Override
    133         protected void onProgressUpdate(Integer... values) {
    134             // TODO Auto-generated method stub
    135              //super.onProgressUpdate(values);
    136             progressDialog.setProgress(values[0]);
    137         }
    138 
    139         @Override
    140         protected void onPostExecute(Bitmap result) {
    141             // TODO Auto-generated method stub
    142             // super.onPostExecute(result);
    143             progressDialog.dismiss();
    144             imageView.setImageBitmap(result);
    145         }
    146 
    147     }
    148 
    149     @Override
    150     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 }

    在手机上运行的样子:

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

  • 相关阅读:
    IDEA的database插件无法链接mysql的解决办法(08001错误)
    window.location.href传参/传值汇总
    toggleClass() 方法
    File file=new File ()
    MultipartFile接口
    @RequestParam注解字参数详解
    在微信下载的浏览器判断问题
    JS可控制的图片自动循环播放查看效果
    PHP接口的声明与引用
    js时间
  • 原文地址:https://www.cnblogs.com/ning1121/p/3922439.html
Copyright © 2011-2022 走看看