2012-09-26 1 views
9

작업을 진행하는 동안 백분율을 추가하지 않는 비동기 작업이 있습니다. 그것은 항상 0 % 0/100대화 진행 설정

에서 유지하는 것은 여기에 내 코드

 private class getAppInfo extends AsyncTask<String, String, String> { 
    /** The system calls this to perform work in a worker thread and 
     * delivers it the parameters given to AsyncTask.execute() */ 
    ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     if(showLoading == true){ 
      dialog = new ProgressDialog(SelfHelp.this); 
      dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
      dialog.setMessage("Loading"); 
      dialog.setIndeterminate(true); 
      dialog.setCancelable(false); 
      dialog.setMax(100); 
      dialog.setProgress(100); 
      dialog.show(); 
     } 
    } 

    @Override 
    protected String doInBackground(String... urls) {      
     String xml = null; 
     int count = 0; 
     try { 
      // defaultHttpClient 
      DefaultHttpClient httpClient = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(urls[0]); 

      HttpResponse httpResponse = httpClient.execute(httpGet); 
      HttpEntity httpEntity = httpResponse.getEntity(); 
      xml = EntityUtils.toString(httpEntity); 

      while(count != 100){ 
       publishProgress(""+count); 
       count += 5; 
      } 

     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } catch (ClientProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     }         

     Document doc = parser.GetDomElement(xml); 
     NodeList nl = doc.getElementsByTagName("topic"); 
     getChildElements(nl);       
     return xml; 
    } 


    @Override 
    protected void onProgressUpdate(String... progress) { 
     Log.v("count",progress[0]); 
     dialog.setProgress(Integer.parseInt(progress[0])); 
    } 

    /** The system calls this to perform work in the UI thread and delivers 
     * the result from doInBackground() */ 
    @Override 
    protected void onPostExecute(String result) {  
     //dialog.setProgress(100); 
     menuList.setAdapter(setListItems(menuItems)); 
     menuList.setTextFilterEnabled(true); 
     if(showLoading == true){ 
      dialog.dismiss(); 
      showLoading = false; 
     } 
    } 

입니다 그것은 onProgressUpdate에 가서 않고 수는 5 상승하지만 진행률 표시 줄이 변경되지 않습니다. 5로 증가시키고 진행 상황을 올바르게 표시하려면 어떻게합니까?

답변

26

문제는 setIndeterminate(true)과 관련이 있습니다. 진행률을 업데이트하려면 false으로 설정해야합니다. 당신 setIndeterminate(true) 다음해서 ProgressDialog 클래식 윈도우 모래 시계로 작동하는지

+0

그 제안은 아무 것도 변경하지 못했습니다. 아직 이동하지 않았습니다. 0 % – BigT

+0

set dialog.setProgress (100); 0 대신 0으로 – Blackbelt

+0

preExecute의 진행률을 0으로 설정하면 여전히 작동하지 않습니다. – BigT

3

당신은 코드, 그것은 %의 비율로 진행 상황을 보여주는를 다음 시도 할 수 있습니다, 여기, 코드,

public class ProgressBarExampleActivity extends Activity 
{ 
    ProgressThread progThread; 
    ProgressDialog progDialog; 
    Button button1, button2; 
    int typeBar;      // Determines type progress bar: 0 = spinner, 1 = horizontal 
    int delay = 1000;     // Milliseconds of delay in the update loop 
    int maxBarValue = 30;   // Maximum value of horizontal progress bar 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

//  // Process button to start spinner progress dialog with anonymous inner class 
//  button1 = (Button) findViewById(R.id.Button01); 
//  button1.setOnClickListener(new OnClickListener() 
//  { 
//   public void onClick(View v) 
//   { 
//    typeBar = 0; 
//    showDialog(typeBar); 
//   } 
//  }); 

