7

您好,感谢您的帮助。

我有一个method调用 anAsyncTask从网上检索一些数据的方法。

method 依次调用多次,因此启动了几个AsyncTasks 。

从每次启动时,method我都需要从相关的 AsyncTask (而不是从之前或之后调用的其他 AsyncTask )中获取正确的结果。

非常感谢任何帮助。


编辑 编辑 编辑 编辑 添加了其余代码。

请注意:整个过程在Service中运行。

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;
    }
}
4

3 回答 3

10

AsyncTask is asynchronous and run in a separate thread. So it is not possible to get the result of AsyncTask in very next statement after you execute it.

To get the relative results from AsyncTask, add a member variable "mRequestId" in your UpdateTaskPrice class and before calling UpdateTaskPrice.execute, set unique request ID.

in "onPostExecute" method of your UpdateTaskPrice class, you can return and process result using this Request Id.

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;
    }
}
于 2013-03-25T13:51:05.660 回答
0

你可以从多个 asynctask 中获取数据,但是你想要结果的地方用 asyctask 是不可能的,你需要使用更多的封装来构造这个问题。

你的结构的问题是......

 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;
}

当您启动新线程时,它将首先执行在 task.execute(symbol); 之后返回的语句 在您的情况下,它是 return 语句,然后它将执行 pre.. doin.. 并发布...

Hear 是可用于从多个 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;
    }
}

希望有所帮助。

于 2013-04-03T06:38:39.230 回答
0

好吧,我认为您可以在AsyncTask. 然后在postExecute()方法中,使用结果和唯一的请求 ID 更新 UI -

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;
    }
}
于 2013-04-02T19:23:53.573 回答