2013-02-06 80 views
0

我有一個應用程序正在從文本文件加載數據並將每個文件的數據存儲到單獨的ArrayList。即使我的應用沒有崩潰從onCreate方法加載它(它只需要大約12秒鐘將所有數據從文本文件加載到ArrayLists中),但我仍被告知要將數據加載到異步線程中。Android:異步線程問題

我試圖建立一個異步線程,但我遇到了一個問題。我是全新的異步線程,所以我不知道/還沒有完全理解所有的細節(我試圖從不同來源拼湊信息)。下面是培訓相關代碼:

@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() { 

    }*/ 

} 

我正在IndexOutOfBoundsException異常(無效指數0,大小爲0),在onCreate方法的最後一條語句。

我想要做的就是將數據加載到單獨的線程中,因爲即使我的應用程序沒有崩潰,我被告知應該這樣做。 UI線程應該處理所有剩下的事情。該應用程序工作正常,直到我添加了異步線程代碼。

我如何讀取文件可以在這裏看到: Android: Asynch Thread Needed?

我在做什麼錯?

+0

您好:

void List<Foo> getListOfFoo() { ArrayList<Foo> listOfFoos = getTheListSomehow(); return listOfFoos; } 

例如!除了下面提出的修復方案,並且在您開始工作之後,如果用戶旋轉屏幕或類似的方式重新加載您的活動,您可能會遇到另一個問題,如果您想關閉onPostExecute中的進度對話框。由於這是等待,用戶可以離開並觸發重新加載。看[這篇文章](http://blogactivity.wordpress.com/2011/09/01/proper-use-of-asynctask/)。這就是爲什麼我提出了Loader API的原因,它帶來了更少的麻煩。 – slezica

+0

@uʍopǝpısdn好吧,我知道你說過它已經有一段時間了,因爲你已經使用它了,但是你認爲你可以把一些東西放在一起,就像你看到的那樣加載文件?我只是想將每個15個文件加載到他們自己的ArrayList中。 onClick方法將處理所有其他事情。我將查看Loader API,並在今天晚些時候嘗試查找一些示例,看看是否可以使用異步方法(由LuxuryMode提供)。 [我在大學裏教我自己,所以我在空閒時間工作。 :)] –

+0

@uʍopǝpısdn到目前爲止,我所能找到的是過於複雜的例子,我不明白和加載數據庫(我也不明白)。 :|我無法找到裝載器從任何地方讀取文件的例子。 –

回答

1

您從doInBackground返回null,所以當然這一切都將失敗。使用AsyncTask來實現它的目的。爲了使它正常工作,你需要用適當的類型參數正確地定義你的AsyncTask。

而不是使populateArrayLists有更新一些其他領域的副作用,有這樣一種方法:再次

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

讓我試試這個......我需要一點時間來適應/進行必要的更改以適應我的代碼... –

+0

這比我想象的要困難得多,因爲我擁有全局ArrayLists,並且在我的populateArrayLists()方法,我一個接一個讀入所有文件並填充所有ArrayLists。 (請參閱我的鏈接問題。) –

+0

@ host_sneed沒問題。看我的編輯。只需在getListOfStrings方法中執行該操作 – LuxuryMode

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

} 
+0

我有其他的東西在onCreate方法(按鈕等)應該對這個電話是最後的事情呢?從我從文檔中瞭解到的,onPostExecute是在doInBackground之後執行的,但它是否會返回到onCreate?或者是否可以使用onCreate完成並轉到用戶交互方法(如onClick)? –

+0

此外,我收到警告,如果我按照您的答案,onPostExecute永遠不會在本地使用。 –

+0

** AsyncTask **是一個並行進程。因此,如果執行** AsyncTask **,它將擁有它自己的進程,onCreate不會等待它完成** AsyncTask **,onCreate將繼續執行'new loadData()。execute() ;' – NaviRamyle