我有一个应用程序,它从文本文件加载数据,并将每个文件中的数据存储到一个单独的ArrayList
中。我被告知要在异步线程上加载数据,即使我的应用程序不会从onCreate方法崩溃加载所有数据(将文本文件中的所有数据加载到ArrayLists只需要大约12秒)。
我试图设置一个异步线程,但遇到了一个问题。我是异步线程的新手,所以我不知道/还完全理解所有的细节(我正试图将不同来源的信息拼凑在一起)。这是相关代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_name);
new loadData().execute();
arrayListElement = ArrayList1.get(0);
}
private class loadData extends AsyncTask<Void, Void, Void> {
ProgressDialog dialog;
protected void onPreExecute() {
dialog = new ProgressDialog(ClassName.this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
populateArrayLists();
return null;
}
/*protected void onProgressUpdate() {
}
protected void onPostExecute() {
}*/
}
在onCreate方法的最后一条语句中,我得到了IndexOutOfBoundsException(索引0无效,大小为0)。
我所想做的就是在一个单独的线程上加载数据,因为即使我的应用程序没有崩溃,我也被告知应该这样做。UI线程应该处理剩下的所有内容。在我添加异步线程代码之前,应用程序一直运行良好。
如何读取我的文件可以在这里看到:安卓:需要异步线程吗?
我做错了什么?
AsyncTask尚未运行完毕,这就是arrayListElement = ArrayList1.get(0);
具有IndexOutOfBoundsException
的原因。
试试这个
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_name);
new loadData().execute();
}
private class loadData extends AsyncTask<Void, Void, Void> {
ProgressDialog dialog;
protected void onPreExecute() {
dialog = new ProgressDialog(ClassName.this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
populateArrayLists();
return null;
}
protected void onPostExecute(Void result) {
arrayListElement = ArrayList1.get(0);
dialog.dismiss();
super.onPostExecute(result);
}
}
您从doInBackground返回null,所以这一切当然都失败了。使用AsyncTask来完成它的任务。要使其正确工作,您需要使用适当的类型参数正确定义AsyncTask。
与其让populateArrayList具有更新其他字段的副作用,不如使用以下方法:
void List<Foo> getListOfFoo() {
ArrayList<Foo> listOfFoos = getTheListSomehow();
return listOfFoos;
}
例如:
public class MyActivity extends Activity {
public void doSomething(List<String> stringList) {
//do something here
}
class MyAsyncTask extends AsyncTask<Void, Void, List<String>> {
@Override
protected List<String> doInBackground(Void... params) {
ArrayList<String> listOfStrings = getListOfStrings();
return listOfStrings;
}
@Override
protected void onPostExecute(List<String> strings) {
super.onPostExecute(strings);
doSomething(strings);
}
private List<String> getListOfStrings() {
ArrayList<String> stringList = new ArrayList<String>();
//This is where you'd actually perform your expensive operation
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(getAssets().open(
"text1.txt")));
String text;
while ((word = br.readLine()) != null) {
stringList.add(text);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close(); // stop reading
} catch (IOException ex) {
ex.printStackTrace();
}
}
return stringList;
}
}
}