无法在空对象引用上销毁活动LocationTrack.stopListener()'

时间:2017-06-16 07:12:16

标签: android android-fragments

在我的Android应用程序中,我在启动画面中获取GPS位置并存储在会话中。在基于位置的片段中,我从数据库中获取数据,如果用户想要更改点击操作栏上的位置,则会转到SelectLocationActivity按钮检测我的位置。

如果用户单击按钮,它会获取位置并存储在会话中,但如果使用单击后退按钮而不对Activity执行任何操作,则我的应用程序崩溃,错误无法破坏活动。

我的代码:

public class SelectLocationActivity extends AppCompatActivity {

private Button detcbtn;

private Session session;

private ArrayList<String> permissionsToRequest;
private ArrayList<String> permissionsRejected = new ArrayList<>();
private ArrayList<String> permissions = new ArrayList<>();

private final static int ALL_PERMISSIONS_RESULT = 101;
LocationTrack locationTrack;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.selectlocation);

    Toolbar toolbar = (Toolbar) findViewById(R.id.stoolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);

    session = new Session(SelectLocationActivity.this);

    detcbtn = (Button) findViewById(R.id.find_location);

    detcbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            permissionsToRequest = findUnAskedPermissions(permissions);
            //get the permissions we have asked for before but are not granted..
            //we will store this in a global list to access later.

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (permissionsToRequest.size() > 0) {
                    requestPermissions(permissionsToRequest.toArray(new String[permissionsToRequest.size()]), ALL_PERMISSIONS_RESULT);
                } else {
                    SetUserLocation();
                }
            }else{SetUserLocation();}

        }
    });

}

public void SetUserLocation() {
    locationTrack = new LocationTrack(SelectLocationActivity.this);

    if (locationTrack.canGetLocation()) {
        double longitude = locationTrack.getLongitude();
        double latitude = locationTrack.getLatitude();

        Geocoder gcd = new Geocoder(SelectLocationActivity.this, Locale.getDefault());
        List<Address> addresses = null;
        try {
            addresses = gcd.getFromLocation(latitude, longitude, 1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (addresses != null && addresses.size() > 0) {
            String locality = addresses.get(0).getLocality();
            String subLocality = addresses.get(0).getSubLocality();
            String address = addresses.get(0).getAddressLine(0);
            String state = addresses.get(0).getAdminArea();
            String countryn = addresses.get(0).getCountryName();
            String postalCode = addresses.get(0).getPostalCode();
            String knownName = addresses.get(0).getFeatureName();


            session.setLocation(latitude, longitude, locality, subLocality);

            Toast.makeText(SelectLocationActivity.this,locality +" "+ subLocality, Toast.LENGTH_SHORT).show();
        }
    } else {
        locationTrack.showSettingsAlert();
    }
    //go to main activity
    SetLocation();
}

public void SetLocation(){
    Intent intent = new Intent(SelectLocationActivity.this,MainActivity.class);
    startActivity(intent);
    finish();
}

///GPS Tracker
private ArrayList<String> findUnAskedPermissions(ArrayList<String> wanted) {
    ArrayList<String> result = new ArrayList<String>();

    for (String perm : wanted) {
        if (!hasPermission(perm)) {
            result.add(perm);
        }
    }

    return result;
}

private boolean hasPermission(String permission) {
    if (canMakeSmores()) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED);
        }
    }
    return true;
}

private boolean canMakeSmores() {
    return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}


@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

    switch (requestCode) {

        case ALL_PERMISSIONS_RESULT:
            for (String perms : permissionsToRequest) {
                if (!hasPermission(perms)) {
                    permissionsRejected.add(perms);
                }
            }

            if (permissionsRejected.size() > 0) {


                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (shouldShowRequestPermissionRationale(permissionsRejected.get(0))) {
                        showMessageOKCancel("These permissions are mandatory for the application. Please allow access.",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                            requestPermissions(permissionsRejected.toArray(new String[permissionsRejected.size()]), ALL_PERMISSIONS_RESULT);
                                        }
                                    }
                                });
                        return;
                    }else{SetUserLocation();}
                }
            }else{SetUserLocation();}
            break;
    }

}

private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(SelectLocationActivity.this)
            .setMessage(message)
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", null)
            .create()
            .show();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    locationTrack.stopListener();
}

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return true;
}
}

在后退按钮上单击它转到我的片段。我需要在片段中创建任何OnResume方法吗?

请参阅错误报告

06-16 12:21:28.061 22173-22173/zesteve.com.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
                                                                           Process: zesteve.com.myapplication, PID: 22173
                                                                           java.lang.RuntimeException: Unable to destroy activity {zesteve.com.myapplication/zesteve.com.myapplication.SelectLocationActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void zesteve.com.myapplication.location.LocationTrack.stopListener()' on a null object reference
                                                                               at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3861)
                                                                               at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3879)
                                                                               at android.app.ActivityThread.access$1500(ActivityThread.java:166)
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1414)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                               at android.os.Looper.loop(Looper.java:148)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5468)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                            Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void zesteve.com.myapplication.location.LocationTrack.stopListener()' on a null object reference
                                                                               at zesteve.com.myapplication.SelectLocationActivity.onDestroy(SelectLocationActivity.java:189)
                                                                               at android.app.Activity.performDestroy(Activity.java:6793)
                                                                               at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1143)
                                                                               at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3848)
                                                                               at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3879) 
                                                                               at android.app.ActivityThread.access$1500(ActivityThread.java:166) 
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1414) 
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                               at android.os.Looper.loop(Looper.java:148) 
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5468) 
                                                                               at java.lang.reflect.Method.invoke(Native Method) 
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

3 个答案:

答案 0 :(得分:1)

当用户点击检测按钮时,将创建locationTrack对象。当用户返回时没有单击检测按钮,locationTrack对象为null。 所以你必须把条件放在onDestroy方法中,如下所示:

@Override
protected void onDestroy() {
    super.onDestroy();
    if(locationTrack!=null)
       locationTrack.stopListener();
}

答案 1 :(得分:0)

听起来像设计错误的代码。检查locationTrack是空的或不是您的责任。

而且,如果您没有点击detcbtn,则不会初始化locationTrack并导致同样的崩溃。

答案 2 :(得分:0)

正如Dhiren所说,在stopListener之前检查nullability或在onCreate方法中实例化对象以确保该对象不为null。