2015-06-22 70 views
-2

問題: 我有一個公共ArrayList的AsyncTask,我想知道如果我可以動態更新此ArrayList而不停止任務。動態更新AsyncTask

問題是,我的任務加載有關他的內部數組中的元素的信息,同時我的活動可以加載更多的元素,所以我想知道是否可以將這些新元素推送到任務的數組中,而不是創建一項新任務。

SOLUTION

MY TASK

public class TaskGetMatchesDetails extends AsyncTask<Void, MatchDetails, Void> { 

private FragmentHistory fragmentHistory; 

//Dynamic Data, Array where we have to add and remove elements. 
private ArrayList<Match> matchesArrayList; 

//Constructor 
public TaskGetMatchesDetails(FragmentHistory f) { 
    this.fragmentHistory = f; 
    this.matchesArrayList = new ArrayList<>(); 
} 

//SYNCHRONIZED METHODS 

public synchronized void addMatch(Match match) { 
    if (this.matchesArrayList != null) { 
     this.matchesArrayList.add(match); 
     Log.d("TASK DETAILS", "ADDED MATCH: " + match.getMatchId()); 
    } 
} 

public synchronized Match getFirsMatchFromArrayList() { 
    if (matchesArrayList.size() > 0) { 
     return matchesArrayList.get(0); 
    } 
    return null; 
} 

public synchronized void removeMatchFromArrayList(Match match) { 
    if (this.matchesArrayList != null) { 
     this.matchesArrayList.remove(match); 
     Log.d("TASK DETAILS", "REMOVED MATCH: " + match.getMatchId()); 
    } 
} 

@Override 
protected Void doInBackground(Void... params) { 
    Match match; 
    MatchDetails matchDetails; 
    while (!isCancelled()) { 

     //If we have not work to do continue 
     if (matchesArrayList.size() <= 0) { 
      continue; 
     } 

     //Get the work for this iteration 
     Match m = getFirsMatchFromArrayList(); 

     //If we have already calculated this data we just jump to other cycle 
     if (fragmentHistory.getMatchDetails(m.getMatchId()) != null) { 
      removeMatchFromArrayList(m); 
      continue; 
     } 

     matchDetails = new MatchDetails(); 

     //TODO: Here we have to proccess the data. 

     publishProgress(matchDetails); 
     removeMatchFromArrayList(m); 

    } 
    return null; 
} 

@Override 
protected void onPostExecute(Void aVoid) { 
    super.onPostExecute(aVoid); 
    fragmentHistory.setTaskGetMatchesDetails(null); 
    cancel(true); 
} 

@Override 
protected void onProgressUpdate(MatchDetails... matches) { 
    super.onProgressUpdate(matches); 
    //We save the data calculated in this fragment 
    fragmentHistory.addMatchDetails(matches[0]); 
} 

@Override 
protected void onCancelled() { 
    super.onCancelled(); 
    } 
} 

創建任務在該片段中onCreate方法

taskGetMatchesDetails = new TaskGetMatchesDetails(this); 
taskGetMatchesDetails.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 

要添加新元素

taskGetMatchesDetails.addMatch(m); 

關閉任務,你只需要

taskGetMatchesDetails.cancel(true); 
+0

請詳細解釋你想要什麼,並請顯示你的代碼 –

+0

你不能等待任務完成,然後檢查數組列表是否已更新?如果不是,完美,如果是的話,重新啓動任務?我不認爲你可以更新後臺線程中使用的數據,我不認爲這是一個好主意。 – JDenais

+0

讓我們看看,我有一個任務,加載有關他的數組中的元素的信息,我的主類可以同時加載更多的元素,所以事情是將這些新元素添加到任務數組,以便它可以繼續加載信息 – iagocanalejas

回答

1

答案是否定的和非常謹慎。不,你不能在沒有額外工作的情況下使用列表。您需要使用信號保護對數據的訪問或使用同步列表。否則,您可能會同時訪問導致部分狀態不正確的列表。這很糟糕,特別是如果兩者都一次更新列表,這可能導致內存訪問錯誤甚至崩潰。

如果您使用同步列表或信號量,您可以訪問它,但您需要仔細編寫算法以避免在中途刪除/添加項目時出現問題。但回答如何做到這一點非常廣泛,你需要給我們一個更具體的算法來做到這一點。

+0

謝謝你兄弟,我會嘗試用這個想法編寫一些代碼,並儘早分享它;) – iagocanalejas