亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

當 AsyncTask 的 doInBackground 內部時列表讀為空

當 AsyncTask 的 doInBackground 內部時列表讀為空

慕的地8271018 2023-09-20 16:26:45
doInBackground我正在嘗試讀取of內部的整數列表AsyncTask。當我將列表傳遞給 的構造函數時AsyncTask,它已滿。但是,當我到達該doInBackground函數時,它是空的。有任何想法嗎?public class floatingActionButtonClickListener implements View.OnClickListener{    @Override    public void onClick(View v) {        if(mAdapter.getDeleteModeStatus()){            // Delete items from database            ArrayList<Integer> IDsToDelete = mAdapter.getJournalIDsToDelete();            new DeleteDatabase().execute(IDsToDelete);            // Turn FAB back to regular button            mFAB.setImageResource(R.drawable.baseline_add_white_48); // Turn FAB to delete button            // Disable delete mode            mAdapter.exitDeleteMode();            // Load database            new LoadDatabase().execute();        }        else{            Intent intent = new Intent(getBaseContext(), AcitivtyJournal.class);            int journalType = Constants.JOURNALTYPE_FULL;            intent.putExtra(Constants.JOURNAL_TYPE, journalType);            startActivity(intent);        }    }}private class DeleteDatabase extends AsyncTask <ArrayList<Integer>, Void, Void> {    @Override    protected void onPreExecute() {        super.onPreExecute();        mProgressBarHolder.setVisibility(View.VISIBLE);    }    @Override    protected Void doInBackground(ArrayList<Integer>... arrayLists) {        ArrayList<Integer> IDsToDelete = arrayLists[0];        AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "JournalEntries")                .build();        for(Integer idToDelete : IDsToDelete){            db.mJournalEntriesDao().deleteCompleteJournalEntry(idToDelete);        }        return null;    }    @Override    protected void onPostExecute(Void aVoid) {        mProgressBarHolder.setVisibility(View.GONE);    }}}
查看完整描述

2 回答

?
ITMISS

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是如何工作的),線程將其緩存刷新到主內存,然后也從中讀取。這就是數據共享的方式。這就是為什么最好使用框架方式,因為框架將負責在線程之間正確發布數據。你可以接受不可變的數據,但列表不是這樣的。即使您將引用聲明為不可變,

只是要明確一點。我并不是說以前的方法不起作用。我是說這是出于善意。您不能只是在線程之間共享數據并希望它起作用。


查看完整回答
反對 回復 2023-09-20
?
搖曳的薔薇

TA貢獻1793條經驗 獲得超6個贊

弄清楚了。為將來可能有類似問題的人發帖。

令人尷尬的是,它ArrayList<Integer>變空了,因為我mAdapter.exitDeleteMode();在調用后在函數中刪除了它AsyncTask().execute()。

我不知道當我將列表發送到時,AsyncTask它是列表的確切地址,而不僅僅是一個新列表(也就是說,直到我發布上面的評論,然后它點擊)。我想我的思路是從 C++ 或其他語言那里得到的。我不記得是哪一個了。

解決方案:我想出的解決方案是直接移入mAdapter.exitDeleteMode()ofonPostExecute()而不是將其放在onClick()方法中。

另一個潛在的解決方案:我相信另一個可行的解決方案(但我沒有測試)是將 a 插入new ArrayList<Integer> ()AsyncTask


查看完整回答
反對 回復 2023-09-20
  • 2 回答
  • 0 關注
  • 137 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號