package com.example.asynctask;
/* 功能:点击按钮后开始下载设置网页中的图片,和上一个区别的地方是它更新了进度条。
* 利用了异步任务的功能。
* */
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
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 org.apache.http.util.EntityUtils;
import android.R.integer;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.InputFilter.LengthFilter;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity {
private Button button;
private ImageView imageView;
// 在清单中加Permission授权访问Internet
// 添加网络图片的路径。
private final String IMAGE_PATH = "http://www.baidu.com/img/bdlogo.png";
// 如果是本地要加IP和端口及目录。
private ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) this.findViewById(R.id.button1);
dialog = new ProgressDialog(this);
dialog.setTitle("提示");
dialog.setCancelable(false);
dialog.setMessage("正在下载图片,请稍候……");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); // 圆形的是没有刻度的,横向的才有。
imageView = (ImageView) this.findViewById(R.id.imageView1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
// 执行异步任务。
new MyTask().execute(IMAGE_PATH);
}
});
}
/*
* 下面是异步任务MyTask。 一步任务执行下载网上图片的控件。
* 这个是个抽象类必定有一个抽象的方法。是doInBackground,这个异步任务戳必须要做的。
*/
public class MyTask extends AsyncTask<String, Integer, byte[]> {
// 参数1是异步任务需要执行的东西,访问网络的网址。第二个参数是刻度的单位类型是integer,第三个参数是结果,后台执行的结果,返回图片是Byte[]字节数组
// 没有参数时候用Void型。
@Override
protected void onPreExecute() {
// 若没有提示框,这个步骤不用调。如果不需要把得到的结果给UI,最后一个步骤不能调。不需要更新进度条就不用步骤三
// 首先设置dialog显示。
super.onPreExecute();
dialog.show();
};
protected byte[] doInBackground(String... params) {
// TODO Auto-generated method stub 这是步骤二
// 会上面一个步骤执行后会立即执行,这是一个后台操作,这个参数是表示要执行的路径。对应于String。会计算出来以返回给最后一个步骤
// 在这个步骤中可以用publishProgess把进度发布给UI线程给第三个步骤。有算法。
// 后台执行的操作,返回结果给onPostExecute
HttpClient httpClient = new DefaultHttpClient(); // 默认的构造函数,多数情况已足够使用。构造一个HttpClient实例。
HttpGet httpGet = new HttpGet(params[0]); // HttpGet是获取网络目标的。
byte[] result = null; // 图片的所有内容
// 要用在显示更新进度条,就要用到流。
InputStream inputStream = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
HttpResponse httpResponse = httpClient.execute(httpGet); // HttpResponse是获取Http响应状态。
long file_length = httpResponse.getEntity().getContentLength(); // 文件总长度
int total_length = 0; // 下载的总长度
byte[] data = new byte[1024];
int len = 0;
if (httpResponse.getStatusLine().getStatusCode() == 200) { // 这是页面请求的状态值,200表示请求成功
inputStream = httpResponse.getEntity().getContent(); // getContent是每次变化的刷新函数。
// 读到缓冲区当中,当不是-1时,就是不是结束时。
while ((len = inputStream.read(data)) != -1) {
// 一边读,一边计算刻度.
total_length += len; // yi wen
// :len是怎么样的,是累计的,还是每一次的while中会有多少数据而没有累计。推测是后者。
int progress_value = (int) ((total_length / (float) file_length) * 100); // 计算刻度的公式
publishProgress(progress_value); // 发布刻度单位到步骤三
outputStream.write(data, 0, len); //从data[0]开始写 data的len个的字节。data的len个字节。
//outputStream是对象,所以可能就把这个数据写入了这个对象里面吗?
}
}
// result = EntityUtils.toByteArray(httpResponse.getEntity());
// 这个是不更新进度时用的代码。
result = outputStream.toByteArray(); //这是把字节流转换成Byte流。
// 上面一句是把这个值返回回去,这种写法不好,后面会处理,如压缩什么的。
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace(); //将异常打印在控制台上
} finally {
httpClient.getConnectionManager().shutdown(); //必须调用方法关闭。
}
return result;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
// 更新进度条。要有计算过程
super.onProgressUpdate(values);
// 字节数组要产生刻度单位,下载的数据长度÷总长度。这个在前面步骤中做
// 发布刻度单位
dialog.setProgress(values[0]);
}
protected void onPostExecute(byte[] result) {
// TODO Auto-generated method stub
// 取得结果,在这里更新UI
super.onPostExecute(result);
Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0,
result.length);
imageView.setImageBitmap(bitmap);
dialog.dismiss();
}
}
}
注释上有解释。
AsyncTask(二)
最新推荐文章于 2018-01-20 14:52:08 发布