2013-03-26 14 views
11

Tôi gặp vấn đề về khái niệm liên quan đến lớp học AsyncTask. Chúng tôi sử dụng AsyncTask để giao diện người dùng chính không bị chặn. Nhưng giả sử, tôi muốn lấy một số dữ liệu từ bộ nhớ của thiết bị và tôi sử dụng lớp AsyncTask cho việc này. Dòng tương ứng của mã sẽ như sau (giả sử kiểu dữ liệu trả về là String):Trả lại dữ liệu từ AsyncTask mà không chặn UI

//code 
    String data = new ExtendedAsyncTask().execute(param1, param2).get(); 
    //use this returned value. 

Sẽ không có người dòng ở trên chặn các giao diện người dùng, đánh bại mục đích của việc sử dụng các AsyncTask? Nếu có, thì làm cách nào để nhận dữ liệu có liên quan mà không chặn giao diện người dùng? Tôi muốn thêm rằng dòng mã tiếp theo sẽ cần dữ liệu này để thực hiện một số tác vụ và do đó phụ thuộc vào giá trị trả lại.

Cảm ơn

+0

AsyncTask giải thích bởi google: https://developer.android.com/guide/components/processes-and-threads.html#AsyncTask –

Trả lời

17

get() method will block the UI thread. Để lấy dữ liệu relavent bạn cần trả về giá trị từ doInBackground và nắm bắt giá trị trong tham số onPostExecute.

Giá trị trả về bởi doInBackground được chụp bằng phương pháp onPostExecute

Ví dụ:

public class BackgroundTask extends AsyncTask<String, Integer, String >{ 
     private ProgressDialog mProgressDialog; 
     int progress; 
     public BackgroundTask() { 
      mProgressDialog = new ProgressDialog(context); 
      mProgressDialog.setMax(100); 
      mProgressDialog.setProgress(0); 
    } 

     @Override 
    protected void onPreExecute() { 
      mProgressDialog =ProgressDialog.show(context, "", "Loading...",true,false); 
     super.onPreExecute(); 
    } 
    @Override 
    protected void onProgressUpdate(Integer... values) { 
    setProgress(values[0]); 
    } 

    @Override 
    protected String doInBackground(String... params) { 
      String data=getDatafromMemoryCard();  

     return data; // return data you want to use here 
    } 
    @Override 
    protected void onPostExecute(String result) { // result is data returned by doInBackground 
     Toast.makeText(context, result, Toast.LENGTH_LONG).show(); 
     mProgressDialog.dismiss(); 
     super.onPostExecute(result); 
    } 
    } 

Nếu bạn đang sử dụng AsyncTask trong lớp riêng biệt, sau đó sử dụng AsyncTask với giao diện callback như thế này

Đây là câu trả lời tôi đã cung cấp trước đó về cùng một AsyncTask with Callback

+0

Tôi không muốn hiển thị dữ liệu đó, tôi muốn sử dụng dữ liệu đó. Tôi có kết quả tương tự như của bạn khi tôi googled vấn đề của tôi. – Rajat

+0

@addresseerajat Đọc câu trả lời hoàn toàn ..Hai dòng cuối cùng thảo luận về AsyncTask với gọi lại, đi đến liên kết một lần – Pragnani

+0

Ok, tôi có một số ý tưởng mơ hồ, nhưng tôi muốn dữ liệu này được chuyển đến luồng giao diện người dùng chính. – Rajat

0

Bạn không nhận được kết quả theo cách này. Xem liên kết này cho một ví dụ: https://github.com/levinotik/ReusableAsyncTask/tree/master/src/com/example

Về cơ bản, đây là những gì bạn cần làm:

  • Xác định một giao diện (= một người biết lắng nghe) mà hoạt động của bạn thực hiện
  • Đặt người nghe trong AsyncTask
  • Gọi yourListener.yourMethod() trong onPostExecute
0

Khi một nhiệm vụ không đồng bộ được thực thi, nhiệm vụ đi qua 4 bước sau:

1.onPreExecute(), invoked on the UI thread before the task is executed. use this to diaply progress dialog. 

2.doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. Can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step. 

3.onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). Used to publish progress. 

4.onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter. 

Trong hoạt động của bạn onCreate()

TextView tv; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    tv= (TextView)findViewById(R.id.textView); 
    new TheTask().execute(); 

    } 
class TheTask extends AsyncTask<Void, Void,String> { 

    protected void onPreExecute() { 
    //dispaly progress dialog 
} 

protected String doInBackground(Void... params) { 
    //do network operation 
    return "hello"; 
} 

protected void onPostExecute(String result) { 
    //dismiss dialog. //set hello to textview 
     //use the returned value here. 
    tv.setText(result.toString()); 
} 
} 

Xem xét sử dụng robospice (Một thay thế cho AsyncTask. https://github.com/octo-online/robospice.

Thực hiện cuộc gọi không đồng bộ, Thông báo trên chuỗi ui.