为 OkHttp 请求单独 Class

Separate Class for OkHttp Requests

我使用 OkHttp 来请求我的树莓派。我正在考虑将请求放在单独的 class 中。

目前我有一种发送请求的方法。代码如下:

private void sendRequest(String url, JSONObject json) {
        Log.d(TAG, "sendRequest: Das Json: " + json);
        // Authentication for the request to raspberry
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.authenticator(new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) throws IOException {
                String credential = Credentials.basic("username", "password");
                return response.request().newBuilder()
                        .header("Authorization", credential)
                        .build();
            }
        });

        // Sending out the request to the raspberry
        OkHttpClient okHttpClient = client.build();

        RequestBody body = RequestBody.create(null, new byte[]{});
        if( json != null) {
            body = RequestBody.create(MediaType.parse(
                    "application/json"),
                    json.toString()
            );
        }

        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(LOG, "Big Fail");

                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                try {
                    ResponseBody responseBody = response.body();
                    if( !response.isSuccessful() ) {
                        Log.d(TAG, "onResponse: We are in !response.successful()");
                        throw new IOException("Response not successful: " + response );
                    }
                    Log.d(LOG, "onResponse: Response is: " + responseBody.string());
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.d(LOG, "onResponse: failed!" + e);
                }
            }
        });
    }

这里是一个如何调用 sendRequest() 函数的例子:

private void makePremixCall(Premix premix) {
        JSONArray jsonArray = new JSONArray();
        ArrayList<Premixable> usedPremixables = premix.getUsedPremixables();
        for(Premixable usedPremixable: usedPremixables) {
            try {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("Silo", usedPremixable.getmSilo());
                jsonObject.put("Gramm", usedPremixable.getmKgPerCow() * mFeeding.getmNumberOfCows());
                jsonArray.put(jsonObject);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("Components", jsonArray);
            sendRequest("http://192.168.178.49:5000/evaluatePost", jsonObject);
        } catch (JSONException e) {
            e.printStackTrace();
            Log.d(TAG, "makePremixCall: " + e);
        }
    }

我的问题是:我想要一个单独的 class,它提供函数 makePremix(Premix premix) 和我需要的其他函数。

我想到的唯一解决方案是在单独的 class 中同步执行请求,并在我工作的 class 中的 AsyncTask 中调用单独的 class。

我在监督什么吗?有没有办法创建一个单独的 class 并仍然使用 OkHttp enqueue 方法?

您可以在单独的 class 中提取 makePremix(Premix premix) 并制作 sendRequest() public(或者根据您的用例可能包私有)。

public void sendRequest(String url, JSONObject json)

然而,由于 sendRequest 是通用的,可以被任何其他 makeAnotherCall() 在其他 class 中使用,因此您需要取回每个请求的结果。因此,您可以从 sendRequest()

中提取回调
public void sendRequest(String url, JSONObject json, Callback callback)

现在你的 sendRequest 看起来像

private void sendRequest(String url, JSONObject json) {
        Log.d(TAG, "sendRequest: Das Json: " + json);
        // Authentication for the request to raspberry
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.authenticator(new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) throws IOException {
                String credential = Credentials.basic("username", "password");
                return response.request().newBuilder()
                        .header("Authorization", credential)
                        .build();
            }
        });

        // Sending out the request to the raspberry
        OkHttpClient okHttpClient = client.build();

        RequestBody body = RequestBody.create(null, new byte[]{});
        if( json != null) {
            body = RequestBody.create(MediaType.parse(
                    "application/json"),
                    json.toString()
            );
        }

        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        okHttpClient.newCall(request).enqueue(callback);
    }

希望它有意义!

另请注意,每次调用 sendRequest 时都会创建一个新的 OkHttp 客户端。您可以通过缓存客户端并重新使用它来优化内存。