我有一个活动
,它扩展了一个名为LocationAware活动
的基本类
所有这些LocationAware活动
活动
所做的就是创建一个位置服务客户端
LocationServices。getFusedLocationProviderClient
和侦听位置更新。
这项活动的来源在这里https://github.com/snijsure/MultiActivity/blob/master/app/src/main/java/com/example/subodhnijsure/multiactivity/LocationAwareActivity.java
当活动被销毁时,它会调用
removeLocationUpdates
。我发现
removeLocationUpdate
返回的任务总是返回not successful
因此,问题是什么是停止接收位置更新的正确方法,从而允许垃圾收集
活动
。
此项目的完整来源可在此处访问-https://github.com/snijsure/MultiActivity
通过查看存储库中的代码,我发现了您的设计中的一些问题,这些问题可能会导致您的活动泄漏。
1)您正在使用两个不同的LocationCallback
。一个在开始,一个在停止方法中,但是您实际上应该使用相同的方法。所以一次实例化它就足够了,并且在删除LocationCallback
时可能也会导致您的任务
的成功结果。
2)由于您使用匿名类实例化了LocationCallback
两次,因此即使您完成了包含类,您也保留了内部类的非静态引用,这会导致您的Memory Leak
。您可以在这里阅读更多信息。
3) IMHO使用一个单独的manager类来处理位置请求比抽象一个活动
更好。
这是我的。。。
GPS管理员。JAVA
public class GpsManager extends LocationCallback {
private FusedLocationProviderClient client;
private Callback callback;
public interface Callback {
void onLocationResult(LocationResult locationResult);
}
public boolean start(Context context, Callback callback) {
this.callback = callback;
client = LocationServices.getFusedLocationProviderClient(context);
if (!checkLocationPermission(context)) return false;
client.requestLocationUpdates(getLocationRequest(), this, null);
return true;
}
public void stop() {
client.removeLocationUpdates(this);
}
@Override
public void onLocationResult(LocationResult locationResult) {
callback.onLocationResult(locationResult);
}
private boolean checkLocationPermission(Context context) {
int permissionCheck = ContextCompat.checkSelfPermission(
context, android.Manifest.permission.ACCESS_FINE_LOCATION);
return permissionCheck == PackageManager.PERMISSION_GRANTED;
}
private LocationRequest getLocationRequest() {
return LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(30_000L)
.setFastestInterval(20_000L);
}
}
从你的活动
这样调用这个
你的活动。JAVA
public class MapsActivity extends AppCompatActivity implements GpsManager.Callback {
private static final int PERMISSION_REQUEST_FINE_LOCATION = 1;
private GpsManager mGpsManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mGpsManager = new GpsManager(getApplicationContext(), this);
// check if user gave permissions, otherwise ask via dialog
if (!checkPermission()) {
getLocationPermissions();
return;
}
mGpsManager.start();
...
}
@Override
protected void onStop() {
super.onStop();
mGpsManager.stop();
}
@Override
public void onLocationResult(LocationResult locationResult) {
// do something with the locationResult
}
// CHECK PERMISSIONS PART
private boolean checkPermission() {
return isGranted(ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION)) &&
isGranted(ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION));
}
@TargetApi(Build.VERSION_CODES.M)
private void getLocationPermissions() {
requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_FINE_LOCATION);
}
@Override
public void onRequestPermissionsResult(int code, @Nullable String permissions[], @Nullable int[] results) {
switch (code) {
case PERMISSION_REQUEST_FINE_LOCATION:
if (isPermissionGranted(results)) {
getLocationRequest();
}
}
}
private boolean isPermissionGranted(int[] results) {
return results != null && results.length > 0 && isGranted(results[0]);
}
private boolean isGranted(int permission) {
return permission == PackageManager.PERMISSION_GRANTED;
}
}
这只是一个猜测,因为我没有尝试你的代码,但是解决方案应该会帮助你。如果我错了,请纠正我;)
Hi@Subodh Nijsure请检查以下代码并粘贴到您的代码中,检查后:
final Task<Void> voidTask = locationProviderClient.removeLocationUpdates(locationCallback);
voidTask.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
Log.e(TAG, "addOnCompleteListener: "+task.isComplete());
}
});
voidTask.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.e(TAG, "addOnSuccessListener: " );
}
});
voidTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e(TAG, "addOnFailureListener: ");
}
});
我认为这是一项艰巨的任务。isSuccessful()当你把这个监听器放在那个时候,这个方法就不起作用了,它工作得很好,我还看到它在内存中释放了所有的内存,当它进入前一个活动时。
当您重定向到任何活动时,请将一次调用的停止位置更新()转移到onPance()中,并从其他方法中删除,如onDevroy(),onStation(),因为它停止一次,所以为什么我们要调用多次时间。
希望这对你有帮助。
在RemovelocationUpdate中,您应该传递locationCallback,因为当前的实现是错误的。
不过,还有可能在其他地方发生内存泄漏。你应该尝试在你的应用程序中集成Leakcanary,它可以给你参考树,并告诉你哪个字段或侦听器导致了内存泄漏。你可以在这里查阅我唯一的一篇博文
public void stopLocationUpdates() {
if (locationProviderClient != null) {
try {
final Task<Void> voidTask = locationProviderClient.removeLocationUpdates(locationCallback);
if (voidTask.isSuccessful()) {
Log.d(TAG,"StopLocation updates successful! ");
} else {
Log.d(TAG,"StopLocation updates unsuccessful! " + voidTask.toString());
}
}
catch (SecurityException exp) {
Log.d(TAG, " Security exception while removeLocationUpdates");
}
}
}
问题内容: 我遵循此处给出的建议,以便使用elasticsearch查找部分单词: ElasticSearchn-gram令牌过滤器未找到部分单词 我创建了一个简单的bash脚本,尝试运行该脚本的一个版本: 运行此脚本后,前两个命令(倾销产品,然后设置索引)似乎可以正常工作: 然后它在映射调用之后给我以下错误: 有人可以看到我在做什么吗?搜索谷歌开始自动完成“映射未找到elasticsearch”
问题内容: 结果始终为1: 我在phpMyAdmin中运行了$ sql查询,它返回3,所以查询不是问题。$ vote_total全局初始化为0,因此1来自某个地方。我还需要提供什么其他信息来帮助我? 谢谢,瑞安 问题答案: 返回选定的行数,而不是特定行的字段。使用来获取您与您的查询选择的行: 您还可以用来获取一行并获取特定字段: 这将获取第一行(从零开始)并返回第一字段(从零开始)。
问题内容: 我已经写了这段简单的代码: 在我的情况当属。谁能建议/建议出什么问题了? 问题答案: 错误检查和处理是程序员的朋友。检查初始化和执行cURL函数的返回值。并在失败的情况下包含更多信息: *在 手动状态: 成功返回cURL句柄,错误返回 FALSE 。 我观察到该函数在您使用其参数且无法解析域时会返回。如果未使用该参数,则该函数 可能 永远不会返回。但是,请务必始终进行检查,因为该手册并
我使用Ehcache 2.6.8作为Spring Boot应用程序的一部分,作为Hibernate 4.3.11的二级缓存。我有一个JMX MBean,它允许我检查缓存的内容(如果您感兴趣,可以在这里查看)。 首先,我使用CacheManager名称来获取缓存列表。这很好。我可以用返回缓存。然后我调用。这很好,cacheName是“com.myapp.DomainObjectName”,键被列为“
我试图打开一个文件进行解析(一个二进制文件),但是无论什么fopen()总是返回NULL。 我已经排除了几乎所有的东西,我有一个简单的测试脚本: trigger_error(var_export())的输出;是: 无论我为第二个fopen()选项指定什么标志,我都会得到相同的结果。 现在,明显的问题是该文件是否存在,以及我是否拥有读取该文件的权限?这两个问题的答案都是肯定的。我使用了相对路径和绝对
在fetchplaces方法中,新的window.google.maps.places.PlacesService(map)总是返回null,并且Service.NearbySearch不会引发函数错误。 请帮忙。