1. 程式人生 > >安卓CursorLoader引發死迴圈程式的探究

安卓CursorLoader引發死迴圈程式的探究

在探究之前,需要確認下CursorLoader和ContentProvider的基本流程,以便於提供有力的理論支援,這次死迴圈呼叫

消耗時間比較久,根本原因是沒有搞清楚CursorLoader和ContentProvider的結合過程

1.建立cursorLoader

@Override public Loader<Cursor> onCreateLoader(int loaderID, Bundle arg1) {  //建立一個cursorLoader,確定了當收到變化通知時,如何進行 query

//cursorLoader第一次載入時,會觸發查詢,查詢會觸發觀察者的註冊過程 }

@Override public void onLoadFinished(Loader<Cursor> loader, Cursor returnCursor)

//當查詢完成,會窒息onLoadFinished

2.

try {     cursor = db.query(tableName, projection, finalSelection, selectionArgs,                   null, null, sortOrder); } catch (Exception e) {     e.printStackTrace(); }

if (cursor != null) {

//實際是註冊觀察者,監聽範圍是 DBAuthority.DB_AUTHORITY_URI)

//根據實踐認為,如果沒有cursorLoader存在,這個註冊是無效的     cursor.setNotificationUri(getContext().getContentResolver(), DBAuthority.DB_AUTHORITY_URI); }

3.內容傳送變更通知觀察者

SQLiteDatabase db = mDbHelper.get().getWritableDatabase(); String tableName = getUriMatcher().getTableName(match); int affectedRows = 0; try {    B: affectedRows = db.update(tableName, values,    selection, selectionArgs); } catch (Exception e) {     e.printStackTrace(); }

A:getContext().getContentResolver().notifyChange(uri, null);

A的含義是通知所有觀察者,uri對應的內容發生變化了,注意,根據實踐測試,請不要認為只有監控這個uri的觀察者才能收到

4.迴圈問題分析:

cursorLoader首次載入---重新整理介面---item從本地資料庫獲取資訊失敗---item 請求網路成功(但是沒有item需要的資料)---修改資料庫---觸發第一步的cuerLoader變化‘

5.迴圈解決方案:

item請求網路的原因是item從本地獲取資訊失敗,所以請求網路。

我們控制網路請求只能進行一次,避免反覆請求

其他問題:資料庫操作慢是因為介面沒有增量返回,導致大量資料庫操作,佔用了執行緒池,可以在contentProvider相關操作打日誌觀察的到