gpt4 book ai didi

android - leakcanary stacktrace 难以理解

转载 作者:行者123 更新时间:2023-11-30 01:20:43 25 4
gpt4 key购买 nike

我有来自泄漏金丝雀的以下堆栈跟踪,我不确定我的 Activity 是如何泄漏的

static LGCobtextHelper.mLGContext
references LGContext.mContext
references
ResourcesContextWrapperFactory$WebViewContextWrapper.mBase
references
com.*.*.activity.MyActivity.networkMonitor
references
com.*.*.NetworkMonitor.mPendingResult
references
android.app.LoadedApk$ReceiverDispatcher$Args.this$0
references
LoadedAok$ReceiverDispathcer.mContext
leaks MyActivity instance

MyActivity 扩展了 BaseActivity,它注册了 onResume() 并注销了 onPause(),所以不确定哪个泄露 Activity

网络监控.java

     public class NetworkMonitor extends BroadcastReceiver {
private final WebSocketClient webSocketClient;
private final ArmingHelper armingHelper;
private final ShutdownManager shutdownManager;
private final CameraThumbnailCache cameraThumbnailCache;
private final CameraAccessManager cameraAccessManager;
private final JoustLogger joustLogger;

private Activity registeredActivity;
private String currentNetworkName;
private List<NetworkStatusChangeListener> networkChangeListeners;

public interface NetworkStatusChangeListener {
void onNetworkUp();
void onNetworkDown();
}

public NetworkMonitor(WebSocketClient webSocketClient, ArmingHelper armingHelper, ShutdownManager shutdownManager, CameraThumbnailCache cameraThumbnailCache, CameraAccessManager cameraAccessManager, JoustLogger joustLogger) {
this.webSocketClient = webSocketClient;
this.armingHelper = armingHelper;
this.shutdownManager = shutdownManager;
this.cameraThumbnailCache = cameraThumbnailCache;
this.cameraAccessManager = cameraAccessManager;
this.joustLogger = joustLogger;
networkChangeListeners = new ArrayList<>();
}

// Activities *must* call this method in onResume() in order for
// the app to watch for network changes
public void startListeningForNetworkChanges(Activity registeringActivity) {
if (!(registeringActivity instanceof NetworkStatusChangeListener)) {
throw new IllegalArgumentException("Registering Activity must implement NetworkStatusChangeListener");
}

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
intentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intentFilter.addAction(GlobalConstants.ANDROID_NET_WIFI_WIFI_STATE_CHANGED);
registeringActivity.registerReceiver(this, intentFilter);
this.registeredActivity = registeringActivity;
registerListenerForNetworkChanges((NetworkStatusChangeListener)registeringActivity);
}

// Activities *must* call this method in onPause() in order to properly
// unregister the receiver that was set in onResume()
public void stopListeningForNetworkChanges(Activity registeringActivity) {
registeringActivity.unregisterReceiver(this);
unregisterListenerForNetworkChanges((NetworkStatusChangeListener)registeringActivity);
registeredActivity = null;
}

// Fragments can use this method to register for Network change updates, call in onResume()
public void registerListenerForNetworkChanges(NetworkStatusChangeListener listener) {
networkChangeListeners.add(listener);
}

// Fragments need to unregister in onPause()
public void unregisterListenerForNetworkChanges(NetworkStatusChangeListener listener) {
networkChangeListeners.remove(listener);
}

@Override
public void onReceive(Context context, Intent intent) {
checkNetworkConnection();
}

public void checkNetworkConnection() {
if (registeredActivity != null) {
final ConnectivityManager connectivityManager = (ConnectivityManager) registeredActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnectedOrConnecting()) {
String newNetworkName = networkInfo.getTypeName();
if (currentNetworkName == null || !currentNetworkName.equals(newNetworkName)) {
Timber.d("Network(%s) Connected", newNetworkName);
// Our network was down, but now it's up. Validate the Websocket
currentNetworkName = newNetworkName;
cameraThumbnailCache.clearInternalURLPreferences();
webSocketClient.reopenWebsocketIfPossible();
cameraAccessManager.onNetworkUp();
if (ActivityBehaviorHelper.needsSecurityCountdown(registeredActivity)) {
armingHelper.startTimerIfReady();
}
for (NetworkStatusChangeListener listener : networkChangeListeners) {
listener.onNetworkUp();
}
joustLogger.onNetworkUp();
}
} else {
Timber.w("Network Down");
currentNetworkName = null;
cameraAccessManager.onNetworkDown();
joustLogger.onNetworkDown();
shutdownManager.onNetworkDown();
for (NetworkStatusChangeListener listener : networkChangeListeners) {
listener.onNetworkDown();
}
}
}
}
}


BaseActivity.java

@Override
protected void onResume() {
super.onResume();
networkMonitor.startListeningForNetworkChanges(this);
}

@Override
protected void onPause() {
networkMonitor.stopListeningForNetworkChanges(this);
super.onPause();
}

最佳答案

看起来您可能不需要在该 NetworkMonitor 类中保留对 Activity 的引用。这可能是您的内存泄漏的根源 - Activity 引用可能在 Activity 被销毁后被保留。看起来您可以将上下文作为参数传递给需要它的方法。

此外,对于此处使用 Activity 上下文的一些地方,例如 context.getSystemService(Context.CONNECTIVITY_SERVICE),您可以改用 Application 上下文,并且可能完全避免需要 Activity 引用。

关于android - leakcanary stacktrace 难以理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37148889/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com