2012-12-29 7 views
1

Jsoup를 사용하는 Android 앱에서 작업 중입니다. 개발 초기에 어떤 종류의 스레딩을 구현해야만했는데, 스레딩 문제를 해결하기 전에 완료된 코드의 상당 부분을 얻고 싶었 기 때문입니다. AsyncTask를 사용하려고하는데 NetworkOnMainThreadException 오류가 발생합니다. AsyncTask에 대한 튜토리얼과 SO 게시물을 많이 읽었지만 여전히 문제를 파악하는 것처럼 보일 수 있습니다. StrictMode ... 코드를 추가하면 Jsoup를 사용하여 데이터를로드 할 때 UI 자물쇠를 제외하고 앱이 원하는대로 작동합니다. 아무도 내가 AsyncTask에 관한 잘못하고있는 것을 보여줄 수 있다면 고맙겠습니다. (추신 내가 정리하는 코드 중복의 많음이 알고,하지만 난 AsyncTask를 먼저 작업을 진행 할)Android AsyncTask 및 NetworkOnMainThreadException

public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 

      /***This is the work around used***/ 
      StrictMode.ThreadPolicy policy = new  StrictMode.ThreadPolicy.Builder().permitAll().build(); 
      StrictMode.setThreadPolicy(policy); 
      /******/ 



      up = new TreeMap<Double, String[]>(); 

      c1 = "example.com/1"; 
      //instansiate textviews (6) 
        doc1 = doc; 
      c2 = "example.com/2"; 
      //instansiate textviews (6) 
        doc2 = doc; 
      c3 = "example.com/3"; 
      //instansiate textviews (6) 
      doc3 = doc; 

      // instansiate textviews(16) 

      new Download().execute(c1,c2,c3); 

    } 
     private class Download extends AsyncTask<String, Integer, String[][]> { 
      @Override 
      protected String[][] doInBackground(String... urls){ 
       out = new String[7][3]; 
       try { 
        doc = Jsoup.connect(urls[0]).data().get();   
        //days, times, and cs arrays created and filled 

        String[] out1arr = {days[0], times[0], cs[0]}; 
        //...all 7 
        String[] out7arr = {days[6], times[6], cs[6]}; 
        String[][] outarrs = {out1arr,out2arr,out3arr,out4arr,out5arr,out6arr,out7arr}; 
        for (int i= 0; i < out.length; i++){ 
         out[i] = outarrs[i]; 
        } 
       } catch (IOException e1) { 
        e1.printStackTrace(); 
       } 
       return (out); 
      } 
      @Override 
      protected void onProgressUpdate(Integer... progress){ 
      } 
      @Override 
      protected void onPostExecute(String[][] result){ 

       Do(/*textviews(6)*/, c1, a, outa, "example1"); //a is previously instantiated double array, outa is preiously instantiated string array 
       Do(/*textviews(6)*/, c2, b, outb, "example2"); 
       Do(/*textviews(6)*/, c3, c, outc, "example3"); 


       upc00.setText(getUpc()[0][0]); 
       //setText for all 16 
       upc32.setText(getUpc()[3][2]); 

      } 

      private void Do(TextView t, TextView u, TextView v, TextView w, TextView x, TextView y,String webpage, double[] darr, String[] sarr, String show){ 


       t.setText(doInBackground(webpage)[0][0]); 
       //...all 6 
       y.setText(doInBackground(webpage)[1][2]);  
       for (int i =0; i < darr.length; i++){ 
        darr[i] = tis[i]; 
        up.put(darr[i], out[i]); 
       } 
      } 
     } 
     private ArrayList<String[]> getMap(){ 
       //... 
      return s; 
     } 
     private String[][] getUpc(){ 
      //... 
      return upc; 
     } 

답변

0

프레임 워크는 사용자가 직접 호출하지 말아야 doInBackground 호출합니다. 코드에서 UI 스레드의 프레임 워크에서 호출하는 onPostExecute에서 전화를 겁니다. 따라서 효과적으로 호출은 UI 스레드에서 실행됩니다.

페치 논리를 모두 doInBackgound 방법으로 이동하십시오. 결과를 호출자에게 전달하려면 onPostExecute 메서드를 사용해야합니다.

+0

감사합니다. 많은 코드를 재배치해야하지만 제안한 변경 사항을 기반으로로드 시간은 이전과 같이 10-15가 아닌 ~ 1 초가되었습니다. – user1935594