Невозможно получить доступ к переменной вне ее области видимости - PullRequest
0 голосов
/ 28 июня 2018

Когда я пытаюсь напечатать значение долготы в строке log("11111111", longitude);, оно работает хорошо и показывает мне значение. Однако, когда я пытаюсь напечатать его на log.e(22222222", longitude);, я получаю NullPointerException.

Я знаю, что я получил исключение нулевого указателя, так как log.e ("2222222", долгота) вызван перед addOnCompleteListner. но что я должен сделать, чтобы дождаться окончания addOnCompleteListner и затем получить доступ к значению

Вот мой код:

package com.example.karem.currentlocation;

import android.Manifest;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

class GetMyCoordinate extends Application {

    Context context;

    GetMyCoordinate(Context context) {
        this.context = context;
    }

    private Boolean mLocationPermissionsGranted = false;
    private FusedLocationProviderClient mFusedLocationProviderClient;

    String longitude;

    String getDeviceLocation() {

        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);

        try {

            final Task location = mFusedLocationProviderClient.getLastLocation();
            location.addOnCompleteListener(new OnCompleteListener() {
                @Override
                public void onComplete(@NonNull Task task) {
                    if (task.isSuccessful()) {

                        Location currentLocation = (Location) task.getResult();
                        longitude = String.valueOf(currentLocation.getLongitude());
                        Log.e("1111111111", longitude);

                    }
                }
            });

            Log.e("22222222", longitude);


        } catch (SecurityException e) {
        }
        return longitude;
    }
}

Ответы [ 4 ]

0 голосов
/ 28 июня 2018

Решение этой проблемы может быть легко достигнуто с помощью интерфейса.

1 - сначала определите интерфейс

public interface ILocationReceived {

onLocationRecieved(String longitude);

}

2 - передать этот интерфейс методу

 public void getDeviceLocation(ILocationRecieved locationRecieved) {

}

3 - У вас в асинхронном методе передается полученное местоположение

locationRecieved.onLocationRecieved(longitude);

4 - При реализации метода просто получите долготу.

new GetMyCoordinate().getDeviceLocation( longitude -> 
// here you get your longitude from the async method.
// use it as you need
print (longitude) 

);

ПРИМЕЧАНИЕ : Написал это безо всякой идеи, чтобы оно могло содержать некоторую синтаксическую ошибку.

0 голосов
/ 28 июня 2018

Функции прослушивателя по своей природе асинхронны, поэтому все, что вы определяете или назначаете, действительно в области действия асинхронных функций. Поэтому, если вы попытаетесь получить к нему доступ вне его области действия, вы получите значение, которое находится в этой области. Поскольку вы только что объявили «долготу», его значение равно Null, поэтому вы получите исключение нулевого указателя. если вы инициализировали его некоторым значением, скажем «x», то вы получите x, напечатанный из оператора Log, имеющего 2222222 в качестве 1-го аргумента.

Надеюсь, это очистит ваше сомнение

0 голосов
/ 28 июня 2018

Проблема на самом деле в переключении потоков, а не в случае выхода из области видимости, как указано выше Стивеном C . Происходит следующее: когда ваш код входит в блок try {}, вы перенесли элемент управления в (FusedLocationProviderClient и добавили прослушиватель) до тех пор, пока не будет получен ответ о вашем местоположении из фонового потока. Поток вызывающего абонента не может ждать для этого. Таким образом, он продолжает печатать log.e («22222222», долгота) (когда ответ не получен), и поэтому возникает случай нулевого значения.

0 голосов
/ 28 июня 2018

Проблема не в том, что вы думаете. Переменная longitude равна в области действия (не "совок"!) В обоих местах.

Фактическая проблема заключается в том, что в утверждении:

    log.e(22222222", longitude);

вы обращаетесь к переменной longitude до ее инициализации. Инициализация выполняется при вызове метода onComplete. Это происходит, когда Task, на который ссылается location, завершается.

(Должен быть другой ключ. Если вы посмотрите журналы, вы, вероятно, увидите, что сообщение журнала «22222222» появляется до сообщения журнала «11111111».)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...