2011-06-23 40 views
0

我有一個ListView,我需要使用後臺線程填充。該列表需要在每個項目被檢索時更新。下面是我如何實現這個的一個非常簡單的例子。AsyncTask訪問Sqlite數據庫導致崩潰

public class DownloadTask extends AsyncTask <MyUserObject, Integer, String> 
    { 
    @Override 
    protected MyUserObject doInBackground(MyUserObject... myUserObj) 
    { 
     MyUserObject muo = null; 
     int nCount = myUserObj.length; 
     if(nCount > 0) 
      muo = myUserObj[0]; 

     muo.DownloadStuff(); 
     return muo.getUserName(); 
    } 

    protected void onPostExecute(String userName) 
    { 
     adapter.names.add(userName); 
     adapter.notifyDataSetChanged(); 
    } 
} 

public class MyAdapterClass extends BaseAdapter 
{ 
    private ArrayList<String>names; 

    public MyAdapterClass(Context context) 
    { 
     names = new ArrayList<String>(); 
    } 

    public fillList() 
    { 
     for(int i=0; i<users.length; i++) 
     { 
      DownloadTask task = new DownloadTask(); 
      task.execute(users[i]); 
     } 
    } 

在上述例子中,「適配器」是類型MyAdapterClass的目的,並且其fillList()方法是什麼啓動線程。在onPostExecute()中調用notifyDataSetChanged()會在數據到達時更新我的​​ListView。

問題是,我正在訪問我在'doStackackground'中調用的DownloadStuff()中的sqlite數據庫,並且有多個線程訪問數據庫導致它崩潰(如果我註釋掉所有數據庫活動在這裏,那麼它運行良好),下面是我如何努力,以解決這一問題,但它仍然崩潰。作爲數據從後臺線程檢索到的我怎麼能有我的ListView更新有什麼建議?

Semaphore semaphore = new Semaphore(1, true); 

public synchronized void DownloadStuff() 
{ 
    semaphore.acquire(1); 
    // ... DB operations ... // 
    semaphore.release(1); 
} 

回答

1

我爲什麼你想爲每個你必須添加到你的適配器的項目單獨啓動AsyncTask,使用onProgressUpdate來通知gui新適配器中的項目。在這種情況下,你想要併發訪問你的數據庫。

+0

它確實如果你能集中你的異步工作到一個更好的(並會避免同步問題^^ –

+0

謝謝你,我不喜歡多個線程或錯過了進展更新,這工作! –

+0

我的新關注AsyncTask永遠不會被銷燬,即使Activity被銷燬也是如此憤怒,東西告訴我,我不應該使用AsyncTask:s –

0

我不確定(因爲我真的很累),但我認爲你的ot使用你同步正確。

您每次執行異步任務時都會創建MyUserObject的不同實例,這意味着您絕對不會在同一個實例上調用Downloadstuff,因此不會產生衝突,但另一方面,您的數據庫是唯一被多個MyUserObject調用的,因此會發生衝突。

你想要做的就是在你所有的異步任務中都有相同的muo實例,這樣他們都在相同的實例上調用downloadstuff,然後同步將阻止多個訪問。

你也不需要這裏的信號燈。


編輯:

魔RISIN的回答也很不錯,如果你能集中你的異步任務,從而節省自己的麻煩到一個你應該(少你身邊有更好的運行併發線程)

+0

我沒有機會嘗試您的解決方案,因爲我決定嘗試並避免使用併發線程,但請感謝您的意見! –