2012-10-26 31 views
11

我知道第一個你會這麼做的......爲什麼你在這個世界上使用AsyncTask。Android:如何等待AsyncTask在MainThread中完成?

所以這裏是我的問題,我正在一些Android應用程序(Android 2.1或更高版本的API 7)上工作,我正在測試仿真器,一切都很好,所以然後我在HTC Sensation上測試,它說NetworkOnMainThreadExeption!

我正在下載一些圖片,然後在地圖上繪製。

所以爲了解決這個問題每個(互聯網連接)在這種情況下下載圖片我必須把AsyncTask的工作。

所以我需要一個方法是如何知道什麼時候所有照片都做了,所以我可以開始繪製..

我嘗試了這麼多,沒有結果,我不知道。我有一個解決方案與處理程序,但如果運行在較慢的網絡我得到空指針(因爲圖片不下載)。

所以請幫助我。

編輯:

這裏的理念是:

Bitmap bubbleIcon ; 
    onCreate(){ 
    ... 
// i am making call for Async 
new ImgDown().execute(url); 
//and then i calling functions and classes to draw with that picture bubbleIcon ! 
DrawOnMap(bubbleIcon); 
} 




//THIS IS ASYNC AND FOR EX. SUPPOSE I NEED TO DOWNLOAD THE PIC FIRST 
    class ImgDown extends AsyncTask<String, Void, Bitmap> { 

     private String url; 

     public ImgDown() { 
     } 

     @Override 
     protected Bitmap doInBackground(String... params) { 
      url = params[0]; 
      try { 
       return getBitmapFromURL(url); 
      } catch (Exception err) { 
      } 

      return null; 

     } 

     @Override 
     protected void onPostExecute(Bitmap result) { 
      bubbleIcon = result; 
      bubbleIcon = Bitmap 
        .createScaledBitmap(bubbleIcon, 70, 70, true); 

     } 

     public Bitmap getBitmapFromURL(String src) { 
      try { 
       Log.e("src", src); 
       URL url = new URL(src); 
       HttpURLConnection connection = (HttpURLConnection) url 
         .openConnection(); 
       connection.setDoInput(true); 
       connection.connect(); 
       InputStream input = connection.getInputStream(); 
       // /tuka decode na slika vo pomalecuk kvalitet! 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inSampleSize = 3; 
       Bitmap myBitmap = BitmapFactory 
         .decodeStream(new FlushedInputStream(input)); 
       Log.e("Bitmap", "returned"); 
       return myBitmap; 
      } catch (IOException e) { 
       e.printStackTrace(); 
       Log.e("getBitmapFromURL", e.getMessage()); 
       return null; 
      } 
     } 

     class FlushedInputStream extends FilterInputStream { 
      public FlushedInputStream(InputStream inputStream) { 
       super(inputStream); 
      } 

      public long skip(long n) throws IOException { 
       long totalBytesSkipped = 0L; 
       while (totalBytesSkipped < n) { 
        long bytesSkipped = in.skip(n - totalBytesSkipped); 
        if (bytesSkipped == 0L) { 
         int byteValue = read(); 
         if (byteValue < 0) { 
          break; // we reached EOF 
         } else { 
          bytesSkipped = 1; // we read one byte 
         } 
        } 
        totalBytesSkipped += bytesSkipped; 
       } 
       return totalBytesSkipped; 
      } 
     } 
    } 

我現在希望更清晰。

+0

,請複製粘貼相關的源代碼。如果僅提供非正式描述,則無法提供幫助。 –

+0

我編輯了帖子。請參閱 – user1730007

+0

使用進度對話框 – WillingLearner

回答

32
class OpenWorkTask extends AsyncTask { 

    @Override 
    protected Boolean doInBackground(String... params) { 
     // do something 
     return true; 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 
     // The results of the above method 
     // Processing the results here 
     myHandler.sendEmptyMessage(0); 
    } 

} 

Handler myHandler = new Handler() { 

    @Override 
    public void handleMessage(Message msg) { 
     switch (msg.what) { 
     case 0: 
      // calling to this function from other pleaces 
      // The notice call method of doing things 
      break; 
     default: 
      break; 
     } 
    } 
}; 
+6

你是人!非常感謝,那就是我一直在尋找的。感謝一個很多人!你是最好的 – user1730007

+1

歡迎你 – RookieWen

+0

真的很好的代碼是...非常感謝你的朋友... –

2
class openWorkTask extends AsyncTask<String, String, Boolean> { 

    @Override 
    protected Boolean doInBackground(String... params) { 
     //do something 
     return true; 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 
     // The results of the above method 
     // Processing the results here 
    } 
} 
+0

我不能在那裏處理結果,我有幾個不同的從其他pleaces調用這個函數,所以..我需要一個方法來知道什麼時候AsyncTask將結束。 – user1730007

+0

當網絡數據採集完成時間 – RookieWen

+0

時,您可以發送HandlerMessage我該怎麼做?你能舉個例子嗎? – user1730007

0

如果我是你,我會使用進度對話框。這樣用戶可以在ASyncTask下載圖片時看到發生了什麼。在PostExecute上,調用主代碼中的方法來檢查圖片是否爲空。記住,你不能更新doInBackground方法的UI所以做任何UI工作,無論是onPreExecute或onPostExecute

private class DownloadPictures extends AsyncTask<String, Void, String> 
{ 

    ProgressDialog progressDialog; 

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

     //Download your pictures 

     return null; 

    } 

    @Override 
    protected void onPostExecute(String result) 
    { 

     progressDialog.cancel(); 

     //Call your method that checks if the pictures were downloaded 

    } 

    @Override 
    protected void onPreExecute() { 

     progressDialog = new ProgressDialog(
       YourActivity.this); 
     progressDialog.setMessage("Downloading..."); 
     progressDialog.setCancelable(false); 
     progressDialog.show(); 

    } 

    @Override 
    protected void onProgressUpdate(Void... values) { 
     // Do nothing 
    } 

} 
5

您可以編寫自己的代表委託信息關於完成任務,使用OOP原則:

task_delegate.java

public interface TaskDelegate { 
    void TaskCompletionResult(String result); 
} 

main_activity.java

public class MainActivity extends Activity implements TaskDelegate { 

    //call this method when you need  
    private void startAsynctask() { 
     myAsyncTask = new MyAsyncTask(this); 
     myAsyncTask.execute(); 
    } 

//your code 

    @Override 
    public void TaskCompletionResult(String result) { 
     GetSomethingByResult(result); 
    } 
} 

my_asynctask.java

public class MyAsyncTask extends AsyncTask<Void, Integer, String> { 

    private TaskDelegate delegate; 

    protected MyAsyncTask(TaskDelegate delegate) { 
     this.delegate = delegate; 
    } 

    //your code 

    @Override 
    protected void onPostExecute(String result) { 

     delegate.TaskCompletionResult(result); 
    } 
}