/** * 作者:crazyandcoder * 联系: * QQ : 275137657 * email: lijiwork@sina.com * 转载请注明出处! */
异步任务 AsyncTask使用
android中实现异步机制主要有Thread加Handler和AsyncTask,今天主要记录一下AsyncTask的学习过程,以备以后之需。
一、构建AsyncTask子类的参数
AsyncTask<Params,Progress,Result>是一个抽象类。通常用于被继承,继承AsyncTask需要指定如下三个泛型参数。
Threading rules There are a few threading rules that must be followed for this class to work properly: 1、The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN. 2、The task instance must be created on the UI thread. 3、execute(Params...) must be invoked on the UI thread. 4、Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually. 5、The task can be executed only once (an exception will be thrown if a second execution is attempted.)
大概意思就是说:
图1 图2 图3
图1显示的是功能,主要是点击button后进入加载网络图片页面;
图2显示的是加载网络图片过程中的进度百分比;
图3显示的是当加载进度百分比为100%时,显示要加载的网络图片。
下面我们来分析一下具体的实现代码:
主界面的布局就不贴了,主要就是一个button按钮,然后在MainActivity中实现页面跳转,我们主要来看看ImageTest.class 中是如何实现加载网络图片的。
首先是xml布局,布局很简单,一个ImageView组件显示网络图片,一个ProgressBar组件用于显示进度,一个TextView用于显示加载的进度百分比,总得布局用RelativeLayout实现。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/imageView1" android:layout_width="match_parent" android:layout_height="match_parent" /> <ProgressBar android:id="@+id/progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="gone" /> <TextView android:id="@+id/mTextprogress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="15%" android:layout_centerInParent="true" android:textSize="13sp" /> </RelativeLayout>
package com.example.asynctaskdemo; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.nfc.Tag; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; /** * 显示一张网络图片 * * @author crazyandcoder * @date [2015-8-9 下午4:11:27] */ public class ImageTest extends Activity { private String TAG = "ImageTest.class"; private ImageView mImageView; private ProgressBar mProgressBar; private TextView mTextProgress; private MyAsyncTaskShowImg mTask; private static String mImgUrl = "http://h.hiphotos.baidu.com/image/pic/item/9922720e0cf3d7ca14dcc750f71fbe096b63a9ea.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.image); initView(); mTask = new MyAsyncTaskShowImg(); mTask.execute(mImgUrl); } private void initView() { mTextProgress = (TextView) findViewById(R.id.mTextprogress); mImageView = (ImageView) findViewById(R.id.imageView1); mProgressBar = (ProgressBar) findViewById(R.id.progress); } class MyAsyncTaskShowImg extends AsyncTask<String, Integer, Bitmap> { /** * 初始化UI控件 * * @see android.os.AsyncTask#onPreExecute() */ @Override protected void onPreExecute() { super.onPreExecute(); mProgressBar.setVisibility(View.VISIBLE); mTextProgress.setText("0%"); } /** * 执行复杂的耗时任务 * * @param params * @return * @see android.os.AsyncTask#doInBackground(Params[]) */ @Override protected Bitmap doInBackground(String... params) { // 网络中图片的地址 String mImgUrl = params[0]; String mFileName = "temp_pic"; Log.d(TAG, "mImgUrl is " + mImgUrl); // 网络中图片最终将转化为bitmap类型返回给imageview显示 Bitmap mBitmap = null; // 获取数据的输入流 InputStream is = null; OutputStream out = null; HttpURLConnection connection; try { // 将网络图片地址以流的方式转化为bitmap类型 connection = (HttpURLConnection) new URL(mImgUrl).openConnection(); connection.setDoInput(true); connection.setDoOutput(false); // 设置链接超时时间 connection.setConnectTimeout(10 * 1000); is = connection.getInputStream(); out = openFileOutput(mFileName, MODE_PRIVATE); byte[] data = new byte[1024]; // 每次读到的长度 int seg = 0; // 总得数据大小 long totalSize = connection.getContentLength(); Log.d(TAG, "total size is " + totalSize); // 现在的进度 long current = 0; // while (!(mTask.isCancelled()) && (seg = is.read(data)) != -1) { // 当前总的进度 current += seg; Log.d(TAG, "current size is " + current); // 下载百分比 int progress = (int) ((float) current / totalSize * 100); Log.d(TAG, "progress size is " + progress); // 通知更新进度 publishProgress(progress); out.write(data, 0, seg); } mBitmap = BitmapFactory.decodeFile(getFileStreamPath(mFileName).getAbsolutePath()); Log.d(TAG, "file is " + getFileStreamPath(mFileName).getAbsolutePath()); connection.disconnect(); is.close(); out.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return mBitmap; } /** * 显示从网络中加载图片的进度 * * @param values * @see android.os.AsyncTask#onProgressUpdate(Progress[]) */ @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); mTextProgress.setText(values[0] + "%"); } /** * 将doInBackground中执行的结果返回给该方法,用于更新UI控件 * * @param result * @see android.os.AsyncTask#onPostExecute(java.lang.Object) */ @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); mProgressBar.setVisibility(View.GONE); mTextProgress.setVisibility(View.GONE); mImageView.setImageBitmap(result); Toast.makeText(ImageTest.this, "图片加载完成.", Toast.LENGTH_LONG).show(); } } @Override protected void onPause() { super.onPause(); if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) { //cancel方法只是将AsyncTask对应的状态标记为cancel状态,不是真的取消 mTask.cancel(true); } } }
最后附上源代码:下载地址
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/liji_xc/article/details/47313069