編輯:關於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
一般使用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
Xamarin android如何調用百度地圖入門示例(一)
在Xamarin android如何調用百度地圖呢?首先我們要區分清楚,百度地圖這是一個廣泛的概念,很多剛剛接觸這個名詞”百度地圖api”,的確是
Android procrank查看內存使用情況
使用adb shell procrank手機中的sh是經過精簡過的,有些手機可能沒有 procrank 命令,可以使用genymotion模擬器,或是自己安裝procra
Android MVP開發模式詳解(十九)
(一).前言:今天我們的項目繼續更新,今天我們主要講解MVP開發模式以及具體實例。 (二).簡介:MVP(Model ViewPrese
Android 訪問文件權限的四種模式介紹
Linux文件的訪問權限* 在Android中,每一個應用是一個獨立的用戶* drwxrwxrwx* 第1位:d表示文件夾,-表示文件* 第2-4位:rwx,表示這個文件