2012-02-25 28 views

Trả lời

13

Mở tùy chọn là sử dụng các thính giả, nơi bạn tạo ra một giao diện mà implents hoạt động của bạn, một cái gì đó như:

public interface AsyncListener { 
    public void doStuff(MyObject obj); 
} 

Bằng cách đó, nếu bạn đang phân lớp AsyncTask, thật dễ dàng để thêm người nghe này, sau đó trong onPostExecute(), bạn có thể làm điều gì đó như:

protected void onPostExecute(MyObject obj) { 
    asyncListener.doStuff(obj); 
} 
6

Điều này phụ thuộc vào cấu trúc lớp của bạn, nhưng nếu AsyncTask của bạn là một lớp trong Activity của bạn thì bạn có thể tham chiếu các phương thức của hoạt động đó. Những gì bạn sẽ làm là trong phương pháp onPostExecute bạn gọi một chức năng của hoạt động của bạn mà đi một số dữ liệu đã được lấy ra trong AsyncTask đến hoạt động nơi sau đó bạn có thể sử dụng nó ..

Mã này sẽ trông như thế này

class YourActivity extends Activity { 
    private static final int DIALOG_LOADING = 1; 

    public void onCreate(Bundle savedState) { 
    setContentView(R.layout.yourlayout); 
    showDialog(DIALOG_LOADING);  
    new LongRunningTask1().execute(1,2,3); 

    } 

    protected Dialog onCreateDialog(int dialogId) { 
    switch(dialogId) { 
     case DIALOG_LOADING: 
      ProgressDialog pDialog = new ProgressDialog(this); 
      pDialog.setTitle("Loading Data"); 
      pDialog.setMessage("Loading Data, please wait..."); 
      return pDialog; 
     default: 
      return super.onCreateDialog(dialogId); 
     }  
    } 

    private void onBackgroundTaskDataObtained(List<String> results) { 
     dismissDialog(DIALOG_LOADING); 
    //do stuff with the results here.. 
    } 

    private class LongRunningTask extends AsyncTask<Long, Integer, List<String>> { 
     @Override 
     protected void onPreExecute() { 
      //do pre execute stuff 
     } 

     @Override 
     protected List<String> doInBackground(Long... params) { 
      List<String> myData = new ArrayList<String>(); 
      for (int i = 0; i < params.length; i++) { 
       try { 
        Thread.sleep(params[i] * 1000); 
        myData.add("Some Data" + i); 
       } catch(InterruptedException ex) { 
       }     
      } 
      return myData; 
     } 

     @Override 
     protected void onPostExecute(List<String> result) { 
      YourActivity.this.onBackgroundTaskDataObtained(result); 
     }  
    } 

} 

Vì vậy, dòng chảy điển hình là như thế này, đặt chế độ xem của trang hiện tại và sau đó hiển thị hộp thoại tiến trình. Ngay sau đó bắt đầu nhiệm vụ async (hoặc bất cứ khi nào, nó không quan trọng thực sự).

Sau khi tác vụ không đồng bộ của bạn hoàn tất, hãy gọi một chức năng của hoạt động và chuyển dữ liệu đó. Không sử dụng dữ liệu được chia sẻ trong tác vụ không đồng bộ hoặc bạn có nguy cơ gặp vấn đề với luồng. Thay vào đó, khi bạn đã hoàn thành, hãy chuyển nó đến hoạt động. Nếu bạn muốn cập nhật quan điểm dần trong khi làm việc bạn có thể sử dụng trên onProgressUpdate

+0

Cảm ơn câu trả lời của bạn. Tôi không phải là fan của AsyncTask đang được sử dụng như một lớp phụ. Tôi nghĩ bạn sẽ có thể sử dụng các sự kiện. Tôi nghĩ rằng câu trả lời là sử dụng ý định nhưng tôi sẽ chỉ tạo ra một trường hợp mới của hoạt động của tôi mà tôi không muốn. – skinnybrit51

+0

Bạn có thể dễ dàng sử dụng AsyncTask trong lớp riêng của mình, nhưng điều đó chỉ hữu ích nếu bạn đang sử dụng cùng một logic đó từ nhiều hoạt động khác nhau. Trong trường hợp này, bạn có thể: 1. sử dụng một lớp cơ sở chung (không hoạt động hoạt động) và sau đó bạn có một phương thức chung có thể được gọi từ tác vụ không đồng bộ. Hoặc tốt hơn nhưng có cả hai thực hiện một giao diện chung mà có gọi lại như tôi mô tả. Chuyển tham chiếu đến hoạt động vào hàm khởi tạo của AsyncTask và đảm bảo asyncTask có một hàm tạo có tham số của kiểu giao diện. –

+0

Tùy chọn cuối cùng của bạn là mương AsyncTask hoàn toàn và đặt nó vào một dịch vụ mà bạn cần tạo một luồng mới để thực hiện hoạt động nền (vì các dịch vụ sẽ không chạy trong chuỗi riêng theo mặc định). Một cách dễ dàng để làm điều này là tạo một IntentService tạo ra một luồng mới cho bạn. –

Các vấn đề liên quan