2011-11-30 85 views
2

我從服務器檢索數據時,顯示進度條,然後從服務器檢索數據顯示圖表上的數據,但在繪製圖表上的數據時,我的進度條凍結了嗎?是否有人知道爲什麼會這樣。 ....在android爲什麼我的ProgressBar凍結?

在此先感謝...

private ProgressDialog pd; 
private Handler handler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) {   
     Toast.makeText(context, "Please Wait...", Toast.LENGTH_LONG).show(); 
     Thread t = new Thread(new Runnable() {    
      @Override 
      public void run() { 
       functionDrawMyData();/*in this function i am accessing activity view and drawing data on that view at time of drawing my Progress bar Freezes */ 
      } 
     }); 
     runOnUiThread(t); 
     pd.dismiss();   
    } 
}; 

此處理我使用的是檢索數據後調用完成 和按鈕點擊我得到的數據,並顯示進度條

ImageButton myButton = (ImageButton) findViewById(R.id.myBtn); 
pair1ChartButton.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) {    
       pd = ProgressDialog.show(v.getContext(),"Please wait...","Retrieving data ...",true, 
         true, 
         new DialogInterface.OnCancelListener(){ 
          @Override 
          public void onCancel(DialogInterface dialog) { 

          } 
         }); 
       Thread t = new Thread(new Runnable() {      
        @Override 
        public void run() { 
          getDataFromServer();//calling function to get data from server 
         handler.sendEmptyMessage(0);      
        } 
       }); 
       t.start(); 
     } 
    }); 

回答

1

你應該與AsyncTask幫助(智能底色線程)和ProgressDialog

的AsyncTask能夠正確且容易使用的UI線程的做到這一點。該類允許執行後臺操作並在UI線程上發佈結果,而無需操縱線程和/或處理程序。

異步任務由在後臺線程上運行並且其結果在UI線程上發佈的計算定義。異步任務由3個泛型類型定義,稱爲Params,Progress和Result,以及4個步驟,分別稱爲begin,doInBackground,processProgress和end。

4個步驟

當執行一個異步任務,任務經過4個步驟:

onPreExecute(),調用執行任務之後立即在UI線程上。此步驟通常用於設置任務,例如通過在用戶界面中顯示進度條。

doInBackground(Params...),在onPreExecute()完成執行後立即在後臺線程上調用。此步驟用於執行可能需要很長時間的後臺計算。異步任務的參數傳遞給此步驟。計算結果必須通過該步驟返回並返回到最後一步。此步驟還可以使用publishProgress(Progress ...)發佈一個或多個進度單元。這些值在onProgressUpdate(Progress ...)步驟中發佈在UI線程上。

onProgressUpdate(Progress...),在調用publishProgress(Progress ...)後在UI線程上調用。執行的時間是未定義的。此方法用於在後臺計算仍在執行時在用戶界面中顯示任何形式的進度。例如,它可以用來爲進度條設置動畫效果或在文本字段中顯示日誌。

onPostExecute(Result),在後臺計算完成後在UI線程上調用。後臺計算的結果作爲參數傳遞給此步驟。 線程規則

有必須遵循此類才能正常工作的幾個線程規則:

任務實例必須在UI線程上創建。 execute(Params ...)必須在UI線程上調用。 請勿手動調用onExExecute(),onPostExecute(Result),doInBackground(Params ...),onProgressUpdate(Progress ...)。 任務只能執行一次(如果第二試圖執行一個異常將被拋出。)

示例代碼
什麼適配器確實在這個例子中並不重要,更重要的是要明白,你需要使用AsyncTask顯示進度對話框。

private class PrepareAdapter1 extends AsyncTask<Void,Void,ContactsListCursorAdapter > { 
    ProgressDialog dialog; 
    @Override 
    protected void onPreExecute() { 
     dialog = new ProgressDialog(viewContacts.this); 
     dialog.setMessage(getString(R.string.please_wait_while_loading)); 
     dialog.setIndeterminate(true); 
     dialog.setCancelable(false); 
     dialog.show(); 
    } 
    /* (non-Javadoc) 
    * @see android.os.AsyncTask#doInBackground(Params[]) 
    */ 
    @Override 
    protected ContactsListCursorAdapter doInBackground(Void... params) { 
     cur1 = objItem.getContacts(); 
     startManagingCursor(cur1); 

     adapter1 = new ContactsListCursorAdapter (viewContacts.this, 
       R.layout.contact_for_listitem, cur1, new String[] {}, new int[] {}); 

     return adapter1; 
    } 

    protected void onPostExecute(ContactsListCursorAdapter result) { 
     list.setAdapter(result); 
     dialog.dismiss(); 
    } 
} 
+0

我如何訪問我的活動視圖在這個AsyncTask子類 – savy

+0

我沒有得到什麼viewContacts preExecute() – savy

+0

這是父類名稱,它包含在這裏發佈的私人類。 – Pentium10

0

這是因爲即使在關閉或解除對話框之前,您也開始更新UI。這是你的progressDialog凍結的原因。

所以更改您這樣的代碼,

 pd.dismiss(); 
    runOnUiThread(t); 
+0

,但我想表明,在對話框拉絲時也.. – savy

+0

,那麼你必須關閉該對話框老並開始新的進度對話框在調用runOnUiThread(t)之前。 –

0

請記住android保持dilogs在內存中的參考。所以它不需要一次又一次地重新創建它。所以進度對話框第一次正常工作,但下一次掛起/卡住。

注意:即使解僱了他們,android也不會清除內存引用。

有方法是Activity類名爲removeDialog(int id)這也會清除內存引用。

這裏是你如何可以顯示和刪除對話框

protected Dialog onCreateDialog(int id) { 
     // TODO Auto-generated method stub 
     switch(id){ 
      case 0:{ 
      dialog = ProgressDialog.show(this, "", 
        "Loading. Please wait...", true); 
      return dialog; 
      } 
      } 

     return super.onCreateDialog(id); 
    } 

現在只需撥打showDialog(0)顯示對話框,removeDialog(0)將其隱藏。

0

同樣的問題我也遇到,我解決我的自我,

只是看到我的示例代碼。你會明白的。

public class NearByLoc extends AsyncTask<Void, Void, Void> { 
    @SuppressLint("InlinedApi") 
    protected void onPreExecute() { 

     // pdailog.show(); 
     loading_spinnerMain.setVisibility(View.VISIBLE); 
    } 


@Override 
    protected Void doInBackground(Void... params) { 
    //write your entire code [logic]here 

    } 
@Override 
    protected void onPostExecute(Void unused) { 

     //finally list of data setting to the adapter 
     //before setting to the adapter you should dismiss Progress spinnerr 

     loading_spinnerMain.setVisibility(View.GONE); 
     NearByMeAdapter adapter = new NearByMeAdapter(NearByMe.this, list); 

     listViewNearLoc.setAdapter(adapter); 
} 

它的工作了me..Hope它可以幫助你