原文地址
http://bbs.isgphone.com/viewthread.php?tid=5455
請支持原創
上次我們講到了Android提供了一個較線程更簡單的處理多任務的方法AsyncTask異步任務類,相對於線程來說AsyncTask對於簡單的任務處理更安全,其內部的實現方法使用了Android的Handler機制,對於常見的文件下載可以使用AsyncTask類來處理,在Browser瀏覽器中就是用了該類下載Web服務器URL的Favicon圖標。
首先Android123以簡單的下載例子演示該類的大致結構,如下
- private class DownloadFilesTask extends AsyncTask {
- 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));
- }
- return totalSize;
- }
- protected void onProgressUpdate(Integer... progress) {
- setProgressPercent(progress[0]);
- }
- protected void onPostExecute(Long result) {
- showDialog("Downloaded " + result + " bytes");
- }
- }
最終我們執行 DownloadFilesTask().execute(url1, url2, url3); 即可。
在Android瀏覽器中下載Favicon圖標的實現如下:
- class DownloadTouchIcon extends AsyncTask {
- private final ContentResolver mContentResolver;
- private final Cursor mCursor;
- private final String mOriginalUrl;
- private final String mUrl;
- private final String mUserAgent;
- /* package */ BrowserActivity mActivity;
- public DownloadTouchIcon(BrowserActivity activity, ContentResolver cr,
- Cursor c, WebView view) { //構造方法
- mActivity = activity;
- mContentResolver = cr;
- mCursor = c;
- mOriginalUrl = view.getOriginalUrl();
- mUrl = view.getUrl();
- mUserAgent = view.getSettings().getUserAgentString();
- }
- public DownloadTouchIcon(ContentResolver cr, Cursor c, String url) { //實現本類的構造
- mActivity = null;
- mContentResolver = cr;
- mCursor = c;
- mOriginalUrl = null;
- mUrl = url;
- mUserAgent = null;
- }
- @Override
- public Bitmap doInBackground(String... values) { //返回Bitmap類型
- String url = values[0];
- AndroidHttpClient client = AndroidHttpClient.newInstance(mUserAgent);
- HttpGet request = new HttpGet(url);
- HttpClientParams.setRedirecting(client.getParams(), true); //處理302等重定向問題
- try {
- HttpResponse response = client.execute(request);
- if (response.getStatusLine().getStatusCode() == 200) { //如果OK
- HttpEntity entity = response.getEntity();
- if (entity != null) {
- InputStream content = entity.getContent(); //將圖標保存到InputStream中,因爲是二進制內容
- if (content != null) {
- Bitmap icon = BitmapFactory.decodeStream( //從流中取出Bitmap,這裏使用了BitmapFactory類的靜態方法decodeStream
- content, null, null);
- return icon;
- }
- }
- }
- } catch (IllegalArgumentException ex) {
- request.abort();
- } catch (IOException ex) {
- request.abort();
- } finally {
- client.close();
- }
- return null;
- }
- @Override
- protected void onCancelled() {
- if (mCursor != null) {
- mCursor.close();
- }
- }
- @Override
- public void onPostExecute(Bitmap icon) {
- if (mActivity != null) {
- mActivity.mTouchIconLoader = null;
- }
- if (icon == null || mCursor == null || isCancelled()) {
- return;
- }
最終圖標要保存到瀏覽器的內部數據庫中,系統程序均保存爲SQLite格式,Browser也不例外,因爲圖片是二進制的所以使用字節數組存儲數據庫的BLOB類型
- final ByteArrayOutputStream os = new ByteArrayOutputStream();
- icon.compress(Bitmap.CompressFormat.PNG, 100, os); //將Bitmap壓縮成PNG編碼,質量爲100%存儲
- ContentValues values = new ContentValues(); //構造SQLite的Content對象,這裏也可以使用raw sql代替
- values.put(Browser.BookmarkColumns.TOUCH_ICON,os.toByteArray()); //寫入數據庫的Browser.BookmarkColumns.TOUCH_ICON字段
- if (mCursor.moveToFirst()) {
- do {
- mContentResolver.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI, mCursor.getInt(0)),values, null, null);
- } while (mCursor.moveToNext());
- }
- mCursor.close();
- }
- }
本次Android開發網通過兩個AsyncTask類演示了多種類型的任務構造,這裏大家注意返回類型,本節演示了Android平臺上Content Provider、AsyncTask、Bitmap、HTTP以及Stream的相關操作,大家如何想很快提高開發水平其實只要理解Google如何去實現Android系統常規構架就可以輕鬆入門谷歌移動平臺。