【发布时间】:2015-01-06 20:38:13
【问题描述】:
我正在寻找一些类似于 Activity.onPause() 的回调,但更通用(我没有 Activity,因为此代码在后台运行)在我的应用程序被杀死之前调用。我不会尝试 Application.onLowMemory() ,因为根据文档,它并不总是被调用[我的意思是当我通过返回或主页按钮退出某些活动时,我的应用程序也可能(而且我知道有时会)被杀死]。
我的应用程序中有一个 LocationListener 类,它进行了一些非常繁重的计算,因此我使用了一些“缓存”或优化。只有当位置发生很大变化或经过足够的时间时,我才会进行繁重的计算。
我注意到,大多数时候,即使我不移动手机,我的繁重计算代码也会一次又一次地被调用。事实证明,这是因为 oldLocation 为空(我的应用程序被 android 杀死)该应用程序工作,因为它被 LocationService 唤醒,但它“忘记”了缓存的 lastLocation (=null)。所以我添加了 saveLastLocation() 这确实有帮助,但我试图找出最好的调用位置。一开始我从 finalize() 中调用它,但它从未被调用过。似乎android“太快”地杀死了我的应用程序,以至于无法调用它。然后我把它移到了它现在的位置,就在繁重的计算之后。
我想知道是否有一种方法,类似于我在 Activity 中使用 onPause() 调用 saveLastLocation 并使用 onResume 调用 loadLastLocation 的理想方法。
我将 MyLocationListener 的实例作为 MyApplication 的静态成员(用于缓存目的)
class MyLocationListener implements LocationListener {
private static MyLocationListener instance;
private Location lastLocation;
public static MyLocationListener getInstance() {
if (null == instance) {
instance = new MyLocationListener();
}
return instance;
}
private MyLocationListener() {
loadLastLocation();
}
@Override
public synchronized void onLocationChanged(final Location location) {
if (null == lastLocation || lastLocation.distanceTo(location) > MIN_LOCATION_CHANGE_DISTANCE
|| getElapsedNanoSec(location) - getElapsedNanoSec(lastLocation) > MIN_LOCATION_CHANGE_NANOSEC) {
// Just to see how many times we enter the heavy calculations
Toast.makeText(MyApp.getContext(), "old: " + lastLocation + "new: " + location, Toast.LENGTH_LONG).show();
// do the heavy calculations
lastLocation = location;
// Is there a better way to call saveLastLocation???
saveLastLocation();
}
}
private synchronized void saveLastLocation() {
final SharedPreferences sharedPreferences = getSharedPreferences();
SharedPreferences.Editor editor = sharedPreferences.edit();
if (null != lastLocation) {
editor.putString(PREF_LAST_LOCATION_PROVIDER, lastLocation.getProvider());
editor.putLong(PREF_LAST_LOCATION_ELAPSED_REALTIME, getElapsedNanoSec(lastLocation));
putDouble(editor, PREF_LAST_LOCATION_LATITUDE, lastLocation.getLatitude());
putDouble(editor, PREF_LAST_LOCATION_LONGITUDE, lastLocation.getLongitude());
editor.apply();
}
}
private synchronized void loadLastLocation() {
final SharedPreferences sharedPreferences = getSharedPreferences();
final String provider = sharedPreferences.getString(PREF_LAST_LOCATION_PROVIDER, null);
if (null != provider) {
final long elapsed = sharedPreferences.getLong(PREF_LAST_LOCATION_ELAPSED_REALTIME, Long.MIN_VALUE);
final double latitude = getDouble(sharedPreferences, PREF_LAST_LOCATION_LATITUDE, Double.MIN_VALUE);
final double longitude = getDouble(sharedPreferences, PREF_LAST_LOCATION_LONGITUDE, Double.MIN_VALUE);
if (null == lastLocation) {
lastLocation = new Location(provider);
} else {
lastLocation.setProvider(provider);
}
setElapsedNanoSec(lastLocation, elapsed);
lastLocation.setLatitude(latitude);
lastLocation.setLongitude(longitude);
}
}
private long getElapsedNanoSec(final Location location) {
long elapsed;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
elapsed = location.getElapsedRealtimeNanos();
} else {
elapsed = location.getTime() * 1000;
}
return elapsed;
}
}
澄清一下:谷歌播放服务没有直接调用 MyLocationListener,我有另一个“真实”的 LocationListener 正在被调用,我从它的 onLocationChanged 调用 MyLocationListener.getInstance().onLocationChanged(location) [我这样做的原因这是我在代码中的许多地方使用大量计算的结果(通过调用此处未提供的其他函数),我希望它尽可能多地缓存]
【问题讨论】:
-
繁重的计算是依赖旧位置还是只用于确定距离变化?
-
只用于优化,不做繁重的计算。计算本身只使用当前位置(除了我打印“你从
移动到 ”的日志,但可以忽略它。
标签: android caching sharedpreferences onpause