【问题标题】:Getter Setter method being called at wrong order以错误的顺序调用 Getter Setter 方法
【发布时间】:2015-09-25 17:23:02
【问题描述】:

我需要一些帮助。我正在制作这个应用程序来解析圣经并将其显示在 webView 中。 我在应用程序中实现了后退下一个/段落功能。它调用了正确的 json 地址,但我在调用 getter 和 setter 的顺序上遇到了一些问题。

这是调用静态方法以获取字符串作为响应的代码块:

 String previousPassage = BackNextGo.getPassage
                    (currentChapter, chapterSelected);       
 L.m("previousPassage");

这是它调用的方法:

public class BackNextGo {

    private BackNextGo() {
    }

    private static String requestUrl;
    private static RequestQueue queue;

    private static String s;

    public static String getPassage(String data, int chapterSelected) {
        setRequestUrl(data, chapterSelected);
        queue = VolleySingleton.getInstance().getRequestQueue();
        sendJsonRequest();
        return getData();
    }

    private static void setRequestUrl(String s, int chapterSelected) {
        requestUrl = Constants.DISPLAY_DATA_URL_PART_1
                + s.replaceAll("\\s+", "").replaceAll("(\\d+)(?!.*\\d)",
                        String.valueOf(chapterSelected))
                        + Constants.DISPLAY_DATA_URL_PART_2 + Constants.BIBLE_API_KEY;
    }

    private static String getRequestUrl() {
        return requestUrl;
    }

    private static void sendJsonRequest() {
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET,
                getRequestUrl(), new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {

                if (response == null || response.length() == 0) {

                } else {

                    try {
                        setData(response
                                .getString(Constants.Keys.Books.KEY_SELECTED_CHAPTER));

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }

        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
            }
        });
        queue.add(request);
    }

    public static String getData() {
        counter++;
        L.m("getter method");
        return s;
    }

    private static void setData(String data) {
        s = data;
        L.m("setter method");
    }
}

我已经在 getter 和 setter 方法以及调用 BackNextPassage 静态类的方法上放置了祝酒词。

顺序是:

1) getter 方法

2) 调用代码块(字符串)

3) 设置方法

据我了解,顺序应该是:首先是setter方法。因为它是从“sendJsonRequest”方法中调用的,然后是 getData 或 getter 方法,最后是调用方法。

这很糟糕,因为每次我调用 BackNextPassage 类时,我都会获取上次调用设置的数据。任何帮助将不胜感激 =)

ps:

L("一些随机文本");这些是正常的祝酒词,例如: Toast.makeText(context, "........show();

更新!:

所以我尝试同步方法,但它只是挂起,直到应用程序崩溃...... 这是我的代码:(也许有人可以指出我的错误?=))

public class BackNextGo {

private static BackNextGo instance = null;
private String requestUrl;
private RequestQueue queue;
private String s;

private BackNextGo() {
}

public static BackNextGo getInstance() {
    if (instance == null) {
        instance = new BackNextGo();
    }
    return instance;
}

public String getPassage(String data, int chapterSelected) {
    setRequestUrl(data, chapterSelected);
    queue = VolleySingleton.getInstance().getRequestQueue();
    synchronized (this) {
        sendJsonRequest();

        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    return getData();
}

private void setRequestUrl(String s, int chapterSelected) {
    requestUrl = Constants.DISPLAY_DATA_URL_PART_1 + s.replaceAll("\\s+", "").replaceAll("(\\d+)(?!.*\\d)", String.valueOf(chapterSelected)) + Constants.DISPLAY_DATA_URL_PART_2 + Constants.BIBLE_API_KEY;
    System.out.println(requestUrl);
}

private String getRequestUrl() {
    return requestUrl;
}

private void sendJsonRequest() {
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, getRequestUrl()
            , new Response.Listener<JSONObject>() {

        @Override
        public void onResponse(JSONObject response) {

            if (response == null || response.length() == 0) {

            } else {

                try {
                    setData(response.getString(Constants.Keys.Books.KEY_SELECTED_CHAPTER));

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }

    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
        }
    });
    queue.add(request);
}

private void setData(String data) {
    synchronized (this) {
        s = data;
        notify();
    }
}

public String getData() {
    return s;
}
}

再一次......这是调用该类的代码:

String previousPassage = BackNextGo.getInstance().getPassage(currentChapter, chapterSelected);

【问题讨论】:

  • 不要做任何事static
  • 为了澄清上面的评论,当您的所有方法都是静态的时,通常表明您没有正确使用面向对象的原则。
  • 根据我对您的问题的了解,您应该在发出请求后设置 proviousPassage。您可以使用从调用类传递到 getPassage 方法的接口来执行此操作。本质上它是一个回调。
  • 我试试看,谢谢 =)

标签: java android methods static getter-setter


【解决方案1】:

所以在 BackNextGo 中创建你的界面

public class BackNextGo {

public interface OnData {
    public void updateData(String data);
}

private BackNextGo() {
}

private static String requestUrl;
private static RequestQueue queue;

private static String s;
private OnData sOnData = null;

public static String getPassage(String data, int chapterSelected, OnData onDataCallback) {
    sOnData = onDataCallback;
    setRequestUrl(data, chapterSelected);
    queue = VolleySingleton.getInstance().getRequestQueue();
    sendJsonRequest();
    return getData();
}

private static void setRequestUrl(String s, int chapterSelected) {
    requestUrl = Constants.DISPLAY_DATA_URL_PART_1
            + s.replaceAll("\\s+", "").replaceAll("(\\d+)(?!.*\\d)",
                    String.valueOf(chapterSelected))
                    + Constants.DISPLAY_DATA_URL_PART_2 + Constants.BIBLE_API_KEY;
}

private static String getRequestUrl() {
    return requestUrl;
}

private static void sendJsonRequest() {
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET,
            getRequestUrl(), new Response.Listener<JSONObject>() {

        @Override
        public void onResponse(JSONObject response) {

            if (response == null || response.length() == 0) {

            } else {

                try {
                    setData(response
                            .getString(Constants.Keys.Books.KEY_SELECTED_CHAPTER));

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }

    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
        }
    });
    queue.add(request);
}

public static String getData() {
    counter++;
    L.m("getter method");
    return s;
}

private static void setData(String data) {
    s = data;
    if(sOnData != null) {
        sOnData.updateData(data);
    }
    L.m("setter method");
}
}

然后在你的调用类中执行类似...

String previousPassage;
OnData onDataCallback = new OnData {
    public void updateData(String data) {
        previousPassage = data;
    }
};
BackNextGo.getInstance().getPassage(currentChapter, chapterSelected, onDataCallback);

【讨论】:

  • 是否可以进行活动并调用startActivityForResult?这样,我 100% 确定数据将在到达调用代码时设置。该活动显然没有视图(我只是在 Android 清单中指定)。我要问的是这样做会有效/可以吗?
  • 不,那是没有效率的。它不会解决任何问题。您将放入活动的代码仍然具有异步调用。您仍然需要调用活动中的接口来获取回调。你可以进入ReactiveX Android 但你也可以使用界面。
  • 好的,谢谢。我只是想知道因为我尝试过它并且它有效:/。但如果它没有效率,我想我不会再这样做了,再次感谢:)
【解决方案2】:

顺序:

1) getter 方法

2) 调用代码块(字符串)

3) 设置方法

没有错!这是意料之中的..让我详细说明一下..


你假设不是这样,主要是因为顺序

sendJsonRequest(); // 'setter' method in here
return getData();  // 'getter' method here

正在被调用。

但是,sendJsonRequest() 需要时间! 'setter' 方法仅在 onResponse(JSONObject response) 内调用,即 JSONRequest 完成时。

因此,一旦sendJsonRequest() 被启动,下一行return getData() 就会立即被调用!这就是为什么 'getter' 出现在 'setter' 之前的原因,除非 JSONRequest 完成得比这更快(这不太可能)。

基本上,不要在发出 JSON 请求后立即尝试获取数据。您应该等待请求完成,并发出某种回调通知请求者数据已准备好,请求者可以使用getData()获取数据。

【讨论】:

  • 那我应该怎么做?我已经尝试将 sendJsonRequest();在一个线程中并调用 thread.join();但我得到相同的结果。你建议我做什么?
  • @JoseMariaLanda 嗨,我对这些东西并不完全熟悉。也许你可以用谷歌搜索“异步任务”,因为 JSONObjectRequest 基本上是一个在后台运行的异步请求,不会影响你的主线程。您将需要某种方式通知调用者数据已准备好,调用者应仅在收到通知时尝试获取数据。
  • 我会尝试并发布我的结果。谢谢
  • @JoseMariaLanda 很抱歉不能提供更好的建议!希望你能尽快解决你的问题:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 2017-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多