5

AsyncTask를 사용하여 JSON을 사용하는 웹 서비스에서 정보를 가져 오는 안드로이드 응용 프로그램을 개발 중이며,이 JSON은 ListView에로드됩니다. 여기까지는 모든 것이 잘 작동합니다.ProgressDialog 또는 ProgressBar가 Android를 실행하는 응용 프로그램의 속도를 저하시킵니다.

onPreExecute() 메서드에서 시작되어 onPostExecute() 메서드에서 해제 된 ProgressDialog를 사용했습니다. 2.3.3 안드로이드 버전을 실행하는 에뮬레이터에서이 모든 작업은 7/8 초까지 걸립니다. 2.3.6을 실행하는 실제 장치로 테스트 한 결과 앱의 동작이 동일합니다.

그러나 4.1 버전의 Android를 실행하는 에뮬레이터를 사용하면이 작업을 수행하는 데 65-70 초가 소요됩니다. ProgressDialog를 제거하면 액션은 안드로이드 2.3 및 4.1 버전에서 7/8 초가 걸립니다. 나는이 모든 시나리오를 여러 번 테스트했습니다.

왜 이런 일이 발생합니까? 나는 그것을 테스트하는 4.1 안드로이드 버전과 어떤 실제 장치가 없으므로 나는 이것이 에뮬레이터 문제인지 궁금한가요? ProgressDialog 대신 일반 진행률 표시 줄 원을 사용하려고했지만 동일한 문제가 발생합니다. Android 4.1 버전에서는 너무 오래 걸립니다.

이 이상한 동작의 원인이 될 수있는 아이디어가 있습니까? : S

감사합니다.

dmon 및 James McCracken이 여기 내 활동의 코드입니다. 제발 도와주세요.

public class MainActivity extends Activity { 
private TextView tvTitleList; 
private ListView lvDataSearch; 
private ProgressDialog dialog; 
private long timeStart; 
private String[] dataSearch; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    tvTitleList = (TextView) findViewById(R.id.tvTitleList); 
    lvDataSearch = (ListView) findViewById(R.id.lvDataSearch); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

public class ProcessUpdateList extends AsyncTask<Integer, String, String[]> { 
    @Override 
    protected void onPreExecute() { 
     timeStart = System.currentTimeMillis(); 
     System.out.println("pre execute"); 
     try { 
      tvTitleList.setText("working...."); 
      dialog = ProgressDialog.show(MainActivity.this, "", "Loading. Please wait...", true); 
     } catch (Exception e) { 
      System.out.println("Error Async 1: " + e.getMessage()); 
     } 
    } 

    @Override 
    protected String[] doInBackground(Integer... paramss) { 
     try { 
      System.out.println("Get Data"); 
      dataSearch = getDataSearch(); 
     } catch (Exception e) { 
      System.out.println("Error Async 2: " + e.getMessage()); 
     } 
     System.out.println("Return Data " 
       + ((System.currentTimeMillis() - timeStart)/1000)); 
     return dataSearch; 
    } 

    @Override 
    protected void onPostExecute(String[] values) { 
     try { 
      System.out.println("Post Execute Data"); 
      tvTitleList.setText("done in " + ((System.currentTimeMillis() - timeStart)/1000)); 
      updateViewList(); 
      dialog.dismiss(); 
     } catch (Exception e) { 
      System.out.println("Error Async 3: " + e.getMessage()); 
     } 
    } 
} 

public void eventUpdateList() {  
    ProcessUpdateList process = new ProcessUpdateList(); 
    try { 
     process.execute(); 
    } catch (Exception e) { 
     System.out.println("NEW ERROR 2: " + e.getMessage()); 
    } 
} 

public String[] getDataSearch() { 
    try { 
     String readTwitterFeed = readJSON2("http://search.twitter.com/search.json?q=hey"); 

     JSONObject jsonObject = new JSONObject(readTwitterFeed); 
     JSONArray jsonArray = new JSONArray(); 

     jsonArray.put(jsonObject); 
     Gson gson = new GsonBuilder().setPrettyPrinting().create(); 
     String json = gson.toJson(jsonObject); 

     JSONObject jsonObject2 = new JSONObject(json); 
     JSONObject level1 = jsonObject2.getJSONObject("nameValuePairs"); 
     JSONObject level2 = level1.getJSONObject("results"); 
     JSONArray level3 = level2.getJSONArray("values"); 

     dataSearch = new String[level3.length()];     
     System.out.println(level3.length()+" resultados encontrados.");; 

     for(int i=0; i<level3.length(); i++) { 
      dataSearch[i] = level3.getJSONObject(i).getJSONObject("nameValuePairs").getString("text"); 
     }   
    } 
    catch(JSONException e) { 
     System.out.println(e.getMessage()); 
    }  
    return dataSearch;  
} 

public String readJSON2(String command) { 
    JSONObject jObj = null; 
    StringBuilder builder = new StringBuilder(); 
    HttpClient client = new DefaultHttpClient(); 
    HttpGet httpGet = new HttpGet(command); 
    try { 
     HttpResponse response = client.execute(httpGet); 
     StatusLine statusLine = response.getStatusLine(); 
     int statusCode = statusLine.getStatusCode(); 
     if (statusCode == 200) { 
      HttpEntity entity = response.getEntity(); 
      InputStream content = entity.getContent(); 
      BufferedReader reader = new BufferedReader(
        new InputStreamReader(content)); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       builder.append(line); 
      } 
      reader.close(); 
      jObj = new JSONObject(builder.toString()); 
     } else { 
      System.out.println(MainActivity.class.toString() + " Failed to download file"); 
     } 
    } catch (Exception e) { 
     return null; 
    } 
    return builder.toString(); 
} 

