編輯:Android開發實例
前言
本文將介紹AsyncTask的使用,之前有介紹過線程和進程。而在AsyncTask中,運行在用戶界面中,執行異步操作,並且把執行結果發布在UI線程上,且也不需要處理線程和Handler。在本篇裡,將會講解到AsyncTask的基本介紹,以及如何使用,最後會以一個簡單的Demo講解AsyncTask的使用。
AsyncTask
AsyncTask,異步任務,可以簡單進行異步操作,並把執行結果發布到UI主線程。AsyncTask是一個抽象類,它的內部其實也是結合了Thread和Handler來實現異步線程操作,但是它形成了一個通用線程框架,更清晰簡單。AsyncTask應該被用於比較簡短的操作(最多幾秒鐘)。如果需要保持長時間運行的線程,可以使用ThreadPooExecutor或者FutureTask,關於這兩個類的內容,以後再介紹,本片博客主要介紹AsyncTask。
AsyncTask被定義為一個操作,運行在一個後台線程中,其結果被發布在UI線程上。它的異步工作的參數與返回值被泛型的三個參數指定:Params、Progress、Result。AsyncTask將經歷4個步驟:onPreExecute、doInBackground、onProgressUpdate、onPostExecute。下面詳細講解這三個參數與四個步驟:
三個泛型參數:
一個異步任務將經歷四個階段:
上面介紹的四個步驟的示意圖:
AsyncTask取消任務
在程序的任何位置,都可以通過cancel(boolean)方法進行取消任務,當取消任務之後,會改變isCancelled()的返回值,使其返回true。之後會調用onCancelled(Object)方法,替代onPostExecute()得到doInBackground()的返回結果。在運行中,可以經常通過isCancelled()方法查看任務是否被取消。
AsyncTask的使用規則
使用AsyncTask必須遵循以下規則:
示例
一個簡單的示例,通過AsyncTask下載一個網絡上的圖片,下載的時候展示一個等待框,並顯示在一個ImageView中。
實現代碼:
- package com.bgxt.datatimepickerdemo;
- import org.apache.http.HttpEntity;
- 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.app.Activity;
- import android.app.ProgressDialog;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import android.widget.ImageView;
- public class AsyncTaskActivity1 extends Activity {
- private Button btnDown;
- private ImageView ivImage;
- private static String image_path = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";
- private ProgressDialog dialog;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.asynctask_activity);
- btnDown = (Button) findViewById(R.id.btnDown);
- ivImage = (ImageView) findViewById(R.id.ivSinaImage);
- // 聲明一個等待框以提示用戶等待
- dialog=new ProgressDialog(this);
- dialog.setTitle("提示信息");
- dialog.setMessage("正在下載,請稍後...");
- btnDown.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // 執行一個異步任務,並把圖片地址以參數的形式傳遞進去
- new MyTask().execute(image_path);
- }
- });
- }
- // 以String類型的參數,Void表示沒有進度信息,Bitmap表示異步任務返回一個位圖
- public class MyTask extends AsyncTask<String, Void, Bitmap> {
- // 表示任務執行之前的操作
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- //顯示等待框
- dialog.show();
- }
- //主要是完成耗時操作
- @Override
- protected Bitmap doInBackground(String... params) {
- HttpClient httpClient=new DefaultHttpClient();
- HttpGet httpGet=new HttpGet(params[0]);
- Bitmap bitmap=null;
- try {
- //從網絡上下載圖片
- HttpResponse httpResponse =httpClient.execute(httpGet);
- if(httpResponse.getStatusLine().getStatusCode()==200){
- HttpEntity httpEntity = httpResponse.getEntity();
- byte[] data=EntityUtils.toByteArray(httpEntity);
- bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return bitmap;
- }
- //完成更新UI操作
- @Override
- protected void onPostExecute(Bitmap result) {
- // TODO Auto-generated method stub
- super.onPostExecute(result);
- //設置ImageView的顯示圖片
- ivImage.setImageBitmap(result);
- // 銷毀等待框
- dialog.dismiss();
- }
- }
- }
效果展示:
上面的Demo並沒有用到進度的信息,下面在提供一個完整的AsyncTask的Demo,同樣是下載一個圖片,並且展示到一個ImageView中,但是這裡在下載的過程中增加一個進度條對話框,用於展示下載的進度。
實現代碼:
- package com.bgxt.datatimepickerdemo;
- 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 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.view.View;
- import android.widget.Button;
- import android.widget.ImageView;
- public class AsyncTaskActivity2 extends Activity {
- private Button btnDown;
- private ImageView ivImage;
- private static String image_path = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";
- private ProgressDialog dialog;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.asynctask_activity);
- btnDown = (Button) findViewById(R.id.btnDown);
- ivImage = (ImageView) findViewById(R.id.ivSinaImage);
- dialog = new ProgressDialog(this);
- dialog.setTitle("提示");
- dialog.setMessage("正在下載,請稍後...");
- dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- dialog.setCancelable(false);
- btnDown.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // 執行異步任務
- new MyTask().execute(image_path);
- }
- });
- }
- public class MyTask extends AsyncTask<String, Integer, Bitmap> {
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- dialog.show();
- }
- @Override
- protected void onProgressUpdate(Integer... values) {
- super.onProgressUpdate(values);
- // 設置進度對話框的進度值
- dialog.setProgress(values[0]);
- }
- @Override
- protected void onPostExecute(Bitmap result) {
- super.onPostExecute(result);
- dialog.dismiss();
- ivImage.setImageBitmap(result);
- }
- @Override
- protected Bitmap doInBackground(String... params) {
- Bitmap bitmap = null;
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- InputStream inputStream = null;
- try {
- HttpClient httpClient = new DefaultHttpClient();
- HttpGet httpGet = new HttpGet(params[0]);
- HttpResponse httpResponse = httpClient.execute(httpGet);
- if (httpResponse.getStatusLine().getStatusCode() == 200) {
- inputStream = httpResponse.getEntity().getContent();
- long file_length = httpResponse.getEntity()
- .getContentLength();
- int len = 0;
- byte[] data = new byte[1024];
- int total_length = 0;
- // 以字節的方式讀取圖片數據
- while ((len = inputStream.read(data)) != -1) {
- total_length += len;
- // 計算進度
- int values = (int) ((total_length / (float) file_length) * 100);
- // 發布進度信息
- publishProgress(values);
- outputStream.write(data, 0, len);
- }
- byte[] result=outputStream.toByteArray();
- bitmap=BitmapFactory.decodeByteArray(result, 0, result.length);
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (Exception e2) {
- }
- }
- return bitmap;
- }
- }
- }
實現效果:
源碼下載
前面walfred已經介紹了使用apktool對apk進行逆向編譯,通過apktool我們的確可以反編譯已經序列化後的AndroidManifest.xml和資源
本文主要講解利用android中Matrix控制圖形的旋轉縮放移動,具體參見一下代碼:代碼如下:/** * 使用矩陣控制圖片移動、縮放、旋轉 &nbs
hello,大家好,本文主要介紹如何開始開發一個美觀、有情調、人見人愛的Android應用程序,已知我們在市面上有不少布局極其精美,在視覺上讓人愛不釋手的應用程序
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