AsyncTask可以用來處理一些後臺較耗時的任務,查看源碼發現其內部就是一個Handler和線程池的封裝,因此可以幫助我們處理耗時任務的同時去更新UI。
本次內容就利用了AsyncTask去實現完成了一個簡單的對圖片加載進度監聽的Demo,當然這個監聽的實現方法有很多,也有很多開源的圖片加載框架也實現了這個功能,這次就當開括思路,也算是和大家一起回顧一下AsyncTask的使用吧。
Demo代碼
public class MainActivity extends AppCompatActivity {
private ProgressBar mProgressBar;
private ImageView mImageView;
private Button mButton;
private MyAsyncTask mTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = findViewById(R.id.progressBar);
mImageView = findViewById(R.id.imageView);
mButton = findViewById(R.id.btn);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTask = new MyAsyncTask(MainActivity.this);
String url = "http://wx1.sinaimg.cn/mw600/0076BSS5ly1gbophiekmuj30u0190aiq.jpg";
mTask.execute(url);
}
});
}
static class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> {
private WeakReference<MainActivity> mWeakReference;
MyAsyncTask(MainActivity activity) {
mWeakReference = new WeakReference<>(activity);
}
//執行前的準備(UI線程)
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//異步執行的代碼(子線程)
@Override
protected Bitmap doInBackground(String... strings) {
String url = strings[0];
HttpURLConnection connection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
File file;
Bitmap bitmap = null;
try {
connection = (HttpURLConnection) new URL(url).openConnection();
Log.i("kkk", "responseCode = " + connection.getResponseCode() + "\ncontentLength = " + connection.getContentLength());
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
return null;
//獲取文件總長度
int totalLength = connection.getContentLength();
int currentLength = 0;
inputStream = connection.getInputStream();
file = new File(mWeakReference.get().getCacheDir().getAbsolutePath() + File.separator + url.substring(url.lastIndexOf("/")));
outputStream = new FileOutputStream(file);
byte[] bytes = new byte[1024 * 8];
int len;
int percent;
while ((len = inputStream.read(bytes)) != -1) {
currentLength += len;
percent = (int) ((float) currentLength / totalLength * 100);
//緩存到本地
outputStream.write(bytes, 0, len);
Log.i("kkk", "percent = " + percent);
publishProgress(percent);
}
//加載本地緩存的圖片並返回
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (connection != null)
connection.disconnect();
if (inputStream != null)
inputStream.close();
if (outputStream != null)
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return bitmap;
}
//執行進度(UI線程)
@Override
protected void onProgressUpdate(Integer... values) {
mWeakReference.get().mProgressBar.setProgress(values[0]);
}
//執行完成返回結果(UI線程)
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (bitmap == null)
return;
MainActivity activity = mWeakReference.get();
activity.mButton.setVisibility(View.GONE);
activity.mProgressBar.setVisibility(View.GONE);
activity.mImageView.setImageBitmap(bitmap);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mTask != null && !mTask.isCancelled()) {
mTask.cancel(true);
}
}
}
完成效果