2013-02-06 2 views
0

텍스트 파일의 데이터를로드하고 각 파일의 데이터를 별도의 ArrayList에 저장하는 앱이 있습니다. 내 응용 프로그램이 onCreate 메서드에서 모든 데이터를로드하는 동안 충돌하지 않아도 비동기 스레드에서 데이터를로드하라는 메시지가 표시되었습니다 (텍스트 파일의 모든 데이터를 ArrayLists에로드하는 데 약 12 ​​초 걸림).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

안녕, 대신 populateArrayLists을 만드는

같은 방법이, 다른 필드를 업데이트의 부작용이! 아래에 제안 된 수정 사항을 제외하고이 작업을 수행 한 후에는 사용자가 화면을 회전 시키거나 이와 유사한 작업을 다시로드하면 진행 대화 상자를'onPostExecute'로 닫을 때 다른 문제가 발생할 수 있습니다. 대기 중이므로 사용자가 다른 곳으로 이동하여 다시로드 할 수 있습니다. [이 기사] (http://blogactivity.wordpress.com/2011/09/01/proper-use-of-asynctask/)를 참조하십시오. 이것이 로더 API를 제안한 이유이며, 이로 인해 문제가 줄어 듭니다. – slezica

+0

@ uʍopǝpısdn 좋아, 네가 그걸로 일한 이후로 잠시 있었다고 했었는데 네가 본 것처럼 파일을로드 할 수있는 무언가를 함께 넣을 수 있다고 생각하니? 각 15 개의 파일을 자신의 ArrayList에로드하려고합니다. onClick 메서드는 다른 모든 것을 처리합니다. Loader API를 살펴보고 오늘 나중에 비동기 메소드를 작동시킬 수 있는지 알아 보는 것 이외에 몇 가지 예제를 찾으려고 노력할 것입니다 (LuxuryMode에서 제공됨). [나는 대학에서 스스로 가르치므로, 나는 자유 시간에 일한다. :)] –

+0

@ uʍopǝpısdn 내가 지금까지 찾을 수 있었던 것은 내가 이해할 수없는 지나치게 복잡한 예제와 데이터베이스를로드하기위한 것들 (나는 또한 이해하지 못함)이다. : | 로더가 파일을 읽는 데 어디서나 예제를 찾을 수 없습니다. –

답변

1

당신은, doInBackground에서 null을 반환하는보십시오. AsyncTask를 사용하여 수행 할 작업을 수행하십시오. 제대로 작동하게하려면 적절한 유형 매개 변수로 AsyncTask를 올바르게 정의해야합니다. 예를 들어

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

내가 이것을 시도해 보자 ... 내 코드에 맞게 필요한 것을 변경/수정하는 데 약간의 시간이 걸릴 것이다 ... –

+0

글로벌 ArrayLists가 있고 있기 때문에 생각했던 것보다 조금 더 어렵다는 것을 증명하고있다. 내 populateArrayLists() 메서드, 모든 파일을 차례로 읽고 모든 ArrayLists를 채 웁니다. (내 연결된 질문보기) –

+0

@lord_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

관련 문제