2017-06-16 104 views
0

在我的android应用程序中,我在启动屏幕中获取GPS位置并存储在会话中。在我的基于位置的片段中,我从数据库中提取数据,如果用户想要在点击操作栏上更改位置,则它将跳转到SelectLocationActivity有按钮检测我的位置。无法销毁空对象上的活动LocationTrack.stopListener()'参考

如果用户点击按钮,它的获取位置和会话存储,但如果使用单击后退按钮与出上做活动的任何行动,我的应用程序得到错误无法破坏活动坠毁。

我的代码:

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)  

回答

1

locationTrack对象将被创建检测按钮,当用户点击。当用户返回而没有点击检测按钮时,locationTrack对象为空。 所以你必须把条件的onDestroy方法象下面这样:

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

完成任务。谢谢你的完美 –

0

听起来像一个坏的设计代码。检查locationTrack为空或不是您的责任。

还有,如果你没有点击detcbtn,locationTrack不会被初始化,将再次导致死机一样。

+0

是的,我知道了,谢谢 –

0

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