2013-12-10 1 views
0

Итак, общая настройка У меня есть ListView, который получает разные значения в зависимости от вкладки, используя фрагменты.Выполнение потоков в порядке, чтобы они не конфликтуют

Если я медленно перемещаю язычки, он отлично работает. Но если я быстро перейду через вкладки, они «конфликтуют». (Элементы из одной вкладки появятся на второй странице).

Итак, мое решение состояло в том, чтобы создавать потоки, которые имеют исполняемые части, затем иметь очередь и добавлять в очередь, а затем запускать их из очереди. Я не думал, что это сработает, когда я это сделаю, и это не так.

Таким образом, общий код выглядит такой:

final Thread clearThread = new Thread(new Runnable() { 
    public void run() { 
     MyFragment.adapter.clear(); 

    } 
}); 
this.threadQueue.add(clearThread); 
if (tab == MenuActivity.TITLES.indexOf("My")) 
{ 
    // My Puzzles 
    final Activity a = this; 
    final Thread myThread = new Thread(new Runnable() { 

     public void run() { 
      MyFragment.getUserPuzzles(a); 
     } 
    }); 
    this.threadQueue.add(myThread); 
} 
else if (tab == MenuActivity.TITLES.indexOf("Top")) 
{ 
    // Top Puzzles 
    final Activity a = this; 
    final Thread topThread = new Thread(new Runnable() { 

     public void run() { 
      MyFragment.getTopPuzzles(a); 
     } 
    }); 
    this.threadQueue.add(topThread); 
} 
//.... More adding the Thread Queue. 

while (this.threadQueue.size() != 0) 
{ 
    final Thread temp = this.threadQueue.poll(); 
    this.runOnUiThread(temp); 
} 

Это в моем FragmentActivity классе, где, как методы, адаптеры и т.д., все в классе фрагмента (MyFrag).

Итак, возникает общий вопрос, как я могу изменить ListView так, чтобы он не конфликтует с другими значениями, заполняемыми во время его заполнения. Некоторые из потоков действительно получают значения в Интернете, поэтому в зависимости от соединения они могут быть быстрыми или медленными, но он загружается, так что он добавляет при загрузке.

Любая помощь будет оценена по достоинству.

Спасибо!

ответ

2

Чтобы синхронизировать потоки, вы блокируете объект, и когда два потока должны всегда синхронизироваться друг с другом, вероятно, это должен быть только один поток. Почему бы не использовать отдельный ListView для каждой вкладки.

+0

Это не имеет для меня никакого смысла. Позаботьтесь, чтобы расширить его немного больше? Может быть, показать какой-то псевдокод? У него есть один «ListView», но несколько потоков изменяют его в фоновом режиме. – Gray

+0

Да, звучит так, как вы говорите. Возможно, он мог бы переделать его, чтобы иметь один ListView для каждой вкладки с задачей async для загрузки элементов. – alex

+0

Серый вид объяснил мою проблему с вашим решением. Однако я сделал что-то очень похожее на то, что вы сказали. Дал каждой вкладке свой собственный адаптер (или что-то подобное, я действительно не знаю, что сделал LOL, но он работает). Я буду отмечать вас так же правильно, как выше это не помогло. –

3

Вставьте поле «текущий идентификатор запроса» в поле ввода. Когда вы создаете поток, установите идентификатор запроса в потоке. Когда поток завершает проверку поля и только обновляет представление, если оно соответствует.

т.е.

AtomicInteger currentId = new AtomicInteger(0); 

new Processor(currentId.incrementAndGet()).start(); 

В процессоре

if (currentId.get() == ourId) { 
    // only here do stuff 
} 

Для полной безопасности вы можете использовать синхронизированный блок, а не AtomicInteger, вы, вероятно, не нужно, что в этом случае, но этот вариант будет выглядеть так:

int currentId = 0; 
Object lock = new Object(); 

synchronized(lock) { 
    new Processor(++currentId).start(); // Must add then use, not use then add! 
} 

в процессоре

synchronized(lock) { 
    if (currentId == ourId) { 
     // only here do stuff 
    } 
} 
Смежные вопросы