2 回答

TA貢獻1871條經驗 獲得超8個贊
這不是您使用 AsyncTask 的方式。您需要聲明參數,然后在回調中接收它們。
另請注意,您正在嘗試以您的方式從兩個線程(主線程和后臺線程)訪問相同的數據(IDsToDelete),而沒有適當的同步。
private class DeleteDatabase extends AsyncTask<ArrayList<Integer>, Void, Void> {
@Override
protected Void doInBackground(ArrayList<Integer>... arrayLists) {
ArrayList<Integer> params = arrayLists[0];
// Do what you need
}
}
ArrayList<Integer> IDsToDelete = mAdapter.getJournalIDsToDelete();
new DeleteDatabase().execute(IDsToDelete);
當你有多線程時,你需要尋找兩件事:
操作的原子執行
內存可見性。
有一個共享內存,每個CPU都緩存數據。當您從一個線程創建某些內容時,您不能指望第二個線程會讀取它。在您的情況下,您正在創建 AsyncTask 并從一個線程注入參數,但然后您從另一個線程在 doInBackground 中讀取它們。一般來說,當你經歷一個同步塊或命中一個易失性變量時(我一般說的是,因為我也不完全理解JVM是如何工作的),線程將其緩存刷新到主內存,然后也從中讀取。這就是數據共享的方式。這就是為什么最好使用框架方式,因為框架將負責在線程之間正確發布數據。你可以接受不可變的數據,但列表不是這樣的。即使您將引用聲明為不可變,
只是要明確一點。我并不是說以前的方法不起作用。我是說這是出于善意。您不能只是在線程之間共享數據并希望它起作用。

TA貢獻1793條經驗 獲得超6個贊
弄清楚了。為將來可能有類似問題的人發帖。
令人尷尬的是,它ArrayList<Integer>
變空了,因為我mAdapter.exitDeleteMode();
在調用后在函數中刪除了它AsyncTask().execute()
。
我不知道當我將列表發送到時,AsyncTask
它是列表的確切地址,而不僅僅是一個新列表(也就是說,直到我發布上面的評論,然后它點擊)。我想我的思路是從 C++ 或其他語言那里得到的。我不記得是哪一個了。
解決方案:我想出的解決方案是直接移入mAdapter.exitDeleteMode()
ofonPostExecute()
而不是將其放在onClick()
方法中。
另一個潛在的解決方案:我相信另一個可行的解決方案(但我沒有測試)是將 a 插入new ArrayList<Integer> ()
到AsyncTask
添加回答
舉報