web-dev-qa-db-ja.com

Android Okhttp非同期呼び出し

Okhttpライブラリを使用して、API経由でAndroidアプリをサーバーに接続しようとしています。

ボタンのクリックでAPI呼び出しが発生し、次のAndroid.os.NetworkOnMainThreadExceptionが表示されます。これは、メインスレッドでネットワークコールを試行していることが原因であると理解していますが、Androidでこのコードが別のスレッドを使用する方法(非同期コール)に関する明確な解決策を見つけるのにも苦労しています)。

@Override
public void onClick(View v) {
    switch (v.getId()){
        //if login button is clicked
        case R.id.btLogin:
            try {
                String getResponse = doGetRequest("http://myurl/api/");
            } catch (IOException e) {
                e.printStackTrace();
            }
            break;
    }
}

String doGetRequest(String url) throws IOException{
    Request request = new Request.Builder()
            .url(url)
            .build();

    Response response = client.newCall(request).execute();
    return response.body().string();

}

上記は私のコードであり、例外が行にスローされています

Response response = client.newCall(request).execute();

私はOkhhtpが非同期リクエストをサポートしていることも読みましたが、Androidのクリーンな解決策は実際には見つかりません。ほとんどがAsyncTask <>を使用する新しいクラスを使用しているようです) ?

ヘルプや提案は大歓迎です、ありがとう...

8
jjharrison

非同期リクエストを送信するには、これを使用します:

void doGetRequest(String url) throws IOException{
    Request request = new Request.Builder()
            .url(url)
            .build();

    client.newCall(request)
            .enqueue(new Callback() {
                @Override
                public void onFailure(final Call call, IOException e) {
                    // Error

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // For the example, you can show an error dialog or a toast
                            // on the main UI thread
                        }
                    });
                }

                @Override
                public void onResponse(Call call, final Response response) throws IOException {
                    String res = response.body().string();

                    // Do something with the response
                }
            });
}

このように呼び出します:

case R.id.btLogin:
    try {
        doGetRequest("http://myurl/api/");
    } catch (IOException e) {
        e.printStackTrace();
    }
    break;
23