2016-01-01 47 views
1

SimpleCursorAdaptor已棄用。我發現它不適合我,因爲它使用UI線程,我將顯示幾百條記錄。我想使用一些使用後臺線程的東西。經過一番研究,我遇到了CursorLoader。我一直在看教程,但我發現實現起來非常棘手。如果CursorLoader有更好的選擇,請告訴我。請有人幫助我。我到目前爲止的代碼。是:用於在ListView中顯示SQLite記錄的SimpleCursorAdaptor替代方法

public void getListFromDb(){ 
    Cursor res = myDb.ViewAll(); 
    startManagingCursor(res); 


    //Map cursor from db to viewFields 
    String[] fromFieldNames = new String[]{DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4, DatabaseHelper.COL_5}; 
    int[] toViewIDS = new int[]{R.id.viewName, R.id.viewAddress, R.id.viewPostcode, R.id.viewType}; 

    //Create adaptor to map items from DB to UI 
    SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter(this, R.id.item_layout, res, fromFieldNames, toViewIDS); 

    // Set adaptor for listView 
    ListView myList = (ListView) findViewById(R.id.listViewLocations); 
    myList.setAdapter(myCursorAdaptor); 

} 
+0

你使用ContentProvider的?CursorLoader與ContentProvider一起作爲數據源。如果你不這樣做,你仍然可以使用[CursorAdapter](http://developer.android.com/intl/pt-br/reference/android/widget/CursorAdapter.html),我認爲這不會被棄用。 – AdamMc331

+0

我該如何使用CursorAdaptor。我試着改變SimpleCursorAdaptor,它給了我一個錯誤,說'CursorAdaptor是抽象的,不能實例化' – Ali

+0

你必須「擴展」CursorAdaptor,實現抽象方法..這就是你所得到的錯誤的意思。通常你會這樣做,如果你想要某種特殊的行爲.. –

回答

1

其實只有一個SimpleCursorAdapter構造函數被depricated,而不是整個類。您仍然可以使用它,但是您必須使用「標準」構造函數,它需要「flags」參數的值。

public void getListFromDb(){ 
    Cursor res = myDb.ViewAll(); 
    startManagingCursor(res); 


    //Map cursor from db to viewFields 
    String[] fromFieldNames = new String[]{DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4, DatabaseHelper.COL_5}; 
    int[] toViewIDS = new int[]{R.id.viewName, R.id.viewAddress, R.id.viewPostcode, R.id.viewType}; 

    //Create adaptor to map items from DB to UI 
    // *** ADD THE FLAGS PARAMETER *** 
    SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter(this, R.id.item_layout, res, fromFieldNames, toViewIDS, FLAG_AUTO_REQUERY); 

    // Set adaptor for listView 
    ListView myList = (ListView) findViewById(R.id.listViewLocations); 
    myList.setAdapter(myCursorAdaptor); 

} 

我已經添加了「FLAG_AUTO_REQUERY」做出改變很明顯,但我懷疑你可能需要使用值「0」(無標誌),除非你的數據在顯示時改變。

重新閱讀您的問題所以後(對不起,是我不好,我真的應該閱讀更仔細地:-P)你真正的問題是如何加載在後臺線程中的數據。有很多方法可以做到這一點,都有好的和不好的一面。

這個經典Android問題有兩個部分: 1:實際上將數據加載到後臺線程並將結果交給UI線程顯示。 2:通常由旋轉引起的生存活動破壞/恢復(但可能是由於接到電話時無法控制的原因造成的)。

CursorLoaders是笨拙的和實行但實際上解決這兩個問題非常好..

AsyncTasks將處理後臺執行,並將結果傳遞到UI線程,工作好,如果你不關心的問題2 ,但是在android中有一個令人討厭的小問題,可能會導致一次只運行一個AsyncTask(如果要並行執行大量工作,則效果並不理想)。

還有一些可以用來做這種像rxJava和奧托的其他工作框架,但它們需要相當大的努力來成爲舒適與最初(雖然可以說是值得的)。

如果你需要擔心你的應用的旋轉和/或中斷我會建議CursorLoaders可能是最初最簡單的,但僅限於簡單的應用。如果您的應用程序將變得複雜,請花些時間查看rxJava或Otto。

希望這會有所幫助。 P.S.簡單的AsyncTask基於例子(沒有測試過,因爲我不把所有的源/資源,但你的想法。)

public void getListFromDb(){ 

     //Map cursor from db to viewFields 
     String[] fromFieldNames = new String[]{DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4, DatabaseHelper.COL_5}; 
     int[] toViewIDS = new int[]{R.id.viewName, R.id.viewAddress, R.id.viewPostcode, R.id.viewType}; 


     // Notice I am passing null as the cursor.. 
     SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter(this, R.id.item_layout, null, fromFieldNames, toViewIDS, 0); 
     // Set adaptor for listView 
     ListView myList = (ListView) findViewById(R.id.listViewLocations); 
     myList.setAdapter(myCursorAdaptor); 

     new AsyncTask<SimpleCursorAdapter, Void, Cursor>() { 
      private SimpleCursorAdapter mSimpleCursorAdapter; 
      @Override 
      protected Cursor doInBackground(SimpleCursorAdapter... params) { 
       // Save cursorAdapter to use in postExecute 
       this.mSimpleCursorAdapter = params[0]; 
       // Load cursor on background thread 
       return myDb.ViewAll(); 
      } 

      @Override 
      protected void onPostExecute(Cursor cursor) { 
       super.onPostExecute(cursor); 
       // and update the cursor (which is already in the listview) 
       this.mSimpleCursorAdapter.changeCursor(cursor); 
      } 
     }.execute(myCursorAdaptor); 

    } 

主要的「貓膩」它是我最初創建一個的simplecursoradapter空遊標;這允許我在沒有數據的情況下在屏幕上獲得列表。然後,我啓動一個AsyncTask,將cursoradapter傳遞給它並讓它將光標加載到後臺線程上。然後我在適配器上調用「changeCursor」,它應該用加載的數據更新列表視圖。你也可以使用onPreExecute顯示忙「微調」並隱藏onPostExecute繁忙的「微調」 ..只是爲了讓用戶知道你正在做的事情。呵呵,以防萬一你錯過了它; onPreExecute和onPostExecute在UI線程上運行,因此可以更新UI,doInBackground運行在後臺線程..

+0

這是使用後臺線程?另外我的應用程序在試圖運行時會一直崩潰。 – Ali

+0

不用擔心。但是,你能告訴我如何使用我提供的代碼實際實現一個CursorLoader嗎? – Ali

+0

嗯;這是相當多的工作,並已有相當多的教程。我可以將一個AsyncTask示例放在一起(代碼少一點).. –

相關問題