2

ネットから Json を取得するために AsyncTask を作成したクラスがあります。

public class MyAsyncGetJsonFromUrl extends AsyncTask<Void, Void, JSONObject> {
    Context context_;
    String url_;
    List<NameValuePair> params_;

    public MyAsyncGetJsonFromUrl(Context context_, List<NameValuePair> params_, String url_) {
        this.context_ = context;
        this.params_ = params_;
        this.url_ = url_;
    }

    @Override
    protected JSONObject doInBackground(Void... params) {
        JSONObject jObj_ = null;
        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url_);
            httpPost.setEntity(new UrlEncodedFormEntity(params_));

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            InputStream is_ = httpEntity.getContent();

            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is_.close();
            String json_ = sb.toString();
            Log.e("JSON", json);

            jObj_ = new JSONObject(json_);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return jObj_;
    }

    protected void onPostExecute(JSONObject jObj_) {
        jObj = jObj_;
    }
}

また、このクラスには、メソッドを呼び出しているアクティビティにこの Json オブジェクトを返すメソッドがあります。

public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {
    new MyAsyncGetJsonFromUrl(context, params, url).execute();
    return jObj;
}

問題は、AsyncTask を開始したnew MyAsyncGetJsonFromUrl(context, params, url).execute();直後に行return jObj;が呼び出され、null が返されることです。したがって、非同期タスクが完了するまで実行を停止したいと思います。このシナリオとまったく同じ質問は他にないため、この質問を重複として言及しないでください。

4

1 に答える 1

6

非同期タスクは非同期です。これは、プログラムの現在のスレッドとは関係なく、バックグラウンドで実行されることを意味します (バックグラウンド スレッドで実行されます)。したがって、非同期タスクが完了するまで、プログラムの実行を停止しようとしないでください。

したがって、2 つのオプションがあります。

  • 非同期タスクではなく、UI スレッド自体でコードを実行する

  • 非同期タスクonPostExecute()メソッドから値を割り当てます

非同期タスクを使用してオプション B を使用することにした場合は、非同期タスクの最後に JSON オブジェクトの値を割り当てることができ、後でアクセスできる静的変数またはそのようなものを使用できます。メソッド自体で JSON オブジェクトに対して必要な後処理を行うこともできますonPostExecute()(例: オブジェクトを解析してユーザーに表示する)。このメソッドは、非同期タスクが操作を完了した後に UI スレッドで実行されるためです。バックグラウンド スレッド。

非同期タスクからの戻り値が必要な場合は、次のようにすることができます。

jObj = new MyAsyncGetJsonFromUrl(context, params, url).execute().get(); 

この場合、プログラムは計算が完了するまで待機しますが、(メモリの制約などにより) スレッドが中断またはキャンセルされるなどの例外がある場合を除きます。しかし、このアプローチは一般的に推奨されていません。非同期タスクのポイントは、非同期操作を許可することであり、それが原因でプログラムの実行を停止してはなりません。

戻り値はdoInBackground()、パラメータとしてOnPostExecute()メソッドに渡されます。onPostExecute は UI スレッド自体で実行されるため、戻り値を入れる必要はありません。結果を使用して、必要なことを行うだけです。

于 2012-11-02T09:38:57.033 に答える