gpt4 book ai didi

java - 为什么我的值没有从内部类添加到全局 ArrayList

转载 作者:行者123 更新时间:2023-12-04 08:59:14 24 4
gpt4 key购买 nike

我从服务器获取数据,我正在创建类 QuizFormat 的对象每次循环执行。我有一个全局ArrayList在其中声明我正在尝试添加这些对象。我正在以单独的方法执行此任务 getTest()它具有内部类并且正在扩展 AsyncTask类,作为获取数据的后台任务在其中进行。问题是,对象没有被添加到列表中。我尝试创建一个单独的方法来通过将对象作为参数传递来添加对象,但不是运气。我怎样才能解决这个问题?这是我正在使用的代码。QuizFormat ,一个带有构造函数、getter 和 setter 的基本类:

public class QuizFormat {
int id;
String question;
String[] options;
String answer;

public QuizFormat(int id, String question, String[] options, String answer) {
this.id = id;
this.question = question;
this.options = options;
this.answer = answer;
}
//getters and setters below
...
...
}
以下是 TestActivity类,我在其中完成上述所有任务:
public class TestActivity extends AppCompatActivity {
ArrayList<QuizFormat> quizFormatList; //Global ArrayList
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);

quizFormatList = new ArrayList<QuizFormat>(); // Initializing ArrayList
getTest(); //call to the method to fetch and add elements

//checking final size
Log.i("size","ArrayList: "+ quizFormatList.size());
try {
for (QuizFormat qf: quizFormatList) {
Log.i("que",qf.getQuestion());
}
} catch (NullPointerException e){
e.printStackTrace();
}
}

public void getTest(){
class FetchData extends AsyncTask<Void,Void,String> {
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);

for (int i=0; i<testArray.length(); i++){
//Parsing JSON data here, skipping that part

String[] options = new String[4];
options[0] = optionsObj.getString("opt1");
options[1] = optionsObj.getString("opt2");
options[2] = optionsObj.getString("opt3");
options[3] = optionsObj.getString("opt4");

int que_id = testObj.getInt("que_id");
String question = testObj.getString("question");
String answer = testObj.getString("answer");

//Adding to ArrayList
quizFormatList.add(new QuizFormat(que_id, question, options, answer));
}
//checking ArrayList size
Log.i("quizFormatList", "size: "+quizFormatList.size());
}
}
//Executing class
FetchData fd = new FetchData();
fd.execute();
}
}
以下是 logcat 输出。
这是从内部类“FetchData”计算的大小
I/quizFormatList: size: 5
以下是 onCreate()中统计的大小调用后的方法 getTest() ,如上面的代码所示。
I/size: ArrayList: 0
如何获取列表中的数据,以及如何访问它?需要帮助。

最佳答案

这是异步与同步行为的经典问题。这里发生的事情是您正在调用方法 getTest这是异步的,然后立即访问 quizFormatList .问题是你访问了quizFormatList之前 getTest有机会填充它。不幸的是,这不能那样做,而且有时可能会起作用,有时可能不会。
对此有几种解决方案,让我尝试提供一种不需要对您现在拥有的进行太多更改的解决方案。首先,我们希望异步任务在完成其工作后实际通知主 Activity 。我们将通过回调来做到这一点:

interface OnAsyncWorkDoneCallback {
void asyncWorkDone(List<QuizFormat> quizFormatList);
}

class FetchData extends AsyncTask<Void,Void,String> {
private final List<QuizFormat> quizFormatList = new ArrayList<>();
private final OnAsyncWorkDoneCallback callback;

public FetchData(OnAsyncWorkDoneCallback callback) {
this.callback = callback;
}

@Override
protected void onPostExecute(String s) {
// Do exactly what you were doing before and populate the field quizFormat

callback.asyncWorkDone(quizFormatList);
}
}
所以我们有一个异步任务,它现在需要一个回调来创建,一旦它完成,它就会调用这个回调,并为 quizFormatList 提供正确的结果。 .
以下是您在 Activity 中使用它的方法:
public class TestActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);

new FetchData((results) -> {
// do whatever you need to do with results
}).execute();
}
}

上面的代码有望工作并满足您的需求,但我不得不说在 android 上使用异步任务被认为是危险的并且非常不鼓励。这个主题本身就是另一个完整的答案,我现在不想解决它,因为您的问题不一定特定于异步任务,而是特定于异步环境中的竞争条件。但是,您可以看到,如果主 Activity 被破坏(手机旋转,即)传递给当前运行的异步任务的回调将属于被破坏的 Activity ,并且根据您对结果的处理,它可能最终会尝试访问它不能再访问的东西。这只是这种方法的问题之一。您可以在线阅读所有内容,关于它的信息已经足够多了,但这里有一个非常好的 post通过丹·卢。

关于java - 为什么我的值没有从内部类添加到全局 ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63631348/

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