【问题标题】:AndroidNetworking.post() doesn't wait the response data before returning via stringAndroidNetworking.post() 在通过字符串返回之前不会等待响应数据
【发布时间】:2020-03-23 21:55:45
【问题描述】:

我在 aar 模块中有一个函数,需要使用 AndroidNetworking 等待 onResponse()onError() 响应。输出是 return 在等待它收到的任何响应之前首先执行。我在等待响应返回我的应用程序时遇到问题。我还在函数上使用了synchronized。这是我模块上的代码

 public static synchronized String getActivationData(final Context context, final String api, final String base64Header, final String endpoint, final JSONObject body) {

    final String[] result = {null};

    new Thread(new Runnable() {
        @Override
        public void run() {
            StrictMode.ThreadPolicy policy =
                    new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);


            String baseURL = null;

            if (api.equalsIgnoreCase("LOCAL")) {
                baseURL = Environments.getMarkLocalAPI();
            } else if (api.equalsIgnoreCase("DEVELOPMENT")) {
                baseURL = Environments.getDevelopmentAPI();
            } else if (api.equalsIgnoreCase("STAGING")) {
                baseURL = Environments.getStagingAPI();
            } else if (api.equalsIgnoreCase("DEPLOYMENT")) {
                baseURL = Environments.getDeploymentAPI();
            }

            final String finalBaseURL = baseURL;


            OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                    .connectTimeout(15, TimeUnit.SECONDS)
                    .readTimeout(15, TimeUnit.SECONDS)
                    .writeTimeout(15, TimeUnit.SECONDS)
                    .build();

            AndroidNetworking.initialize(context, okHttpClient);

            AndroidNetworking.post(finalBaseURL + endpoint)
                    .setPriority(Priority.HIGH)
                    .addJSONObjectBody(body)
                    .addHeaders("Project", base64Header)
                    .addHeaders("Content-Type", "application/json")
                    .build()
                    .getAsJSONObject(new JSONObjectRequestListener() {

                        @Override
                        public void onResponse(JSONObject response) {
                            result[0] = String.valueOf(response);
                        }

                        @Override
                        public void onError(ANError anError) {
                            if (anError.getErrorCode() != 0) {
                                result[0] = String.valueOf(anError.getErrorDetail());

                            } else {
                                result[0] = String.valueOf(anError.getErrorDetail());
                            }
                        }
                    });
            Log.i("data", result[0]);
        }
    }).start();
    return result[0];
}

并通过以下方式在我的应用程序上调用该函数:

String data = ActivationResponseV2.getActivationData(getContext(), "LOCAL", header, "/sample/response", jsonObject);

我可以知道我做错了什么吗?谢谢!

【问题讨论】:

  • 您显然是在新创建的线程之外返回结果,该线程仍在AndroidNetworking.post 之外,并且肯定会在发布回调之前触发。
  • @GiddyNaya 我怎样才能把它退回里面?当我把它放进去时它给了我一个错误
  • 将回调传递给方法以在您的 post 调用中使用 result[0] 的值,而不是返回它。
  • 我可以举个例子吗?抱歉新手回调
  • See here 将回调传递给函数

标签: android multithreading synchronization android-networking


【解决方案1】:

我已经使用ANRequest 完成了它。阅读this 文件后。我试图复制它并得到我想要的输出。

这是代码:

 public static synchronized String getActivationData(final Context context, final String api, final String base64Header, final String endpoint, final JSONObject body) {

    final String[] result = {null};

    String baseURL = null;

    if (api.equalsIgnoreCase("LOCAL")) {
        baseURL = Environments.getMarkLocalAPI();
    } else if (api.equalsIgnoreCase("DEVELOPMENT")) {
        baseURL = Environments.getDevelopmentAPI();
    } else if (api.equalsIgnoreCase("STAGING")) {
        baseURL = Environments.getStagingAPI();
    } else if (api.equalsIgnoreCase("DEPLOYMENT")) {
        baseURL = Environments.getDeploymentAPI();
    }

    final String finalBaseURL = baseURL;


    OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
            .connectTimeout(15, TimeUnit.SECONDS)
            .readTimeout(15, TimeUnit.SECONDS)
            .writeTimeout(15, TimeUnit.SECONDS)
            .build();

    AndroidNetworking.initialize(context, okHttpClient);

    ANRequest request = AndroidNetworking.post(finalBaseURL + endpoint)
            .setPriority(Priority.HIGH)
            .addJSONObjectBody(body)
            .addHeaders("Project", base64Header)
            .addHeaders("Content-Type", "application/json")
            .build();


    ANResponse response = request.executeForJSONObject();

    if (response.isSuccess()) {
        result[0] = String.valueOf(response.getResult());
        Log.d(TAG, "response : " + result[0]);
    } else {
        ANError error = response.getError();
        Log.d(TAG, "response : " + error);
    }

    return result[0];
    }
}

编码愉快!

【讨论】:

    【解决方案2】:

    响应在 post 调用之外返回:要处理此问题,您可以将回调方法传递给您的函数,以便在结果准备好时使用它。

    public static void getActivationData(final Context context, 
           final String api, final String base64Header, final String endpoint,
             final JSONObject body, Callable<Void> methodParam) { 
                String baseURL = null;
    
                if (api.equalsIgnoreCase("LOCAL")) {
                    baseURL = Environments.getMarkLocalAPI();
                } else if (api.equalsIgnoreCase("DEVELOPMENT")) {
                    baseURL = Environments.getDevelopmentAPI();
                } else if (api.equalsIgnoreCase("STAGING")) {
                    baseURL = Environments.getStagingAPI();
                } else if (api.equalsIgnoreCase("DEPLOYMENT")) {
                    baseURL = Environments.getDeploymentAPI();
                } 
    
    
                OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                        .connectTimeout(15, TimeUnit.SECONDS)
                        .readTimeout(15, TimeUnit.SECONDS)
                        .writeTimeout(15, TimeUnit.SECONDS)
                        .build();
    
                AndroidNetworking.initialize(context, okHttpClient);
    
                AndroidNetworking.post(baseURL + endpoint)
                        .setPriority(Priority.HIGH)
                        .addJSONObjectBody(body)
                        .addHeaders("Project", base64Header)
                        .addHeaders("Content-Type", "application/json")
                        .build()
                        .getAsJSONObject(new JSONObjectRequestListener() {
    
                            @Override
                            public void onResponse(JSONObject response) {
                                //result[0] = String.valueOf(response);
                                methodParam.call(String.valueOf(response));
                            }
    
                            @Override
                            public void onError(ANError anError) {
                                if (anError.getErrorCode() != 0) {
                                   // result[0] = String.valueOf(anError.getErrorDetail()); 
                                } else {
                                    //result[0] = String.valueOf(anError.getErrorDetail());
                                }
                                methodParam.call(String.valueOf(anError.getErrorDetail()));
                            }
                        });
                 // Log.i("data", result[0]); 
      }
    

    像下面这样使用

    ActivationResponseV2.getActivationData(getContext(), "LOCAL", header, 
               "/sample/response", jsonObject, new Callable<Void>() {
                    public Void call(String data) {
                        //...Consume data here
                        return null;
                    });
    

    【讨论】:

    • 你好。到目前为止,我已经尝试将它放在我的 aar 上。但它提示“java.util.concurrent.Callable中的call()不能应用于java.lang.String”
    • 更改为public Void call(String data)
    猜你喜欢
    • 2019-02-20
    • 2022-12-20
    • 1970-01-01
    • 2017-10-12
    • 2021-08-02
    • 2020-04-20
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    相关资源
    最近更新 更多