【问题标题】:Separate Class for OkHttp RequestsOkHttp 请求的单独类
【发布时间】:2019-12-27 21:27:23
【问题描述】:

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

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

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

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

我想到的唯一解决方案是在单独的类中同步实现请求,并在我正在工作的类的 AsyncTask 中调用该单独的类。

我是否监督某些事情?有没有办法创建一个单独的类并且仍然使用 OkHttp 入队方法?

【问题讨论】:

  • 你能显示一些代码吗
  • 给你,我添加了相关函数的代码

标签: android asynchronous okhttp3 apprequests


【解决方案1】:

您可以将makePremix(Premix premix) 提取到一个单独的类中并将sendRequest() 公开(或者根据您的用例可能是包私有)。

public void sendRequest(String url, JSONObject json)

但是,由于sendRequest 是通用的,并且可以被其他类中的任何其他makeAnotherCall() 使用,因此您需要获取每个请求的结果。因此,您可以从 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 客户端。您可能可以通过缓存客户端并重用它来优化内存。

【讨论】:

  • 感谢您的回答。这对我来说很有意义。但是,我实际上希望有一个解决方案,允许我也将 sendRequest() 方法放入单独的类中。
  • 我不关注 sendRequest 并且 makePremix 现在可以在不同的类中。
  • 有一个类说HttpManager,它保持一个okhttp客户端并暴露sendRequest。从另一个班级说PremixRepository(这将有makePremise调用sendRequest
  • 对不起,我可能解释错了。我想将 makePremix() 和 sendRequest() 放在一个类中,但与其余代码分开。让我们这两种方法都在类 HttpManager 中,现在在我的其他类中我希望能够做一些类似 HttpManager.makePremix(premix1)
  • 只需将回调作为参数即可。 HttpManager.makePremise(premix, callback)。这将让 HttpManager 处理线程逻辑。
猜你喜欢
  • 1970-01-01
  • 2020-06-21
  • 2016-11-23
  • 1970-01-01
  • 2020-03-28
  • 2019-08-27
  • 1970-01-01
  • 2019-04-12
  • 1970-01-01
相关资源
最近更新 更多