Изменение локальной переменной внутри метода, когда метод выполняется, переменная не изменяется - PullRequest
0 голосов
/ 15 июня 2019

Я работаю над приложением для Android.У меня есть эта форма, когда кнопка нажата, он выполняет метод с именем insertData ().Внутри этой функции я меняю локальную переменную под названием «адрес» другой функцией getAddress ().

Внутри функции getAddress локальная переменная «адрес» успешно изменяется.Но когда мы входим в функцию insertData (), переменная «address» по-прежнему содержит старые данные в этом случае «Location Unknown».

Что я здесь не вижу?

insertData ()

public String address = "Location unknown";

public boolean insertData(String title, String description, String image, Double longitude, Double latitude, String date) {
    String location = Double.toString(longitude) + "," + Double.toString(latitude);
    getAddress(location);
    Log.d("TAG2", address); // Still "Location unknown"
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL_2, title);
    contentValues.put(COL_3, description);
    contentValues.put(COL_4, image);
    contentValues.put(COL_5, longitude);
    contentValues.put(COL_6, latitude);
    contentValues.put(COL_7, date);
    contentValues.put(COL_8, address);
    long result = db.insert(TABLE_NAME, null, contentValues);
    if (result == -1)
        return false;
    else
        return true;

}

getAddress ()

    public void getAddress(String coordination) {

    String token = "{removed for a reason haha}";
    String url = "https://api.mapbox.com/geocoding/v5/mapbox.places/" + coordination + ".json?access_token=" + token;

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder().url(url).build();

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

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if(response.isSuccessful()) {
                String data = response.body().string();
                JsonParser parser = new JsonParser();

                try {
                    JsonObject obj = (JsonObject) parser.parse(data);
                    JsonArray arr = obj.getAsJsonArray("features");
                    JsonObject objj = arr.get(2).getAsJsonObject();
                    String place = objj.get("place_name").getAsString();
                        address = place;
                        Log.d("TAG", address); // Gives an address
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

Logcat Debugger

2019-06-15 20:12:58.968 31465-31465/com.example.triptracker D/TAG2: Location unkown
2019-06-15 20:12:59.269 31465-31569/com.example.triptracker D/TAG: Mountain View, California, United States

Я не могу изменить метод onResponse () для возврата String.Я не знаю почему, но это метод только для чтения.

getAddress {изменен}

    public void getAddress(String coordination) {

    String token = "{empty}";
    String url = "https://api.mapbox.com/geocoding/v5/mapbox.places/" + coordination + ".json?access_token=" + token;

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder().url(url).build();

    try (Response response = client.newCall(request).execute()) {
        String data = response.body().string();
        JsonParser parser = new JsonParser();

        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

        JsonObject obj = (JsonObject) parser.parse(data);
        JsonArray arr = obj.getAsJsonArray("features");
        JsonObject objj = arr.get(2).getAsJsonObject();
        String place = objj.get("place_name").getAsString();
        address = place;
        Log.d("TAG", address);
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

1 Ответ

2 голосов
/ 15 июня 2019

getAddress() выполняет свою работу асинхронно. Ко времени возврата getAddress() ваш HTTP-запрос не будет завершен, и поэтому address еще не изменится.

Так как insertData() выполняет дисковый ввод-вывод, вы должны вызывать insertData() в его собственном фоновом потоке, поэтому вы не замораживаете пользовательский интерфейс во время работы дискового ввода-вывода. Если это так, то вы можете использовать OkHttp синхронно, используя execute() вместо enqueue(). Это позволит вам getAddress() вернуть адрес, чтобы вы могли вставить его в свою базу данных.

...