Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android AsyncTask 詳解及注意事項

Android AsyncTask 詳解及注意事項

編輯:關於Android編程

AsyncTask是Android提供的輕量級的異步類,它使創建異步任務變得更加簡單,不再需要編寫任務線程和Handler實例即可完成相同的任務。

AsyncTask定義了三種泛型類型 Params,Progress和Result。

Params 啟動任務執行的輸入參數,比如HTTP請求的URL。 Progress 後台任務執行的百分比。 Result 後台執行任務最終返回的結果,比如String。
例如:
class RetrieveCategoryTask extends AsyncTask>

根據AsyncTask源碼:

public abstract class AsyncTask 

這裡的String, Void, List分別對應Params, Progress, Result

一般使用AsyncTask至少需要實現以下2個方法:
protected abstract Result doInBackground(Params... var1);//耗時操作,例如網絡請求任務。這裡相當於一個子線程
   protected void onPostExecute(Result result) {//可以在這裡處理doInBackground得到的數據,能夠對UI進行操作,屬於UI主線程
        throw new RuntimeException("Stub!");
    }

當然如果有必要的話還可以實現下面幾個方法:

onProgressUpdate(Progress…) 可以使用進度條增加用戶體驗度。 此方法在主線程執行,用於顯示任務執行的進度。 onPreExecute() 這裡是最終用戶調用Excute時的接口,當任務執行之前開始調用此方法,可以在這裡顯示進度對話框。 onCancelled() 用戶調用取消時,會調用此方法

使用AsyncTask類,以下是幾條必須遵守的准則:

Task的實例必須在UI thread中創建; execute方法必須在UI thread中調用; 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法; 該task只能被執行一次,否則多次調用時將會出現異常;

 

需要注意的是Android為了安全考慮,不允許在主線程即UI線程進行耗時操作。例如HTTP請求等。

如果在UI中使用了耗時操作的話,Android Studio本身是不會報錯的。只有在APP執行到相應的耗時操作位置時才會停止運行。手機或模擬器上會出現“很抱歉,XXX已停止運行”同時Android Studio logcat輸出“

E/AndroidRuntime: FATAL EXCEPTION: main
Process:.....

java.lang.RuntimeException.....

