7

こんにちは、あなたの助けに感謝します。

ネットからデータを取得するためにをmethod呼び出すがあります。AsyncTask

method 順番に数回呼び出されるため、複数のAsyncTasksを起動します

を起動するたびにmethod、相対的なAsyncTaskから正しい結果を取得する必要があります(前後に呼び出された他のAsyncTaskからではありません)。

どんな助けでも大歓迎です。


編集編集編集編集残りのコードを追加しました。

注意:プロセス全体がサービス内で実行されます。

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は非同期であり、別のスレッドで実行されます。したがって、AsyncTaskを実行した後、次のステートメントでAsyncTaskの結果を取得することはできません。

AsyncTaskから相対的な結果を取得するには、UpdateTaskPriceクラスにメンバー変数 "mRequestId"を追加し、UpdateTaskPrice.executeを呼び出す前に、一意のリクエストIDを設定します。

UpdateTaskPriceクラスの「onPostExecute」メソッドでは、このリクエスト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

さて、のコンストラクターで一意のリクエストIDを渡すことができると思います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 に答える
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..とpost..を実行します。

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 に答える