У меня есть ListView, который мне нужно заполнить, используя фоновый поток. Список должен обновляться при получении каждого элемента. Ниже приведен очень упрощенный пример того, как я это реализую.
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 () - это то, что запускает потоки. Вызов notifyDataSetChanged () в onPostExecute () - это то, что обновляет мой ListView по мере поступления данных.
Проблема в том, что я обращаюсь к своей базе данных sqlite в «DownloadStuff ()», которая вызывается в «doInBackground», и наличие нескольких потоков, обращающихся к БД, приводит к ее аварийному завершению (если я закомментирую все действия БД здесь , затем он работает нормально. Ниже описывается, как я пытаюсь обойти эту проблему, однако она все еще дает сбой. Любой совет, как можно получить обновление ListView при получении данных из фонового потока?
Semaphore semaphore = new Semaphore(1, true);
public synchronized void DownloadStuff()
{
semaphore.acquire(1);
// ... DB operations ... //
semaphore.release(1);
}