gpt4 book ai didi

java - 当 AsyncTask 的 doInBackground 内部时列表读为空

转载 作者:行者123 更新时间:2023-12-02 09:27:50 25 4
gpt4 key购买 nike

我正在尝试读取 AsyncTaskdoInBackground 内的整数列表。当我将列表传递给 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);
}
}

}

最佳答案

这不是你使用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 并从一个线程注入(inject)参数,但然后您从另一个线程在 doInBackground 中读取它们。一般来说,当你经历一个同步块(synchronized block)或命中一个 volatile 变量时(我一般说的是,因为我也不完全理解JVM是如何工作的),线程将其缓存刷新到主内存,然后也从中读取。这就是数据共享的方式。这就是为什么最好使用框架方式,因为框架将负责在线程之间正确发布数据。你可以接受不可变的数据,但列表不是这样的。即使您将引用声明为不可变,您也可能会从两个线程中看到正确的对象,但它们保存的数据可能是旧的。

只是为了清楚起见。我并不是说以前的方法不起作用。我是说这是出于善意。您不能只是在线程之间共享数据并希望它起作用。

关于java - 当 AsyncTask 的 doInBackground 内部时列表读为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58211488/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com