2012-04-07 1 views
0

인터넷에서 데이터를 가져 와서 구문 분석 한 다음 사용자에게 데이터를 표시하려고합니다. 작업은 일반적으로 3 초 정도 걸리며, ProgressDialog 회 전자에 데이터로드 중임을 알리는 메시지를 표시하고 싶습니다. 문제는 ProgressDialog가 로딩이 거의 완료되었을 때만 나타납니다. 이것은 내 코드ProgressDialog가 바로 표시되지 않습니다.

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    Button load_routes = (Button)findViewById(R.id.load_routes); 

    load_routes.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      task_complete = false; 
      progressBar = new ProgressDialog(v.getContext()); 
      progressBar.setCancelable(false); 
      progressBar.setMessage("Fetching routes data ..."); 
      progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
      progressBar.show(); 

      if(haveNetworkConnection()) 
      { 
       loading_routes_data(v); 
      } 
      else 
      { 
       progressBar.dismiss(); 
      } 
     } 
    }); 
} 

입니다 그리고 이것은 온 클릭 호출되는 내 기능입니다

private void loading_routes_data(View v) 
{ 
    try 
    { 
     new Thread(new Runnable() 
     { 
      public void run() 
      { 
       while(!task_complete) 
       { 
        refresh_routes(); 
        try 
        { 
         Thread.sleep(1000); 
        } 
        catch(InterruptedException e) 
        { 
         e.printStackTrace(); 
        } 
       } 
       runOnUiThread(new Runnable() 
       { 
        public void run() 
        { 
         progressBar.dismiss(); 
        } 
       }); 
      } 
     }).start(); 
    } 
    catch(Exception e) 
    { 
    } 

    while(!task_complete) 
    { 
    } 
} 

refresh_routes() 함수는 데이터를 가져을 구문 분석하고 truetask_complete, 나는 여부에조차 확실하지 않다 설정 또는 while 루프 안에 보관해야합니다.

그래서 내 큰 문제입니다. ProgressDialog을 버튼 클릭으로 바로 표시하고 싶습니다. refresh_routes()을 호출하고 refresh_routes()이 완료되면 진행률 대화 상자를 제거하고 싶습니다. 그러나 나는 그 일을 어떻게해야하는지 확신 할 수 없다.

누군가가 예를 들어 어떤 기사에서 문제를 해결하는 방법을 보여줄 수 있다면 정말 감사 할 것입니다. 미리 감사드립니다.

답변

2

메서드 끝에서 while(!task_complete)을 호출하여 UI 스레드를 잠그고 있습니다. 이런 작업에 실제로는 AsyncTask을 사용해야합니다. 여기 AsyncTask이 어떻게 보일지이다 : 당신의 refresh_routes() 방법은 어떻게 작동하는지

new MyAsyncTask(this).execute(); 

잘 모르겠어요,하지만 당신은 내부 기능의 움직이는 고려해 볼 수 있습니다 :

private class MyAsyncTask extends AsyncTask<Void, Void, Void> { 

    private ProgressDialog progressDialog; 
    private Context context; 

    public MyAsyncTask(Context context) { 

     this.context = context; 
    } 

    @Override 
    protected void onPreExecute() { 

     super.onPreExecute(); 
     progressDialog = ProgressDialog.show(context, null, "Fetching routes data ..."); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 

     while (!task_complete) { 
      refresh_routes(); 
      try { 
       Thread.sleep(1000); 
      } 
      catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 

     super.onPostExecute(result); 
     progressDialog.dismiss(); 
    } 
} 

이를 실행하려면이 작업을 수행 할 것 doInBackground() 방법.

+0

굉장 했어! 모든 온라인 자습서에서는 스레드를 사용하라고 말했지만 이는 놀라운 것입니다. 또한 asynch에서 뷰를 매개 변수로 받아들이는 함수를 호출 할 수있는 방법이 있는지 알고 싶습니까? – Quillion

+0

백그라운드 프로세스가 진행되는 동안 진행 상황을 보여 주려면 onProgressUpdate (...) 메소드를 오버라이드하십시오. 그런 다음 액션을 트리거하기 위해'doInBackground()'메소드 내에서'publishProgress (...) '를 호출 할 수 있습니다. UI 스레드에서 자동으로 실행됩니다. 모든 것이 어떻게 잘 맞는지 이해하려면'AsyncTask' 문서를 읽으십시오. –

1

AsyncTask을 사용하십시오. 그것은 당신에게 액티비티와 함께 ​​멀티 스레딩을 수행하는 훌륭한 기능을 제공합니다.