Android:异步线程问题

时间:2013-02-06 02:12:47

标签: android android-asynctask android-activity

我有一个应用程序正在从文本文件加载数据并将每个文件中的数据存储到单独的ArrayList中。我被告知要在异步线程上加载数据,即使我的应用程序没有崩溃从onCreate方法加载它(只需大约12秒就可以将文本文件中的所有数据加载到ArrayLists中)。

我试图设置一个异步线程,但是我遇到了一个问题。我是异步线程的新手,所以我不知道/还没有完全理解所有细节(我试图从不同的来源拼凑信息)。以下是相关代码:

@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线程应该处理所有其余的。应用程序运行正常,直到我添加了异步线程代码。

我的文件如何阅读可以在这里看到: Android: Asynch Thread Needed?

我做错了什么?

2 个答案:

答案 0 :(得分:2)

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);
    }

}

答案 1 :(得分:1)

你从doInBackground返回null,所以当然这都失败了。使用AsyncTask来实现它的目的。要使其正常工作,您需要使用适当的类型参数正确定义AsyncTask。

不要让populateArrayLists有更新其他字段的副作用,而是使用如下方法:

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;
            }
        }
    }