我从服务器获取数据,并且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
有机会填充它。不幸的是,这不能那样做,而且有时可能行得通,有时可能行不通。
为此,有几种解决方案,让我尝试提供一种不需要对现有内容进行太多更改的解决方案。首先,我们希望异步任务在完成其工作时实际上通知主要活动。我们将通过回调执行此操作:
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
。
在活动中如何使用它:
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上使用异步任务被认为是危险的,不鼓励这样做。这个主题本身就是另一个完整的答案,我现在不想解决,因为您的问题不一定特定于异步任务,而是针对异步环境中的竞争条件。但是,您可以看到,如果主要活动被破坏(电话旋转),则传递给当前正在运行的异步任务的回调将属于被破坏的活动,并且取决于您对结果的处理方式,它最终可能会尝试访问无法再访问的东西。这只是这种方法的问题之一。您可以在线阅读所有相关信息,其中有足够的信息,但这是一篇非常好的文章 丹·刘(Dan Lew)着。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句