位置管理器removeUpdates NPE



我有一个非活动类MyLocation在搜索位置,它被称为表单MainActivity。当MainActivity为onPause()时,我想删除更新,但我得到了一个NPE,因为即使侦听器正在运行,它也为null。我知道我可以用if捕获NPE,但我的问题是为什么侦听器为空。

我正在呼叫主活动@onPause():

MyLocation myLocation = new MyLocation(MainActivity.this, this);
myLocation.removeListener();

在MyLocation中,我启动位置管理器,并希望停止使用方法removeListener():进行侦听

编辑:添加MyLocation的完整代码:

    public class MyLocation {
    LocationManager lm;
    LocationManager lmNetwork;
    LocationManager lmGPS;
    LocationResult locationResult;
    boolean gps_enabled = false;
    boolean network_enabled = false;
    Context context;
    static Activity activity;
    private String gps, network, strLocationProvider;
    static ProgressDialog progress;
    private final int interval = 30000;
    private Handler handler = new Handler();
    private Handler handler2 = new Handler();
    public MyLocation(MainActivity context, MainActivity activity) {
        this.context = context;
        MyLocation.activity = activity;
    }
    public boolean getLocation(Context context, LocationResult result) {
        // Create a progress bar to display while the list loads
        showLoadingDialog();
        // I use LocationResult callback class to pass location value from
        // MyLocation to user code.
        locationResult = result;
        if (lm == null)
            lm = (LocationManager) context
            .getSystemService(Context.LOCATION_SERVICE);
        // exceptions will be thrown if provider is not permitted.
        try {
            network_enabled = lm
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch (Exception ex) {
        }
        try {
            gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch (Exception ex) {
        }
        // don't start listeners if no provider is enabled
        if (!gps_enabled && !network_enabled)
            enableLocationServices(context);
        if (network_enabled)
            System.out.println("Network => enabled");
        lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
                locationListenerNetwork);
        if (gps_enabled)
            System.out.println("GPS => enabled");
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
                locationListenerGps);
        handler.postDelayed(locationfallback, interval);
        return true;
    }
    LocationListener locationListenerNetwork = new LocationListener() {
        public void onLocationChanged(Location location) {
            System.out
            .println("Provider => Network");
            locationResult.gotLocation(location);
            hideLoadingDialog();
            lm.removeUpdates(this);
            handler.removeCallbacks(locationfallback);
            //Continue searching for GPS for a defined time period
            handler2.postDelayed(GPSstopdelayed, interval);
        }
        public void onProviderDisabled(String provider) {
        }
        public void onProviderEnabled(String provider) {
        }
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
    };
    LocationListener locationListenerGps = new LocationListener() {
        public void onLocationChanged(Location location) {
            System.out
            .println("Provider => GPS");
            locationResult.gotLocation(location);
            hideLoadingDialog();
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerNetwork);
            handler.removeCallbacks(locationfallback);
        }
        public void onProviderDisabled(String provider) {
        }
        public void onProviderEnabled(String provider) {
        }
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
    };
    //Schedule GPS listener
    private Runnable GPSstopdelayed = new Runnable() {
        @Override
        public void run() {
            lm.removeUpdates(locationListenerGps);
        }
    };
    //Fallback if listeners don't find any location until handler timer elapses
    private Runnable locationfallback = new Runnable() {
        @Override
        public void run() {
            lm.removeUpdates(locationListenerGps);
            lm.removeUpdates(locationListenerNetwork);
            try {
                LocationManager lm = (LocationManager) context
                        .getSystemService(Context.LOCATION_SERVICE);
                Criteria criteria = new Criteria();
                criteria.setAccuracy(Criteria.ACCURACY_FINE);
                criteria.setAltitudeRequired(false);
                criteria.setBearingRequired(false);
                criteria.setCostAllowed(true);
                criteria.setPowerRequirement(Criteria.POWER_LOW);
                strLocationProvider = lm.getBestProvider(criteria, true);
                System.out
                .println("FallbackLocationProvider => " + strLocationProvider);
                Location location = lm
                        .getLastKnownLocation(strLocationProvider);
                if (location != null) {
                    locationResult.gotLocation(location);
                    // Highlight GPS or Network icon
                    String usedProvider = location.getProvider();
                    if (usedProvider.equals("gps")) {
                        //Do something
                    }
                    if (usedProvider.equals("network")) {
                        //Do something else
                    }
                    hideLoadingDialog();
                }
                if (location == null) {
                    hideLoadingDialog();
                    Toast.makeText(
                            activity,context.getResources()
                            .getString(R.string.place_not_found),
                                    Toast.LENGTH_LONG).show();
                }
                return;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    };
    public static abstract class LocationResult {
        public abstract void gotLocation(Location location);
    }
    public void enableLocationServices(final Context context) {
        // Show dialog to enable location services
        AlertDialog.Builder mAlertDialog = new AlertDialog.Builder(context);
        // Setting Dialog Title
        mAlertDialog
        // .setTitle(
        // context.getResources().getString(
        // R.string.location_not_available))
        .setMessage(
                context.getResources().getString(
                        R.string.enable_location_services))
                        .setPositiveButton(
                                context.getResources()
                                .getString(R.string.open_settings),
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog,
                                            int which) {
                                        Intent intent = new Intent(
                                                Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                        context.startActivity(intent);
                                        dialog.dismiss();
                                    }
                                }).show();
    }
    protected void removeListener() {
        handler.removeCallbacks(locationfallback);
        lm.removeUpdates(locationListenerGps);
        lm.removeUpdates(locationListenerNetwork);
    }
    protected void showLoadingDialog() {
        if (progress != null){
            progress.cancel();
            progress = ProgressDialog.show(activity, null, null, true, true);
            progress.setContentView(R.layout.progress_location_layout);
        } 
        if (progress == null){
            progress = ProgressDialog.show(activity, null, null, true, true);
            progress.setContentView(R.layout.progress_location_layout);
        }
    }
    protected void hideLoadingDialog() {
        if (progress != null && progress.isShowing()) {
            progress.cancel();
        }
    }
}

