字符串在匿名内部 Class 之外变为 null

String becomes null outside of Anonymous Inner Class

我正在用 google 的 FusedLocationClient 检索 LastKnowlocation 并将 userLocalityuserCountry 作为两个字符串存储在 OnsuccesListener 匿名中内部 class.

在下面的代码中:文本集在 locationProvidedTextView 中是正确的(因此 userLocalityuserCountry 得到一些值)但是当我尝试在内部 class 它们不知何故都变成了 null

这可能是一个愚蠢的问题,但是我做错了什么?我需要在另一个 OnclickListener 方法中使用这些值。

代码片段:

    // GlOBAL VARIABLES
   ....
   private  String userCountry;
   private  String userLocality;

@Override
protected void onCreate(Bundle savedInstanceState) {
      ....
 mFusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    // Got last known location. In some rare situations this can be null.
                    if (location != null) {
                        Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
                        try {
                            List<Address> addresses = geoCoder
        .getFromLocation(location.getLatitude(), location.getLongitude(), 1);

                            if (addresses.size() > 0) {
                                if (addresses.size() > 0) {
                                     userLocality = addresses.get(0).getLocality();
                                     userCountry = addresses.get(0).getCountryName();

                                    locationProvidedTextView.setText("Your address: " + userLocality + ", " + userCountry);

                                }
                            }
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }

                    }
                }
            });
 // HERE BOTH STRINGS BECOME NULL
    System.out.println("ADDRESS1 ======= " + userLocality);
    System.out.println("ADDRESS2 ======= " + userCountry);
          ....
   }

问题是您没有构建任何检索值的机制。换句话说,您的 onCreate 现在看起来像这样:

onCreate{
// set listener
// print stuff out
}

在调用侦听器后设置值,但此时您已经完成了 onCreate 方法。

这是正常的。

我不知道你的代码,但 addOnSuccessListener 似乎是一种异步机制。

所以你想在异步部分之外显示未设置的值。

换句话说,您试图显示一个尚未设置的值。

要对此进行测试,您可以输入: 在 addOnSuccessListener 里面 a:

System.out.println("User locality found");

您会看到该消息可能会在

之后发送
System.out.println("ADDRESS1 ======= " + userLocality);

获取位置需要一些时间。根据您的代码,您将立即打印 mFusedLocationClient.getLastLocation().addOnSuccessListener

您的监听器不会立即被调用。所以你不会在这些字符串中获得任何值。

更好的实现方式是,在另一个 class 中完成所有与位置相关的事情,而不是在 onCreate 中。然后使用 interface 得到结果后得到结果。

            @Override
            public void onSuccess(Location location) {
                // Got last known location. In some rare situations this can be null.
                if (location != null) {
                    Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
                    try {
                        List<Address> addresses = geoCoder
    .getFromLocation(location.getLatitude(), location.getLongitude(), 1);

                        if (addresses.size() > 0) {
                            if (addresses.size() > 0) {
                                 userLocality = addresses.get(0).getLocality();
                                 userCountry = addresses.get(0).getCountryName();

                                locationProvidedTextView.setText("Your address: " + userLocality + ", " + userCountry);

                            }
                        }
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }

我猜这个方法每次根据 GPS 准确获取坐标时都会将数据设置为 userLocality 和 userCountry,但是当 GPS 禁用或网络不强时,它可能会给出错误的读数,这可能导致获取空字符串变量在这里您应该尝试更改提供商和网络或 gps 提供商的准确性,这可能会有所帮助。