編輯:關於Android編程
AsyncQueryHandler簡介:
異步的查詢操作幫助類,可以處理增刪改(ContentProvider提供的數據)
使用場景:
在一般的應用中可以使用ContentProvider去操作mysql" target="_blank" title="MySQL知識庫">數據庫。
這在數據量很小的時候是沒有問題的,但是如果數據量大了,可能導致UI線程發生ANR異常(超過5秒)。
當然你也可以寫個Handler去做這些操作,只是你每次使用ContentProvider時都要再寫個Handler,必然降低了效率。
因此當數據量較大時,最好還是使用Android已經封裝好的異步查詢框架AsyncQueryHandler,優化我們的代碼.
要注意的是,一般在查詢本地的應用的數據的時候要去采用CursorAdapter。
AsyncQueryHandler內部實現
AsyncQueryHandler類封裝了調用者線程與工作線程的交互過程。交互的主體是兩個Handler,一個運行在調用者線程中,一個運行在工作者線程中。通過提供onXXXComplete的回調接口,實現事件的完成處理。
API中提供
startInsert,
startDelete,
startUpdate,
startQuery四種方法,並有響應的onXXXComplete()方法.於對應的4個onXXXComplete()方法都是空實現,因此我們完成相應調用後進行後續其他的操作.
使用方法
繼承AsyncQueryHandler類,並提供onXXXComplete方法的實現(可以實現任何一個或多個,當然你也可以一個也不實現,如果你不關注操作數據庫的結果),在你的實現中做一些對數據庫操作完成的處理。
使用時直接調用startXXX方法即可。傳入的通用參數如下:
token,一個令牌,主要用來標識查詢,保證唯一即可.需要跟onXXXComplete方法傳入的一致。(當然你也可以不一致,同樣在數據庫的操作結束後會調用對應的onXXXComplete方法)。當你使用很多次查詢的時候,這個值就相當於綁定了你的查詢方法。
cookie,你想傳給onXXXComplete方法使用的一個對象。(沒有的話傳遞null即可)
Uri uri(進行查詢的通用資源標志符):
projection 查詢的列
selection 限制條件
selectionArgs 查詢參數
orderBy 排序條件
下面簡單介紹一下查詢操作,如果查詢操作熟悉了,其他的也就迎刃而解了。
例如,我要查詢一下我手機裡面有多少視頻文件,以及對應的視頻文件的名稱、視頻占用內存、視頻時長,以及路徑。按照以往的方式,我們會這麼寫:
ListvideoDatas = new ArrayList (); /*//參數:url、查詢哪些列、選擇條件占位符、選擇條件占位符?用什麼替換、查詢後排序方式 Cursor cursor = context.getContentResolver().query(Media.EXTERNAL_CONTENT_URI, new String[]{Media.TITLE,//視頻名稱 Media.SIZE,Media.DURATION,Media.DATA},//大小、時長、視頻路徑 null, null, null); while(cursor.moveToNext()){ VideoInfo videoInfo = new VideoInfo(); String title = cursor.getString(cursor.getColumnIndex(Media.TITLE)); int size = cursor.getInt(cursor.getColumnIndex(Media.SIZE)); int duration = cursor.getInt(cursor.getColumnIndex(Media.DURATION)); String path = cursor.getString(cursor.getColumnIndex(Media.DATA));; videoInfo.setDuration(duration); videoInfo.setPath(path); videoInfo.setSize(size); videoInfo.setTitle(title); videoDatas.add(videoInfo); }
new Thread(new Runnable() { @Override public void run() { // 獲取數據 videDatas = MediaInfoEngine.getVideoInfo(UIUtils.getContext()); UIUtils.runOnUiThread(new Runnable() { @Override public void run() { adapter.notifyDataSetChanged(); } }); } }).start();這樣就獲取到了手機所有視頻文件信息了。但是,如果你手機裡有1萬條視頻文件,這個時候,即使使用這種方式,估計上邊業報ANR了。這個時候,AsyncQueryHandler幫我們解決很多問題,因為它已經自動幫我們封裝了子線程。提供子線程DB操作,然後回調到主線程UI操作。寫法如下:
AsyncQueryHandler queryHandler = new AsyncQueryHandler(context.getContentResolver()) { /**查詢的響應回調*/ @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { if(token == 1){ while(cursor.moveToNext()){ VideoInfo videoInfo = new VideoInfo(); String title = cursor.getString(cursor.getColumnIndex(Media.TITLE)); int size = cursor.getInt(cursor.getColumnIndex(Media.SIZE)); int duration = cursor.getInt(cursor.getColumnIndex(Media.DURATION)); String path = cursor.getString(cursor.getColumnIndex(Media.DATA));; videoInfo.setDuration(duration); videoInfo.setPath(path); videoInfo.setSize(size); videoInfo.setTitle(title); videoDatas.add(videoInfo); } } } }; /**啟動異步查詢*/ //參數一:請求碼 queryHandler.startQuery(1, null, Media.EXTERNAL_CONTENT_URI, new String[]{Media.TITLE,//視頻名稱 Media.SIZE,Media.DURATION,Media.DATA},//大小、時長、視頻路徑 null, null, null);具體的參數,在開篇就介紹的很詳細了。簡單說一下如何操作的:首先執行開始查詢操作startQuary(),這個方法給我們封裝好了,是在子線程執行的,在它內部自定查詢完畢後會生成一個curssor對象,回調內部類裡面的onQueryComplete方法,這個方法的三個參數分別是:1:請求碼(可以想一下intent隱式啟動的那個請求碼的意思)2:執行startQuary()時候,第二參數。一般傳入null,但是有時候會是某個對象(場景:AsyncQueryHandler與CursorAdapter結合使用的時候,這裡就可以傳入一個curssorAdapter對象,在回到方法裡面就可以接收這個對象。回想message的obj字段)3:startQuary()方法查詢數據庫後所有返回的結果游標。接下來就很簡單了,遍歷cursor保存數據即可了。
這個時候,我們獲取數據的時候,也就不用自己開啟線程了。直接獲取即可,如下:
// 獲取數據,不用再開啟你子線程了 videDatas = MediaInfoEngine.getVideoInfo(UIUtils.getContext()); adapter.notifyDataSetChanged();這裡我沒有用到CursorAdapter,因為實際開發中,也沒怎麼用到這個適配器。後續博客會再對這個適配器做詳細的介紹。
看來只有礼拜天才有時間寫點博客啊,平時只能埋頭苦干了。今天在公司加班,遇到一個需求,就是自動換行的TextView,有點像網頁的tag標簽,點擊一下,就自動
概念應用的開發離不開存儲,存儲分為網絡、內存、SDCard文件存儲以及外部SDCard2文件存儲,開發中一定要注意好內存管理以免oom、卡頓等不好的用戶體驗,同時還要注意
由於項目裡用到了百度地圖,路線規劃的標題(比如“M235/362”)在百度地圖API裡面沒有給出來,網上各種搜索都找不到別人發出來的方案,然後就只
本文我主要通過查看Activity的實現源碼和推測其設計思想的方法來探討一下Android的本質是什麼。 Activity恐怖是Android用得最多且是最基本的組