下面給出一個范例:

  1 package idv.ron.texttojson_android;
  2 
  3 import android.app.ProgressDialog;
  4 import android.content.Context;
  5 import android.net.ConnectivityManager;
  6 import android.net.NetworkInfo;
  7 import android.os.AsyncTask;
  8 import android.os.Bundle;
  9 import android.support.v7.app.ActionBarActivity;
 10 import android.util.Log;
 11 import android.view.LayoutInflater;
 12 import android.view.View;
 13 import android.view.ViewGroup;
 14 import android.widget.AdapterView;
 15 import android.widget.AdapterView.OnItemClickListener;
 16 import android.widget.ArrayAdapter;
 17 import android.widget.BaseAdapter;
 18 import android.widget.ListView;
 19 import android.widget.Spinner;
 20 import android.widget.TextView;
 21 import android.widget.Toast;
 22 
 23 import com.google.gson.Gson;
 24 import com.google.gson.JsonObject;
 25 import com.google.gson.reflect.TypeToken;
 26 
 27 import java.io.BufferedReader;
 28 import java.io.BufferedWriter;
 29 import java.io.IOException;
 30 import java.io.InputStreamReader;
 31 import java.io.OutputStreamWriter;
 32 import java.lang.reflect.Type;
 33 import java.net.HttpURLConnection;
 34 import java.net.URL;
 35 import java.util.List;
 36 
 37 public class SearchActivity extends ActionBarActivity {
 38     private final static String TAG = "SearchActivity";
 39     private ProgressDialog progressDialog;
 40     private AsyncTask retrieveCategoryTask, retrieveBookTask;
 41     private Spinner spCategory;
 42     private ListView lvBook;
 43 
 44     class RetrieveCategoryTask extends AsyncTask> {
 45         @Override
 46         protected void onPreExecute() {
 47             super.onPreExecute();
 48             progressDialog = new ProgressDialog(SearchActivity.this);
 49             progressDialog.setMessage("Loading...");
 50             progressDialog.show();
 51         }
 52 
 53         @Override
 54         protected List doInBackground(String... params) {
 55             String url = params[0];
 56             String jsonIn;
 57             JsonObject jsonObject = new JsonObject();
 58             jsonObject.addProperty("param", "category");
 59             try {
 60                 jsonIn = getRemoteData(url, jsonObject.toString());
 61             } catch (IOException e) {
 62                 Log.e(TAG, e.toString());
 63                 return null;
 64             }
 65 
 66             Gson gson = new Gson();
 67             Type listType = new TypeToken>() {
 68             }.getType();
 69 
 70             return gson.fromJson(jsonIn, listType);
 71         }
 72 
 73         @Override
 74         protected void onPostExecute(List items) {
 75             ArrayAdapter adapter = new ArrayAdapter<>(SearchActivity.this,
 76                     android.R.layout.simple_list_item_1, items);
 77             adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 78             spCategory.setAdapter(adapter);
 79             progressDialog.cancel();
 80         }
 81     }
 82 
 83     public class RetrieveBookTask extends
 84             AsyncTask> {
 85         @Override
 86         protected void onPreExecute() {
 87             super.onPreExecute();
 88             progressDialog = new ProgressDialog(SearchActivity.this);
 89             progressDialog.setMessage("Loading...");
 90             progressDialog.show();
 91         }
 92 
 93         @Override
 94         protected List doInBackground(String... params) {
 95             String url = params[0];
 96             String category = params[1];
 97             String jsonIn;
 98             JsonObject jsonObject = new JsonObject();
 99             jsonObject.addProperty("param", category);
100             try {
101                 jsonIn = getRemoteData(url, jsonObject.toString());
102             } catch (IOException e) {
103                 Log.e(TAG, e.toString());
104                 return null;
105             }
106 
107             Gson gson = new Gson();
108             Type listType = new TypeToken>() {
109             }.getType();
110             return gson.fromJson(jsonIn, listType);
111         }
112 
113         @Override
114         protected void onPostExecute(List result) {
115             showResult(result);
116             progressDialog.cancel();
117         }
118     }
119 
120     @Override
121     protected void onCreate(Bundle savedInstanceState) {
122         super.onCreate(savedInstanceState);
123         setContentView(R.layout.search_activity);
124         spCategory = (Spinner) findViewById(R.id.spCategory);
125         lvBook = (ListView) findViewById(R.id.lvBook);
126         if (networkConnected()) {
127             retrieveCategoryTask = new RetrieveCategoryTask().execute(Common.URL);
128         } else {
129             showToast(this, R.string.msg_NoNetwork);
130         }
131     }
132 
133     // check if the device connect to the network
134     private boolean networkConnected() {
135         ConnectivityManager conManager =
136                 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
137         NetworkInfo networkInfo = conManager.getActiveNetworkInfo();
138         return networkInfo != null && networkInfo.isConnected();
139     }
140 
141 
142     private String getRemoteData(String url, String jsonOut) throws IOException {
143         StringBuilder jsonIn = new StringBuilder();
144         HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
145         connection.setDoInput(true); // allow inputs
146         connection.setDoOutput(true); // allow outputs
147         connection.setUseCaches(false); // do not use a cached copy
148         connection.setRequestMethod("POST");
149         connection.setRequestProperty("charset", "UTF-8");
150         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
151         bw.write(jsonOut);
152         Log.d(TAG, "jsonOut: " + jsonOut);
153         bw.close();
154 
155         int responseCode = connection.getResponseCode();
156 
157         if (responseCode == 200) {
158             BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
159             String line;
160             while ((line = br.readLine()) != null) {
161                 jsonIn.append(line);
162             }
163         } else {
164             Log.d(TAG, "response code: " + responseCode);
165         }
166         connection.disconnect();
167         Log.d(TAG, "jsonIn: " + jsonIn);
168         return jsonIn.toString();
169     }
170 
171     public void onSearchClick(View v) {
172         Object item = spCategory.getSelectedItem();
173         if (item == null || item.toString().trim().length() <= 0) {
174             showToast(this, R.string.msg_NoCategoryFound);
175         } else {
176             String category = item.toString().trim();
177             if (networkConnected()) {
178                 retrieveBookTask = new RetrieveBookTask().execute(Common.URL, category);
179             } else {
180                 showToast(this, R.string.msg_NoNetwork);
181             }
182         }
183     }
184 
185     public void showResult(List result) {
186         final BookListAdapter adapter = new BookListAdapter(this, result);
187         lvBook.setAdapter(adapter);
188         lvBook.setOnItemClickListener(new OnItemClickListener() {
189             @Override
190             public void onItemClick(AdapterView parent, View view,
191                                     int position, long id) {
192                 adapter.expand(position);
193                 lvBook.setItemChecked(position, true);
194             }
195         });
196     }
197 
198     private class BookListAdapter extends BaseAdapter {
199         private LayoutInflater layoutInflater;
200         private List bookList;
201         private boolean[] bookDetailExpanded;
202 
203         public BookListAdapter(Context context, List bookList) {
204             this.layoutInflater = LayoutInflater.from(context);
205             this.bookList = bookList;
206             this.bookDetailExpanded = new boolean[bookList.size()];
207         }
208 
209         @Override
210         public int getCount() {
211             return bookList.size();
212         }
213 
214         @Override
215         public Object getItem(int position) {
216             return bookList.get(position);
217         }
218 
219         @Override
220         public long getItemId(int position) {
221             return bookList.get(position).getId();
222         }
223 
224         @Override
225         public View getView(int position, View convertView, ViewGroup parent) {
226             if (convertView == null) {
227                 convertView = layoutInflater.inflate(
228                         R.layout.book_listview_item, parent, false);
229             }
230             TextView tvBookTitle = (TextView) convertView
231                     .findViewById(R.id.tvBookTitle);
232             TextView tvBookDetail = (TextView) convertView
233                     .findViewById(R.id.tvBookDetail);
234             Book book = bookList.get(position);
235 
236             tvBookTitle.setText(book.getName() + "  $" + book.getPrice());
237             tvBookDetail.setText("Author: " + book.getAuthor() + "  Type: "
238                     + book.getType());
239             tvBookDetail
240                     .setVisibility(bookDetailExpanded[position] ? View.VISIBLE
241                             : View.GONE);
242             return convertView;
243         }
244 
245         public void expand(int position) {
246             // 被點擊的資料列才會彈出內容,其他資料列的內容會自動縮起來
247             // for (int i=0; i

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved