2012-08-02 74 views
3

之前完成我有有兩個按鈕(連接請求數據)的Android應用程序(用Java編寫的)。的Java/Android的等待,直到一個線程中運行的新方法

單擊每個按鈕時,將執行一項任務,並顯示一個進度對話框顯示該任務已完成多少。

爲了顯示進度對話框,當每個按鈕被點擊時,任務在一個線程上運行。

連接按鈕只有一個任務 - 在線程上運行。然而,請求數據按鈕可以執行兩個任務 - 類似的連接按鈕,而且第二個任務的線程上的第一個任務,refreshInfo()必須在線程上的第一個任務後運行,progThread是完了。

private Button connectButton; 
private Button requestDataButton; 

private ProgressDialog connectionDialog; 
private ProgressDialog requestDataDialog; 

private ProgressThread progThread; 

private int currentDialog; 

public void connectClick(View view)  //When the connect button is clicked 
{ 
    performAction(1); //Run the thread to perform the action 
} 

public void requestDownloadClick(View view) //When the request data button is clicked 
{ 
    performAction(2); //Run the thread to perform the action 

    refreshInfo(); //Do something else 
} 

private void performAction(int type) 
{ 
    currentDialog = type; 

    showDialog(type); 

    try 
    { 
     progThread.join(); 
    } 
    catch (InterruptedException e) 
    { 
     e.printStackTrace(); 
    } 
} 

這裏的關鍵方法的performAction(整型)。我基本上不希望這種方法完成,直到progThread已經完成運行。

正如你所看到的,我已經試過progThread.join()防止方法持續,直到progThread運行完畢,然而由於progThread涉及顯示進度對話框,運行progThread .join()似乎阻止了進度對話框的顯示,因爲當前您單擊按鈕時,第一個任務正在執行,但對話框只在最後閃爍。

任何人都可以想到一種方法來運行線程,顯示進度對話框正常,然後運行第二種方法(如果有的話)。

我已經包含下面的線程代碼在需要時。

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

    private Handler progressHandler; 
    int mState; 
    int total; 

    ProgressThread(Handler _handler) // Constructor with an argument that specifies Handler on main thread to which messages will be sent by this thread. 
    { 
     progressHandler = _handler; 
    } 

    public void run() // Invoked automatically when the Thread starts. 
    { 
     mState = RUNNING; 

     updateProgressBar(); 

     connectButton = (Button) findViewById(R.id.btnConnect); 
     requestDataButton = (Button) findViewById(R.id.btnRequestDownload); 

     while (mState == RUNNING) 
     { 
      if (currentDialog == 1) 
      { 
       try 
       { 
        doSomething(); 

        if (something) 
        { 
         setState(DONE); 

         total = 100; 

         updateProgressBar(); 

         removeDialog(1); 

         connectButton.setEnabled(false); 
        } 
        else 
        { 
         total = total + 20; 

         if (something has reached a limit) 
         { 
          setState(DONE); 

          total = 0; 

          updateProgressBar(); 

          removeDialog(1); 
         } 
        } 

        updateProgressBar(); 
       } 
       catch (Exception e) 
       { 

       } 
      } 

      if (currentDialog == 2) 
      { 
       try 
       { 
        doSomething(); 

        total = 10; 

        updateProgressBar(); 

        doSomething(); 

        total = 70; 

        updateProgressBar(); 

        if (something) //If the download info has not been got 
        { 
         setState(DONE); 

         total = 0; 

         updateProgressBar(); 

         removeDialog(2); 

         runOnUiThread(new Runnable() 
         { 
          public void run() 
          { 
           connectButton.setEnabled(true); 

           requestDataButton.setEnabled(true); 
          }        
         }); 
        } 
        else 
        { 
         total = 100; 

         updateProgressBar(); 

         setState(DONE); 

         removeDialog(2); 

         runOnUiThread(new Runnable() 
         { 
          public void run() 
          { 
           requestDataButton.setEnabled(false); 
          }        
         }); 
        } 
       } 
       catch (Exception e) 
       { 
        removeDialog(2); 

        setState(DONE); 

        runOnUiThread(new Runnable() 
        { 
         public void run() 
         { 
          connectButton.setEnabled(true); 

          requestDataButton.setEnabled(true); 
         }        
        }); 
       } 
      } 
     } 
    } 

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

    public void updateProgressBar() 
    { 
     Message msg = progressHandler.obtainMessage(); // Send message (with current value of total as data) to Handler on UI thread so that it can update the progress bar 

     Bundle b = new Bundle(); 

     b.putInt("total", total); 

     msg.setData(b); 

     progressHandler.sendMessage(msg); 
    } 
} 

final Handler handler = new Handler()  // Handler on the main (UI) thread that will receive messages from the second thread and update the progress. 
{ 
    public void handleMessage(Message msg) 
    { 
     int total = msg.getData().getInt("total");    // Get the current value of the variable total from the message data and update the progress bar 

     switch (currentDialog) 
     { 
     case 1 : 
      connectionDialog.setProgress(total); 
      break; 

     case 2 : 
      requestDataDialog.setProgress(total); 
      break; 
     } 
    } 
}; 

protected Dialog onCreateDialog(int id) 
{ 
    switch (currentDialog) 
    { 
    case 1 : 
     connectionDialog = new ProgressDialog(this); 

     connectionDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 

     connectionDialog.setMax(100); 

     connectionDialog.setProgress(0); 

     connectionDialog.setMessage("Connecting To The Device"); 

     progThread = new ProgressThread(handler); 

     progThread.start(); 

     return connectionDialog; 

    case 2 : 
     requestDataDialog = new ProgressDialog(this); 

     requestDataDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 

     requestDataDialog.setMax(100); 

     requestDataDialog.setProgress(0); 

     requestDataDialog.setMessage("Requesting Download Data"); 

     progThread = new ProgressThread(handler); 

     progThread.start(); 

     return requestDataDialog; 

    default : 
     return null; 
    } 
} 
+0

閱讀Java同步的CountdownLatch,等待的對象,它需要JAVA的正確理解要運行的線程訂購明智的。 – 2012-08-02 09:18:18

回答

6

的Android API提供一個AsyncTask class它有兩個方法doInBackgroundonPostExecute。您必須重寫它們兩個,在doInBackground中執行任何您必須執行的操作,並在完成任務時執行onPostExecute回調。 還有一個onProgressUpdate回調,這正是你需要的。

+0

謝謝,這真的很有用:) – 2012-08-02 09:59:54

0

似乎其他答案你有覆蓋。 AsyncTask是要走的路。

但是,如果您想要穿過您的線程實現,只需start()下一個線程在第一個線程的run方法結束時。

+0

謝謝我要給異步任務去:) – 2012-08-02 10:00:25

0

聽起來像是你需要使用尺寸1

+0

我試過了,但它只是暫停整個線程運行。 – 2012-08-02 10:01:13

相關問題