Android帶進(jìn)度條的下載圖片示例(AsyncTask異步任務(wù))
為什么要用異步任務(wù)?
在Android中只有在主線程才能對ui進(jìn)行更新操作,而其它線程不能直接對ui進(jìn)行操作
android本身是一個(gè)多線程的操作系統(tǒng),我們不能把所有的操作都放在主線程中操作 ,比如一些耗時(shí)操作。如果放在主線程中 會(huì)造成阻塞 而當(dāng)阻塞事件過長時(shí) 系統(tǒng)會(huì)拋出anr異常。所以我們要使用異步任務(wù)。android為我們提供了一個(gè)封裝好的組件asynctask。
AsyncTask可以在子線程中更新ui,封裝簡化了異步操作。適用于簡單的異步處理。如果多個(gè)后臺(tái)任務(wù)時(shí)就要使用Handler了 在這里就不再說明。
AsyncTask通常用于被繼承。AsyncTask定義了三種泛型類型<Params,Progress,Result>
- Params:啟動(dòng)任務(wù)時(shí)輸入的參數(shù)類型
- Progress:后臺(tái)任務(wù)執(zhí)行的百分比
- Result:執(zhí)行任務(wù)完成后返回結(jié)果的類型
繼承AsyncTask后要重寫的方法有:
doInBackgroud:必須重寫,異步執(zhí)行后臺(tái)線程要完成的任務(wù),耗時(shí)任務(wù)要寫在這里,并且在這里不能操作ui??梢哉{(diào)用 publishProgress方法來更新實(shí)時(shí)的任務(wù)進(jìn)度
onPreExecute:執(zhí)行耗時(shí)操作前調(diào)用,可以完成一些初始化操作
onPostExecute:在doInBackground 執(zhí)行完成后,主線程調(diào)用此方法,可以在此方法中操作ui
onProgressUpdate:在doInBackgroud方法中調(diào)用publishProgress方法,更新任務(wù)的執(zhí)行進(jìn)度后 就會(huì)調(diào)用這個(gè)方法
下面通過一個(gè)實(shí)例來了解AsyncTask
首先附上運(yùn)行結(jié)果

布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/btn_download" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="點(diǎn)擊下載" /> <FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/iv_image" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="fitCenter" /> </FrameLayout> </LinearLayout>
MainActivity
package com.example.asynctask;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URLConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity implements OnClickListener{
private ImageView image;
private ProgressDialog progress;
private Button btn_download;
private static String URL="http://img4.imgtn.bdimg.com/it/u=1256159061,743487979&fm=21&gp=0.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image=(ImageView) findViewById(R.id.iv_image);
btn_download=(Button) findViewById(R.id.btn_download);
progress=new ProgressDialog(this);
progress.setIcon(R.drawable.ic_launcher);
progress.setTitle("提示信息");
progress.setMessage("正在下載,請稍候...");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
btn_download.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new MyAsyncTask().execute(URL);
}
/*
* String*********對應(yīng)我們的URL類型
* Integer********進(jìn)度條的進(jìn)度值
* BitMap*********異步任務(wù)完成后返回的類型
* */
class MyAsyncTask extends AsyncTask<String, Integer, Bitmap>{
//執(zhí)行異步任務(wù)(doInBackground)之前執(zhí)行,并且在ui線程中執(zhí)行
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
if(image!=null){
image.setVisibility(View.GONE);
}
//開始下載 對話框進(jìn)度條顯示
progress.show();
progress.setProgress(0);
}
@Override
protected Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
//params是一個(gè)可變長的數(shù)組 在這里我們只傳進(jìn)來了一個(gè)url
String url=params[0];
Bitmap bitmap=null;
URLConnection connection;
InputStream is;//用于獲取數(shù)據(jù)的輸入流
ByteArrayOutputStream bos;//可以捕獲內(nèi)存緩沖區(qū)的數(shù)據(jù),轉(zhuǎn)換成字節(jié)數(shù)組。
int len;
float count=0,total;//count為圖片已經(jīng)下載的大小 total為總大小
try {
//獲取網(wǎng)絡(luò)連接對象
connection=(URLConnection) new java.net.URL(url).openConnection();
//獲取當(dāng)前頁面的總長度
total=(int)connection.getContentLength();
//獲取輸入流
is=connection.getInputStream();
bos=new ByteArrayOutputStream();
byte []data=new byte[1024];
while((len=is.read(data))!=-1){
count+=len;
bos.write(data,0,len);
//調(diào)用publishProgress公布進(jìn)度,最后onProgressUpdate方法將被執(zhí)行
publishProgress((int)(count/total*100));
//為了顯示出進(jìn)度 人為休眠0.5秒
Thread.sleep(500);
}
bitmap=BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.toByteArray().length);
is.close();
bos.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap;
}
//在ui線程中執(zhí)行 可以操作ui
@Override
protected void onPostExecute(Bitmap bitmap) {
// TODO Auto-generated method stub
super.onPostExecute(bitmap);
//下載完成 對話框進(jìn)度條隱藏
progress.cancel();
image.setImageBitmap(bitmap);
image.setVisibility(View.VISIBLE);
}
/*
* 在doInBackground方法中已經(jīng)調(diào)用publishProgress方法 更新任務(wù)的執(zhí)行進(jìn)度后
* 調(diào)用這個(gè)方法 實(shí)現(xiàn)進(jìn)度條的更新
* */
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
progress.setProgress(values[0]);
}
}
}
最后不要忘記在AndroidManifest文件中配置網(wǎng)絡(luò)訪問權(quán)限
<uses-permission android:name="android.permission.INTERNET"/>
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
深入解析Android中View創(chuàng)建的全過程
這篇文章主要給大家深入的解析了關(guān)于Android中View創(chuàng)建的全過程,文中介紹的非常詳細(xì),相信對大家會(huì)有一定的參考借鑒,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。2017-03-03
Android中實(shí)現(xiàn)Webview頂部帶進(jìn)度條的方法
這篇文章主要介紹了Android中實(shí)現(xiàn)Webview頂部帶進(jìn)度條的方法,當(dāng)前很流行的一個(gè)效果,就是打開網(wǎng)頁時(shí)會(huì)在頂部顯示一個(gè)打開進(jìn)度條,需要的朋友可以參考下2015-01-01
Android在一個(gè)app中安裝并卸載另一個(gè)app的示例代碼
這篇文章主要介紹了Android在一個(gè)app中安裝并卸載另一個(gè)app的示例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
基于Android自定義控件實(shí)現(xiàn)刮刮樂效果
這篇文章主要介紹了基于Android自定義控件實(shí)現(xiàn)刮刮樂效果 的相關(guān)資料,需要的朋友可以參考下2015-12-12
Android實(shí)現(xiàn)系統(tǒng)日歷同步日程
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)系統(tǒng)日歷同步日程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04
Android在view.requestFocus(0)返回false的解決辦法
這篇文章主要介紹了Android在view.requestFocus(0)返回false的解決辦法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2016-08-08