     // Process button to start horizontal progress bar dialog with anonymous inner class 
     button2 = (Button) findViewById(R.id.Button02); 
     button2.setOnClickListener(new OnClickListener() 
     { 
      public void onClick(View v) 
      { 
       typeBar = 1; 
       showDialog(typeBar); 
      } 
     }); 
    } 

    // Method to create a progress bar dialog of either spinner or horizontal type 
    @Override 
    protected Dialog onCreateDialog(int id) 
    { 
     switch(id) 
     { 
//  case 0:      // Spinner 
//   progDialog = new ProgressDialog(this); 
//   progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
//   progDialog.setMessage("Loading..."); 
//   progThread = new ProgressThread(handler); 
//   progThread.start(); 
//   return progDialog; 
     case 1:      // Horizontal 
      progDialog = new ProgressDialog(this); 
      progDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
      progDialog.setMax(maxBarValue); 
      progDialog.setMessage("Dollars in checking account:"); 
      progThread = new ProgressThread(handler); 
      progThread.start(); 
      return progDialog; 
     default: 
      return null; 
     } 
    } 

    // Handler on the main (UI) thread that will receive messages from the 
    // second thread and update the progress. 

    final Handler handler = new Handler() 
    { 
     public void handleMessage(Message msg) 
     { 
      // Get the current value of the variable total from the message data 
      // and update the progress bar. 
      int total = msg.getData().getInt("total"); 
      progDialog.setProgress(total); 
//   if (total >= maxBarValue) 
      if (total <= 0)    
      { 
       dismissDialog(typeBar); 
       progThread.setState(ProgressThread.DONE); 
      } 
     } 
    }; 

    // Inner class that performs progress calculations on a second thread. Implement 
    // the thread by subclassing Thread and overriding its run() method. Also provide 
    // a setState(state) method to stop the thread gracefully. 

    private class ProgressThread extends Thread 
    { 
     // Class constants defining state of the thread 
     final static int DONE = 0; 
     final static int RUNNING = 1; 

     Handler mHandler; 
     int mState; 
     int total; 

     // Constructor with an argument that specifies Handler on main thread 
     // to which messages will be sent by this thread. 

     ProgressThread(Handler h) 
     { 
      mHandler = h; 
     } 

     // Override the run() method that will be invoked automatically when 
     // the Thread starts. Do the work required to update the progress bar on this 
     // thread but send a message to the Handler on the main UI thread to actually 
     // change the visual representation of the progress. In this example we count 
     // the index total down to zero, so the horizontal progress bar will start full and 
     // count down. 

     @Override 
     public void run() 
     { 
      mState = RUNNING; 
      total = maxBarValue; 
      while (mState == RUNNING) 
      { 
       // The method Thread.sleep throws an InterruptedException if Thread.interrupt() 
       // were to be issued while thread is sleeping; the exception must be caught. 
       try 
       { 
        // Control speed of update (but precision of delay not guaranteed) 
        Thread.sleep(delay); 
       } catch (InterruptedException e) { 
        Log.e("ERROR", "Thread was Interrupted"); 
       } 

       // Send message (with current value of total as data) to Handler on UI thread 
       // so that it can update the progress bar. 

       Message msg = mHandler.obtainMessage(); 
       Bundle b = new Bundle(); 
       b.putInt("total", total); 
       msg.setData(b); 
       mHandler.sendMessage(msg); 

       total--; // Count down 
      } 
     } 

     // Set current state of thread (use state=ProgressThread.DONE to stop thread) 
     public void setState(int state) 
     { 
      mState = state; 
     } 
    } 
} 

출력을 참조입니다

enter image description here

1

AsyncTask를 메인 UI로 실행하는 내 서비스에서 통신하는 방법을 찾고있을 때이 솔루션을 발견했기 때문에 다른 aproach를 언급 할 것입니다. 루시퍼 (Lucifer)의 솔루션은 서비스를위한 모듈 식이 아닙니다. 서비스를 1 클래스 이상 사용해야한다면 (내 경우) 가변 핸들러에 액세스 할 수 없으며 핸들러를 보낼 수도 없다는 것을 알고 있습니다. Intent to Service (AsyncTask tho에 보낼 수 있음). 해결책은 방송입니다.

sendBroadcast(new Intent(WORK_DONE)); 
AsyncTask를에

및 활동에

private BroadcastReceiver receiver = new BroadcastReceiver() { 
    public void onReceive(Context c, Intent i) { //update your UI here } 
} 

registerReceiver(receiver, new IntentFilter(WORK_DONE)); 

.

안드로이드 개발자가 사용하는 모든 내부 클래스가 마음에 들지 않습니다. 내부 클래스를 만들고 외부 클래스 변수에 액세스하는 것이 더 쉽지만 일단 클래스를 다시 사용할 필요가 있으면 코드를 편집해야합니다. 나는 안드로이드를 처음 접했을 때, 어쩌면 내가 틀렸고 실제로 그 클래스들을 재사용 할 필요가 없다. 결코 큰 프로젝트를 수행하지는 못했지만 생각이 들지 않았습니다.하지만 대학생들이 재사용 가능한 코드를 프로그래밍하는 방법을 가르쳐 주었기 때문에 옳은 생각을하지 못했습니다.