无法访问超出其范围的变量

时间:2018-06-28 07:57:02

标签: java android variables null

当我尝试在行log("11111111", longitude);上打印经度值时,它工作良好,并向我显示了该值。但是,当我尝试在log.e(22222222", longitude);上打印时,会得到NullPointerException

我知道在addOnCompleteListner之前调用了空指针异常原因log.e(“ 2222222”,经度)。 但是我应该怎么做才能等到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 :(得分:0)

问题不在于您的想法。 longitude变量在两个范围内都是 (不是“ scoop”!)。

实际的问题是在语句中:

    log.e(22222222", longitude);

您正在初始化变量longitude。调用onComplete方法时完成初始化。当Task所指的location完成时就会发生这种情况。

(应该有另一个线索。如果查看日志,您可能会发现“ 22222222”日志消息出现在“ 11111111”日志消息之前。)

答案 1 :(得分:0)

侦听器函数本质上是异步的,因此您定义或分配的任何内容在异步函数范围内均有效。因此,如果您尝试访问其范围之外的值,则将获得该范围内的值。正如您刚刚声明的“经度”,它的值为Null,因此您将获得null指针异常。如果将其初始化为某个值,则说“ x”,则将从具有2222222作为第一个参数的Log语句中打印x。

希望它消除了您的疑问

答案 2 :(得分:0)

问题实际上出在线程切换上,而不是 Stephen C 所提到的超出范围的情况。发生的情况是,当您的代码进入try {}块时,您已将控件转移到了(FusedLocationProviderClient并添加了侦听器),直到响应从后台线程到达您的位置为止。您的调用者线程无法等待它。因此,实际上它继续打印log.e(“ 22222222”,经度)(当响应尚未到达时),这就是为什么出现空值情况的原因。

答案 3 :(得分:0)

解决方案可以通过界面轻松实现。

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) 

);

注意:编写时没有任何想法,因此可能包含一些语法错误。