1. 程式人生 > >Android執行緒池(AsyncTask)與HttpClient的結合使用

Android執行緒池(AsyncTask)與HttpClient的結合使用

AsyncTask(非同步任務):

    1.解釋:AsyncTask是抽象類,若要使用,需要建立一個子類去繼承它;

                 使用AsyncTask不需要再使用Handler和子執行緒;

    2.功能:非同步操作、重新整理使用者介面;

    3.AsyncTask的三個泛型引數:

①Params(String)傳遞引數,後臺任務時使用(即呼叫doInBackground()方法);

②Progress(Integer)後臺執行任務,返回泛型進度單位,用於在使用者介面顯示進度;

③Result(Bitmap)任務執行完畢,使用泛型作為返回值返回結果;

    4.AsyncTask四大方法:

①onPreExecute()後臺任務開始執行前呼叫,可以訪問UI控制元件,用於初始化操作(如:顯示控制元件);

②doInBackground(Stringparams) 該方法中的所有程式碼都會在子執行緒中執行,在這個方法中處理耗時任務(如:下載、讀寫大檔案...),任務執行完畢返回result,若方法型別為void則不需要返回。在該方法中不可進行UI操作

③onProgressUpdate(Integervalues) 當在後臺任務呼叫了publishProgress()方法後,該方法很快會被呼叫,其攜帶的引數是後臺任務傳遞過來的。在該方法中可以利用引數中的數值對UI元素進行更新操作

④onPostExecute(Bitmapresult) 後臺任務執行完畢並通過return返回時,該方法很快會被呼叫。其返回的資料會被作為引數傳遞到該方法中,可以利用返回的資料對UI進行操作(如:提醒任務執行結果、關閉進度條對話方塊...)。

    5.使用AsyncTask更新UI控制元件:

package com.example.mjon.myapplication;

import
android.app.ProgressDialog;
import
android.graphics.Bitmap;
import
android.graphics.BitmapFactory;
import
android.os.AsyncTask

;
import
android.support.v7.app.AppCompatActivity;
import
android.os.Bundle;
import
android.view.View;
import
android.widget.Button;
import
android.widget.ImageView;

import
org.apache.http.HttpResponse;
import
org.apache.http.client.HttpClient;
import
org.apache.http.client.methods.HttpGet;
import
org.apache.http.impl.client.DefaultHttpClient;

import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
java.io.InputStream;

public class
MainActivity extends AppCompatActivity {

   
private Buttonbtn;
    private
ImageView img;
   
//資源連結
   
private Stringimage_path = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1523612429201&di=010e8721a2c271c163f276bbc233f97f&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fc%2F58b8e4cb25ef9.jpg";
   
//對話方塊進度條
   
private ProgressDialogdialog;

   
@Override
   
protected void onCreate(BundlesavedInstanceState) {
       
super.onCreate(savedInstanceState);
       
setContentView(R.layout.activity_main);
       
btn =(Button) findViewById(R.id.btn);
       
img =(ImageView) findViewById(R.id.img);
       
//建立對話方塊進度條,並設定標題、資訊、樣式、焦點
       
dialog = new ProgressDialog(MainActivity.this);
       
dialog.setTitle("正在載入");
       
dialog.setMessage("圖片正在載入中,請稍後...");
       
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
       
dialog.setCancelable(false)//是否失去焦點

       
btn.setOnClickListener(new View.OnClickListener() {

           
@Override
           
public void onClick(View arg0) {
               
// ▲必須寫在UI主執行緒中
                new MyAsyncTask().execute(image_path)//例項化並呼叫MyAsyncTask執行網路請求及資源下載
            }
        })
;
   
}

   
//建立AsyncTask類方法,繼承父類並給予三個泛型引數(資源連結,泛型進度單位,返回資料)
    public class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> {

       
//後臺任務開始前呼叫——初始化
       
@Override
       
protected void onPreExecute() {
           
super.onPreExecute();
           
dialog.show()//顯示進度條對話方塊控制元件
       
}

       
//子執行緒執行——訪問網路
       
@Override
       
protected BitmapdoInBackground(String... params) {
            Bitmap bitmap =
null;  //用於儲存圖片
           
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()//建立輸出流物件,程式內部建立一個位元組陣列的緩衝區,利用該物件可以向陣列中寫入bute型資料
            InputStream inputStream = null; //建立位元組輸入流物件
           
try {
                HttpClient httpClient =
new DefaultHttpClient()//例項化DefaultHttpClient物件,儲存到HttpClient介面中
                HttpGet httpGet = new HttpGet(params[0])//建立請求物件並傳遞引數params(資源連結)
                HttpResponse httpResponse =httpClient.execute(httpGet)//通過介面去執行請求模式操作,伺服器返回一個Response(儲存返回的所有資料)物件,建立HttpResponse物件接收資料物件
                if (httpResponse.getStatusLine().getStatusCode() == 200) {  //取出伺服器狀態碼,若等於200說明請求和響應皆成功
                    inputStream =httpResponse.getEntity().getContent()//通過HttpResponse物件取出資料,儲存在位元組型輸入流中
                    long file_length = httpResponse.getEntity().getContentLength()//獲取檔案的總長度
                   
int len = 0//每次讀取位元組的長度
                   
int total_length = 0//讀取位元組長度的總和
                   
byte[] data = newbyte[1024]; //建立緩衝區
                   
while ((len = inputStream.read(data)) != -1) {  //判斷是否讀到檔案末尾
                       
total_length += len//疊加每次下載的長度
                       
int value = (int) ((total_length / (float) file_length) * 100)//下載完的部分佔全部檔案長度的百分比,返回刻度值
                       
publishProgress(value)//把進度刻度釋出出去
                       
outputStream.write(data, 0, len)//把緩衝區資料寫入到輸出流物件中
                   
}
                   
byte[] result = outputStream.toByteArray()//將輸出流裡的資料轉換為位元組型陣列
                   
bitmap = BitmapFactory.decodeByteArray(result, 0, result.length)//將位元組陣列流轉換成為Bitmap圖片格式
                }
            }
catch (Exceptione) {

            }
finally {
               
if (inputStream!= null) {  //判斷輸入流是否有資料,若輸入流有資料
                   
try {
                       inputStream.close()
//關閉輸入流
                   
} catch (IOException e) {
                       e.printStackTrace()
;
                   
}
                }
            }
           
return bitmap//返回圖片
       
}

       
@Override
       
protected void onProgressUpdate(Integer...values) {
           
super.onProgressUpdate(values);
           
dialog.setProgress(values[0])//設定進度條對話方塊刻度;
       
}

       
@Override
       
protected void onPostExecute(Bitmap result){
           
super.onPostExecute(result);
           
img.setImageBitmap(result)//設定圖片
           
dialog.dismiss()//結束進度條對話方塊
       
}

    }
}

訪問網路許可權:

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

    6.總結:

            ①Android studio 使用HttpClient時,需要在build.gradle新增依賴:

android {defaultConfig {useLibrary'org.apache.http.legacy'
   
}
}

           ②官方文件說明:Android 6.0 版本 刪除了對Apache HTTP客戶端的支援,建議使用HttpURLConnection,此API更高效,因為它通過透明壓縮和響應快取減少了網路使用,並最大限度地降低了功耗