2013-03-25 40 views
7

Xin chào và cảm ơn sự giúp đỡ của bạn.Nhận kết quả từ một số AsyncTasks

Tôi có số method gọi số AsyncTask để truy xuất một số dữ liệu từ mạng.

methodđược gọi nhiều lần theo trình tự và do đó khởi chạy một số AsyncTasks.

Từ mỗi lần khởi chạy của method Tôi cần lấy lại kết quả chính xác từ AsyncTask tương đối (và không phải từ một số AsyncTask khác được gọi trước hoặc sau).

Bất kỳ trợ giúp nào được đánh giá cao.


CHỈNH SỬA CHỈNH SỬA CHỈNH SỬA CHỈNH SỬA Đã thêm phần còn lại của mã.

Xin lưu ý: toàn bộ quá trình chạy bên trong Dịch vụ .

public static class UpdateService extends Service { 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     int[] appWidgetIds = intent.getIntArrayExtra("widgetsids"); 
     final int N = appWidgetIds.length; 
     AppWidgetManager manager = AppWidgetManager.getInstance(this); 
     for (int i = 0; i < N; i++) { 
      int appWidgetId = appWidgetIds[i]; 
      Log.e("","i="+Integer.toString(i)+ " di "+Integer.toString(N)); 
      RemoteViews view = buildUpdate(getApplicationContext(), 
        appWidgetIds); 
      manager.updateAppWidget(appWidgetId, view); 
     } 
     return (START_NOT_STICKY); 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 
} 

private static RemoteViews buildUpdate(Context ctxt, int[] appWidgetIds) { 
    RemoteViews updateViews = new RemoteViews(ctxt.getPackageName(), 
      R.layout.widget); 
     updateViews.setTextViewText(R.id.price1, getPrice(list.get(0) 
      .getSymbol())); 

}   
    //THIS METHOD IS CALLED SEVERAL TIMES IN SEQUENCE <---- 
    private static String getPrice(String symbol) { 
    String result=""; 
    UpdateTaskPrice up = new UpdateTaskPrice(); 
    up.execute(symbol, null, null); 
    //HERE I WANT THE RESULT FROM onPostExecute() <---- 
    return result; 
} 

//THIS IS THE ASYNCTASK WHICH IS LAUNCHED SEVERAL TIMES 
public class UpdateTaskPrice extends AsyncTask<String, Void, String> { 

    @Override 
    protected void onProgressUpdate(Void... progress) { 
    } 

    @Override 
    protected void onPostExecute(String result) { 
    //HERE I RECEIVE THE RESULT FROM doInBackground <---- 
    //I NEED TO PASS IT BACK TO getPrice() <---- 
    } 

    @Override 
    protected String doInBackground(String... symbol) { 
     String result = ""; 
     DefaultHttpClient client = new DefaultHttpClient(); 
     String srt = ""; 

     String url = context.getString(R.string.urlaternativo).concat(
       symbol[0]); 

     HttpGet getMethod = new HttpGet(url); 
     try { 
      ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
      srt = client.execute(getMethod, responseHandler); 
      int inizio = srt.indexOf("<last data=\""); 
      int fine = srt.indexOf("\"/>", inizio + 12); 
      result = srt.substring(inizio + 12, fine); 

     } catch (Throwable t) { 
      // Log.e("ERROR", "ERROR", t); 
     } 
     //HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute() <---- 
     return result; 
    } 
} 
+1