这是MainActivity的gotLocation(),它调用了一个方法来显示位置:

 LocationResult locationResult = new LocationResult() {
 @Override
 public void gotLocation(Location location) {
     if (location == null){
         tvcity.setText(R.string.notfound);
     }       
     if (location != null) {
         setLocation(location);
     }
 }
 };

这是日志:

10-08 14:16:22.805: W/dalvikvm(4939): threadid=1: thread exiting with uncaught  exception (group=0x40c87318)
10-08 14:16:22.805: E/AndroidRuntime(4939): FATAL EXCEPTION: main
10-08 14:16:22.805: E/AndroidRuntime(4939): java.lang.RuntimeException: Unable to pause activity {com.fleank.skybuddy/com.fleank.skybuddy.MainActivity}: java.lang.NullPointerException
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2842)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2798)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2776)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.app.ActivityThread.access$800(ActivityThread.java:134)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.os.Looper.loop(Looper.java:137)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.app.ActivityThread.main(ActivityThread.java:4744)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at java.lang.reflect.Method.invokeNative(Native Method)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at java.lang.reflect.Method.invoke(Method.java:511)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at dalvik.system.NativeStart.main(Native Method)
10-08 14:16:22.805: E/AndroidRuntime(4939): Caused by: java.lang.NullPointerException
10-08 14:16:22.805: E/AndroidRuntime(4939):     at com.fleank.skybuddy.MyLocation.removeListener(MyLocation.java:131)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at com.fleank.skybuddy.MainActivity.onPause(MainActivity.java:457)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.app.Activity.performPause(Activity.java:5106)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1225)
10-08 14:16:22.805: E/AndroidRuntime(4939):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2829)

看起来错误在MyLocation类和MainActivity中,我的赌注是,您启动该类的一个新实例,然后尝试访问位置侦听器,你能编辑你的帖子并发布MyLocation.java的全部代码吗?我认为,如果您保存对MyLocation实例的引用,并在onPause()方法中调用该实例,它就会起作用。

编辑

您在onPause()方法中启动了myLocation的一个新实例,并且在类中启动了位置侦听器,这意味着您至少有两个myLocation实例,因此还有两个LocaitonListener实例。您用其中一个开始位置更新,然后尝试用第二个停止位置更新。您可以做的是保存我所在位置的类变量,在onCreate中初始化它,并在onPause方法中使用它。类似的东西:

public class MainActivity extends Activity {
    private MyLocation mMyLocation;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMyLocation = new MyLocation(MainActivity.this, this);
    }
    @Override
    protected void onPause() {
        myLocation.removeListener();
        super.onPause();
    }
}

另一个与您现在所做的非常相似的选项是使用此处描述的Singleton设计模式:http://www.tutorialspoint.com/design_pattern/singleton_pattern.htm,我会使用我提出的第一个建议。

最新更新