2011-06-23 38 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

我没有机会尝试您的解决方案,因为我决定尝试并避免使用并发线程,但请感谢您的意见! –