Có thể thực hiện được nhưng không được khuyến nghị qua 'Asynctask.get() ', tôi đã giải thích API đặc biệt này nhiều hơn một chút trong [câu trả lời này] (http://stackoverflow.com/questions/8921244/return-data-from -asynctask-android/8922074 # 8922074). – yorkw

+0

Tại sao bạn không chỉ chuyển RemoteViews vào UpdateTaskPrice AsyncTask của bạn trong hàm khởi tạo của nó và 'setTextViewText' bên trong onPostExecute? Bằng cách này, mỗi AsyncTask đều biết View nào sẽ cập nhật và thậm chí bạn sẽ không cần kết quả –

+0

sử dụng một intentservice. đó là đủ đồng bộ. – njzk2

Trả lời

10

AsyncTask không đồng bộ và chạy trong một chuỗi riêng biệt. Vì vậy, bạn không thể lấy kết quả của AsyncTask trong câu lệnh tiếp theo sau khi bạn thực thi nó.

Để nhận kết quả tương đối từ AsyncTask, hãy thêm biến thành viên "mRequestId" vào lớp UpdateTaskPrice của bạn và trước khi gọi UpdateTaskPrice.execute, hãy đặt ID yêu cầu duy nhất.

trong phương thức "onPostExecute" của lớp UpdateTaskPrice, bạn có thể trả về và xử lý kết quả bằng cách sử dụng Id yêu cầu này.

public class UpdateTaskPrice extends AsyncTask<String, Void, String> { 

    protected int mRequestId; 

    public void setRequestId (int requestId) 
    { 
     this.mRequestId = requestId; 
    } 

    @Override 
    protected void onProgressUpdate(Void... progress) { 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     // do whatever with result using mRequestId 
    } 

    @Override 
    protected String doInBackground(String... symbol) { 
     String result = ""; 
     DefaultHttpClient client = new DefaultHttpClient(); 
     String srt = ""; 

     String url = context.getString(R.string.urlaternativo).concat(
       symbol[0]); 

     HttpGet getMethod = new HttpGet(url); 
     try { 
      ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
      srt = client.execute(getMethod, responseHandler); 
      int inizio = srt.indexOf("<last data=\""); 
      int fine = srt.indexOf("\"/>", inizio + 12); 
      result = srt.substring(inizio + 12, fine); 

     } catch (Throwable t) { 
      // Log.e("ERROR", "ERROR", t); 
     } 
     //HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute() <---- 
     return result; 
    } 
} 
+0

Cảm ơn rất nhiều! Tôi nghi ngờ tôi đã phải làm một cái gì đó như thế. Xin vui lòng tôi yêu cầu bạn nếu bạn có thể xây dựng thêm một chút câu trả lời bởi vì tôi không hoàn toàn chắc chắn làm thế nào tôi có thể vượt qua kết quả và requestId để 'getPrice'method. Cảm ơn một lần nữa! –

+1

AsyncTasks được dự định chạy ở chế độ nền. Để hiển thị kết quả được trả về bằng phương thức getPrice, bạn cần cập nhật chế độ xem Hoạt động của mình. phương thức onPostExecute chạy trong luồng chính của Activity. Nếu bạn chuyển tham chiếu đến hoạt động của mình trong UpdateTaskPrice (giống như mRequestId), thì bạn có thể truy cập chế độ xem Hoạt động trong phương thức onPostExecute. Bạn cũng có thể gọi một phương thức khác của hoạt động của bạn chịu trách nhiệm phân tích cú pháp kết quả và hiển thị giá được phân tích cú pháp từ kết quả – Amit

+0

Cảm ơn bạn. Tôi nhận được nó và tôi không nhận được nó ... Xin vui lòng Amit bạn sẽ được như vậy loại để cho tôi biết làm thế nào tôi nên sửa đổi mã? Cảm ơn! –

0

Vâng, tôi nghĩ bạn có thể chuyển id yêu cầu duy nhất trong hàm tạo của AsyncTask. Sau đó, trong phương pháp postExecute(), cập nhật giao diện người dùng với kết quả và yêu cầu id duy nhất -

public class UpdateTaskPrice extends AsyncTask<String, Void, String> { 

    private int mIdentifier; 
    private Service mService; 

    public UpdateTaskPrice(Service service, int identifier) { 
     this.mIdentifier = identifier; 
    } 

    @Override 
    protected void onProgressUpdate(Void... progress) { 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     ((UpdateService) mService).informPrice(mIdentifier, result); 
    } 

    @Override 
    protected String doInBackground(String... symbol) { 
     String result = ""; 
     DefaultHttpClient client = new DefaultHttpClient(); 
     String srt = ""; 

     String url = context.getString(R.string.urlaternativo).concat(
       symbol[0]); 

     HttpGet getMethod = new HttpGet(url); 
     try { 
      ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
      srt = client.execute(getMethod, responseHandler); 
      int inizio = srt.indexOf("<last data=\""); 
      int fine = srt.indexOf("\"/>", inizio + 12); 
      result = srt.substring(inizio + 12, fine); 

     } catch (Throwable t) { 
      // Log.e("ERROR", "ERROR", t); 
     } 
     //HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute() <---- 
     return result; 
    } 
} 
0

Bạn có thể lấy dữ liệu từ nhiều AsyncTask, nhưng nơi bạn muốn kết quả là không thể với asyctask, bạn cần phải sử dụng đóng gói nhiều hơn để cấu trúc vấn đề này.

vấn đề với cấu trúc của bạn là ...

private static String getPrice(String symbol) { 
    String result=""; 
    UpdateTaskPrice up = new UpdateTaskPrice(); 
    up.execute(symbol, null, null); 
    //HERE I WANT THE RESULT FROM onPostExecute() <---- 
    return result; 
} 

khi bạn đang bắt đầu thread mới nó đầu tiên sẽ thực hiện báo cáo kết quả đó là sự trở lại sau task.execute (biểu tượng); trong trường hợp của bạn nó là câu lệnh return và sau đó nó sẽ exucute trước .. doin .. và sau ...

Nghe là mô hình mà bạn có thể sử dụng để lấy dữ liệu từ nhiều AsycTask

//Calling to the method callAsyncTask; 
callAsyncTask(new AsyncResultCallback(){ 
    public void onResult(String result, String symbol){ 
     //TODO dosomthing with the result 
    } 
}); 


public void callAsyncTask(AsyncResultCallback callback){ 
    new UpdateTaskPrice(callback).execurte(symbol); 
} 

public interface AsyncResultCallback{ 
    public void onResult(String result, String symbol); 
} 

public class UpdateTaskPrice extends AsyncTask<String, Void, String> { 

    AsyncResultCallback callback; 
    String symbol; 

    UpdateTaskPrice(AsyncResultCallback callback){ 
     this.callback = callback; 
    } 

    @Override 
    protected void onProgressUpdate(Void... progress) { 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     callback.onResult(result, symbol); 
    } 

    @Override 
    protected String doInBackground(String... symbol) { 
     this.symbol = symbol; 
     String result = ""; 
     DefaultHttpClient client = new DefaultHttpClient(); 
     String srt = ""; 

     String url = context.getString(R.string.urlaternativo).concat(symbol[0]); 

     HttpGet getMethod = new HttpGet(url); 
     try { 
      ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
      srt = client.execute(getMethod, responseHandler); 
      int inizio = srt.indexOf("<last data=\""); 
      int fine = srt.indexOf("\"/>", inizio + 12); 
      result = srt.substring(inizio + 12, fine); 

     } catch (Throwable t) { 
      // Log.e("ERROR", "ERROR", t); 
     } 
      //HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute() <---- 
     return result; 
    } 
} 

hy vọng rằng giúp đỡ.

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