編輯:關於Android編程
之前介紹了Handler、Thread等知識,接下來就開始講一下AsyncTask,他其實就是前兩者封裝而成,方便使用。有一點非常重要,使用AsyncTask一定要把API文檔看清楚,為什麼這麼說,下文重點說到。
AsyncTask 能夠讓你恰當容易地使用UI線程。AsyncTask其實是Android給開發者提供的一個簡單輕量級的多線程類,通過它我們可以很容易新建一個線程做一些耗時的操作,並在這個過程中更新UI。之所以說它輕量級,是因為缺少了直接使用Thread的靈活性。這個類允許執行後台操作,在UI線程上發布的結果而無需操縱線程或Handler。AsyncTask設計出來的目的就是作為Thread和Handler的一個輔助類,並不構成一個通用線程框架。asynctasks應用於短作業(最多幾秒鐘)。如果你需要保持線程運行很長一段時間,那麼強烈建議你使用javaAPIjava.util.concurrent包裡面的類,例如Executor, ThreadPoolExecutor and FutureTask。一個AsyncTask任務由計算運行在後台線程上,其結果發表在UI線程上。它有三種參數類型, Params, Progress and Result和四個步驟:onPreExecute, doInBackground, onProgressUpdate and onPostExecute。
AsyncTask必須使用子類,也就是必須繼承 AsyncTask才能使用它。子類會覆蓋至少一個方法(doInBackground(Params…)),通常將覆蓋第二個(onPostExecute(Result))。
下面看一個例子:
[java]
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
一旦創建,執行一個任務非常簡單:
[java]
new DownloadFilesTask().execute(url1, url2, url3);
new DownloadFilesTask().execute(url1, url2, url3); android的類AsyncTask對線程間通訊進行了包裝,提供了簡易的編程方式來使後台線程和UI線程進行通訊:後台線程執行異步任務,並把操作結果通知UI線程。
AsyncTask是抽象類.AsyncTask定義了三種泛型類型 Params,Progress和Result。
Params 啟動任務執行的輸入參數,比如HTTP請求的URL。
Progress 後台任務執行的百分比。
Result 後台執行任務最終返回的結果,比如String,Integer。
AsyncTask的執行分為四個步驟,每一步都對應一個回調方法,開發者需要實現這些方法。
1) 繼承AsyncTask
2) 實現AsyncTask中定義的下面一個或幾個方法
onPreExecute(), 該方法將在執行實際的後台操作前被UI 線程調用。可以在該方法中做一些准備工作,如在界面上顯示一個進度條,或者一些控件的實例化,這個方法可以不用實現。
doInBackground(Params...), 將在onPreExecute 方法執行後馬上執行,該方法運行在後台線程中。這裡將主要負責執行那些很耗時的後台處理工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。
onProgressUpdate(Progress...),在publishProgress方法被調用後,UI 線程將調用這個方法從而在界面上展示任務的進展情況,例如通過一個進度條進行展示。
onPostExecute(Result), 在doInBackground 執行完成後,onPostExecute 方法將被UI 線程調用,後台的計算結果將通過該方法傳遞到UI 線程,並且在界面上展示給用戶.
onCancelled(),在用戶取消線程操作的時候調用。在主線程中調用onCancelled()的時候調用。
為了正確的使用AsyncTask類,以下是幾條必須遵守的准則:
1) Task的實例必須在UI 線程中創建
2) execute方法必須在UI 線程中調用
3) 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法,需要在UI線程中實例化這個task來調用。
4) 該task只能被執行一次,否則多次調用時將會出現異常
doInBackground方法和onPostExecute的參數必須對應,這兩個參數在AsyncTask聲明的泛型參數列表中指定,第一個為doInBackground接受的參數,第二個為顯示進度的參數,第第三個為doInBackground返回和onPostExecute傳入的參數。閱讀AsyncTask的源碼可知,AsyncTask是使用java.util.concurrent 框架來管理線程以及任務的執行的。
實例
1、一個模擬下載進度條的例子
[java]
package com.example.asynctaskdemo;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class Asy1Activity extends Activity {
Button download;
ProgressBar pb;
TextView tv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.asy1);
pb = (ProgressBar) findViewById(R.id.pb);
tv = (TextView) findViewById(R.id.tv);
download = (Button) findViewById(R.id.download);
download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DownloadTask task=new DownloadTask();
task.execute(100);
}
});
}
class DownloadTask extends AsyncTask<Integer, Integer, String>{
@Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
}
@Override
protected void onPostExecute(String result) {
setTitle(result);
super.onPostExecute(result);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
tv.setText(values[0]+"%");
}
@Override
protected String doInBackground(Integer... params) {
for(int i=0;i<=100;i++){
pb.setProgress(i);
publishProgress(i);
try {
Thread.sleep(params[0]);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "執行完畢";
}
}
}
package com.example.asynctaskdemo;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class Asy1Activity extends Activity {
Button download;
ProgressBar pb;
TextView tv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.asy1);
pb = (ProgressBar) findViewById(R.id.pb);
tv = (TextView) findViewById(R.id.tv);
download = (Button) findViewById(R.id.download);
download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DownloadTask task=new DownloadTask();
task.execute(100);
}
});
}
class DownloadTask extends AsyncTask<Integer, Integer, String>{
@Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
}
@Override
protected void onPostExecute(String result) {
setTitle(result);
super.onPostExecute(result);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
tv.setText(values[0]+"%");
}
@Override
protected String doInBackground(Integer... params) {
for(int i=0;i<=100;i++){
pb.setProgress(i);
publishProgress(i);
try {
Thread.sleep(params[0]);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "執行完畢";
}
}
}
1、一個從網絡下載圖片的例子
[java]
package com.example.asynctaskdemo;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
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.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
public class Asy2Activity extends Activity {
private Button button;
private ProgressBar progressBar;
private ImageView imageView;
private final String imageUrl = "http://avatar.csdn.net/D/1/4/1_wangjinyu501.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.asy2);
initView();
}
private void initView() {
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
AsyncTaskLoadImage asyncTaskLoadImage = new AsyncTaskLoadImage();
asyncTaskLoadImage.execute(imageUrl);
}
});
progressBar = (ProgressBar) findViewById(R.id.pb);
imageView = (ImageView) findViewById(R.id.imageview);
}
class AsyncTaskLoadImage extends AsyncTask<String, Integer, Bitmap> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = null;
try {
URL url = new URL(params[0]);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.connect();
int MAX = urlConnection.getContentLength();
progressBar.setMax(MAX);
InputStream inputStream = urlConnection.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int len = 0;
int processBarNum = 0;
while ((len = inputStream.read(b)) != -1) {
byteArrayOutputStream.write(b, 0, len);
processBarNum += len;
publishProgress(processBarNum);
}
// bitmap = BitmapFactory.decodeStream(inputStream);
bitmap = BitmapFactory.decodeByteArray(
byteArrayOutputStream.toByteArray(), 0, MAX);
inputStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onProgressUpdate(Integer... values) {
progressBar.setProgress(values[0]);
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
super.onPostExecute(result);
}
}
}
前言ImageView是android開發中非常常用的一種控件,在顯示圖片時,我們可以直接拿來用,也可以根據使用場景,結合幾種不同的顯示方式ScaleType,來對顯示的
=============================== 准備 1,導入銀聯支付libs:UPPayAssistEx.jar;UPPayPluginEx.jar;
本章節所有內容皆為原創,如需轉載,請注明出處。http://blog.csdn.net/manoel/article/details/38471825Android是一個
大家看到微信首頁切換效果有沒有覺得很炫,滑動切換,點擊底部bar瞬間切換,滑動切換漸變效果,線上效果圖:之前也在博客上看到別人的實現,再次基礎上,我做了些優化。首先說下實