我有一个activity
扩展名为class
的{{1}} LocationAwareActivity
LocationAwareActivity
所有activity
LocationServices.getFusedLocationProviderClient
会创建一个位置服务客户端
listens
和removeLocationUpdates
来
位置更新。
当活动被破坏时,它会调用removeLocationUpdate
。我发现的是
activity
返回始终返回不成功的任务LocationAwareActivity
没有被垃圾收集。
- 因此,如果我启动从activity
继承的任何活动,该活动始终保持在堆上。
所以问题是什么是停止接收位置更新的正确方法,从而允许<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
<body>
<div ng-app="app">
<div ng-controller="MainCtrl" ng-init="init()">
<input type="text" ng-model="listData">
</div>
</div>
</body>
<script>var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.init = function(){
$scope.list=[
{
"name":"john",
"types":[
{"work":"aa"},
{"work":"bb"}
]
}
];
$scope.listData = "";
for(var i=0;i<$scope.list[0].types.length;i++){
if($scope.listData!= undefined){
$scope.listData = $scope.listData+","+$scope.list[0].types[i].work;
}
}
}
});
</script>
</html>
被垃圾收集。
此项目的整个来源可在此处访问 - https://github.com/snijsure/MultiActivity
答案 0 :(得分:7)
在 removeLocationUpdates 中,您应该传递 locationCallback ,当前的实现是错误的。
但是,其他地方也有可能发生内存泄漏。您应该尝试在您的应用中集成Leakcanary,它可以为您提供参考树,并告诉您哪个字段或侦听器导致此内存泄漏。 您可以参考one of my only blog post here
My Training set and labels: 26721(each image have size (32, 32,1)) , (26721, 10)
Validation set and labels: 6680(each image have size(32,32,1), (6680,10)
答案 1 :(得分:4)
您好@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: ");
}
});
我认为 voidTask.isSuccessful()当你把这个监听器放在那个时候它正常工作时这个方法不起作用我也看到内存它会释放所有内存来到上一个活动。
当你重定向到任何活动时,请将 stopLocationUpdates()一次调用到onPause()并从其他方法中删除,如onDestroy(),onStop()因为它停止一次所以我们为什么要这样做多次打电话。
希望这会对你有所帮助。
答案 2 :(得分:3)
Task对象返回false的原因在于stopLocationUpdates
方法,您再次创建本地**LocationCallback**
引用,然后将此引用用作locationProviderClient.removeLocationUpdates(cL);
中的参数
您的本地LocationCallBack永远不会出现在locationProviderClient
所以你需要做的是,你必须传递你在startLocationUpdates
方法中实例化的同一个全局对象,而不是创建另一个LocationCallBack对象
你的代码应该是这样的
inal Task<Void> voidTask = locationProviderClient.removeLocationUpdates(locationCallback);
答案 3 :(得分:3)
通过查看存储库中的代码,我发现您的设计中可能会导致Activity
泄漏的一些问题。
1)您正在使用两个不同的LocationCallbacks
。一个在开始,一个在停止方法,但你应该实际使用相同的。因此,一次实例化它就足够了,并且在删除Task
时可能也会导致LocationCallback
的成功结果。
2)由于您使用LocationCallback
实例化Anonymous Class
两次,即使您完成了包含类,也会保留内部类的非静态引用,这会导致您的Memory Leak
。您可以阅读有关此here的更多信息。
3)恕我直言,最好使用单独的经理类来处理您的位置请求,而不是抽象Activity
。
这就是说我的......
<强> GpsManager.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);
}
}
并从Activity
这样的
<强> YourActivity.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;
}
}
这只是一个猜测,因为我没有尝试您的代码,但解决方案应该会帮助您。如果我错了,请纠正我;)