使用接口更新全局变量

Update global variable by using a interface

我的 MainActivity.java

中有一个异步 class
class Register extends AsyncTask<String, String, JSONObject> {
JSONObject json;

     @Override
     protected JSONObject doInBackground(String[] args) {

         String function = args[3];
         String email = args[2];
         String password = args[1];
         String name = args[0];

         ContentValues params = new ContentValues();
         params.put("username", name);
         params.put("password", password);
         params.put("function", function);
         if (email.length() > 0)
             params.put("email", email);

         String URL = "https://lamp.ms.wits.ac.za/home/s2090704/index.php";
         new PhpHandler().makeHttpRequest(act, URL, params, new RequestHandler() {
             @Override
             public void processRequest(String response) throws JSONException {
                json = new JSONObject(response);
                 System.out.println(json); //outputs {response: " ...",message:"..."}


             }
         });
         System.out.println(json); //outputs null
         return json;
     }
}

在 doInBackground() 中,PhpHandler 使用 OkHttp 处理细节。

public class PhpHandler {

    JSONObject json;
    static String responseData = "";

    public void makeHttpRequest(final Activity a, String url,
                                      ContentValues params, final RequestHandler rh) {

        // Making HTTP request
            OkHttpClient client = new OkHttpClient();
            FormBody.Builder builder = new FormBody.Builder();

            for (String key : params.keySet()) {
                builder.add(key, params.getAsString(key));
            }

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

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

                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    responseData = Objects.requireNonNull(response.body()).string();
                    //System.out.println(responseData);
                   a.runOnUiThread(new Runnable() {
                       @Override
                       public void run() {
                           try {
                               rh.processRequest(responseData);
                           } catch (JSONException e) {
                               e.printStackTrace();
                           }
                       }
                   });
                }
            });

    }
}

RequestHandler是处理mainUiThread请求的接口。

package com.example.registration;

import org.json.JSONException;

public interface RequestHandler{
   void processRequest(String response) throws JSONException;
}

现在 json 不会更新我的异步 class Register.I 的 doInBackground 方法中的 processRequest 方法 Register.I 知道接口使变量静态和最终有什么方法可以更新json?

的值

processRequest 方法将在您从 doInBackground return json 很久之后执行,因为 makeHttpRequest 执行异步 http 请求。

知道这一点,你可能会想重新设计这个class(没有必要在AsyncTask中包装已经异步的请求),但如果你真的想这样做,您必须等待请求完成才能 returning json(例如,通过使用 CountDownLatch)。

  CountDownLatch latch = new CountDownLatch(1);
  someField = null;
  AtomicReference<String> someValue = new AtomicReference<>();

  // don't start new threads like this, im just trying to keep this example simple
  new Thread() {
    Thread.sleep(1000); // sleep for 1 second
    someValue.set("abc"); // notice that because when using AtomicReference you assign it's value using `set` method instead of `=` operator, you can keep it as local variable instead of field class
    latch.countDown(); // reduce latch count by one
  }.run();

  System.out.println(someValue.get()); // null - because the assignation will happen in one second

  latch.await(); // this will force current thread to wait until the latch count reaches zero (initial was 1, passed to constructor)

  System.out.println(someValue.get()); // "abc"

read more