public void updateViewList() { 
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, dataSearch);     
    lvDataSearch.setAdapter(adapter); 
} 

public void clickBRefreshList(View v) { 
    eventUpdateList(); 
} 
} 
+0

나는 이것이 일어날 이유를 생각할 수 없다. 로그를 게시 할 수 있습니까? –

+1

뭔가보기에 위력이 들지만 시간이 좀 걸릴 것입니다. 또한 0.875 초 또는 "7 또는 8"초를 의미하는지 여부도 분명하지 않습니다. 만약 당신이 7 - 8을 의미한다면, 무엇인가가 틀린 것입니다. AsyncTask에 대한 코드를 게시해야합니다. – dmon

답변

4

에뮬레이터에서만이 동일한 동작을 4.1에서 테스트 할 수 있습니다. 내 실제 장치 (Galaxy S3 - 4.1)에서는 이런 일이 발생하지 않습니다. 또한 불확실한 진도 표시 줄에서만 발생하는 것으로 보입니다. 왜 이런 일이 일어날 지 모르지만 어쩌면 다른 사람들에게 일어난 일을 잘 알게 될 것입니다. 웹 서비스에 연결하고 xml 응답을 구문 분석 한 다음 구문 분석 된 응답을 표시하는 것과 거의 동일한 작업을 수행하고 있습니다. 참고로 ListViewandroid:empty 함수에 ProgressBar을 사용하고 있습니다.

편집 : 란 몇 가지 테스트

내가 XML 파일을 구문 분석 테스트 레이아웃에 ProgressBar과 나는이있어 : 그래서

Parse time: 94785 ms

을,이

<ProgressBar 
     android:id="@id/android:empty" 
     style="@android:style/Widget.Holo.ProgressBar" 
     android:layout_width="wrap_content" 
     android:layout_height="0dip" 
     android:layout_gravity="center_horizontal|center_vertical" 
     android:layout_weight="1"/> 
변경

to this

<TextView 
     android:id="@id/android:empty" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Searching..."/> 

및이 Parse time: 2642 ms

주를 가지고 : 내 ProgressBarListViewLinearLayout에있는 모든 분석은 AsyncTask에서 이루어집니다. 이것은 모두 에뮬레이터에 있습니다. 정말 이상한 ... 내 생각 엔 에뮬레이터는 실제로에서 스레드를 분리하지 않으므로 AsyncTaskProgressBar 회전이 CPU 사이클을 위해 싸우는 반면 실제 전화에서는 에뮬레이션되지 않으므로 의도 한대로 작동합니다.

편집 : WinXP에서 TaskManager를 본 후, 에뮬레이터는 실행중인 7 개의 스레드로 시작합니다.내 응용 프로그램을 실행하고 AsyncTask을 사용하여 AsyncTask.THREAD_POOL_EXECUTOR을 실행하고이 전체 프로세스 중에 스레드 수는 작업 관리자에서 7에서 결코 바뀌지 않습니다.

+0

이 스레드를 보았을 때 비슷한 문제에 대해 게시하려고했습니다. 내 4.4.2 에뮬레이터에서 똑같은 것을 볼 수 있습니다. http 호출에서 응답을 수신하는 AsyncTask는 progessBar를 뷰에 추가 할 때만 1-2 초에서 80-90 초로 증가했습니다. Windows에서 실행되는 BlueStacks에는 표시되지 않으므로 테스트 할 Android 장치가없는 경우 BlueStacks를 테스트하는 것이 좋습니다. – ScottyB