使用接口更新全局变量

问题描述 投票:-1回答:1

我的MainActivity.java中有一个异步类

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不会从异步类Register的doInBackground方法的processRequest方法中更新。我知道接口使变量成为静态变量,而final是否有任何方法可以更新json的值?

java android android-asynctask java-native-interface okhttp
1个回答
0
投票

[processRequest方法将在您从json返回doInBackground后很长时间执行,因为makeHttpRequest执行异步HTTP请求。

知道这一点,您可能需要重新设计此类(不需要在AsyncTask中包装已经异步的请求),但是如果您确实想以这种方式这样做,则必须等待您的请求在返回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

© www.soinside.com 2019 - 2024. All rights reserved.