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更高效,因为它通过透明压缩和响应缓存 减少了网络使用,并 最大限度地降低了功耗

猜你喜欢

转载自blog.csdn.net/march0000/article/details/80151546
今日推荐