gpt4 book ai didi

android - 按下后退按钮后如何解决 IntentReceiverLeaked

转载 作者:行者123 更新时间:2023-11-29 22:56:20 24 4
gpt4 key购买 nike

我在使用 android 6 时遇到 WifiDirect 连接问题。直接连接 WIFI 并将后退按钮推到我的应用程序后。该应用程序泄漏了 intentreceiver

public class WifiDirectController
extends ServerController
implements WifiP2pManager.ConnectionInfoListener,
WifiP2pManager.ChannelListener,
WiFiDirectBroadcastReceiver.WiFiDirectBroadcastListener,
WifiDirectServer.WifiDirectServerListener {
private static final String TAG = "WP2P.Controller";

private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private WifiP2pDevice mDevice;

private BroadcastReceiver mReceiver;

private boolean isWifiP2pEnabled = false;
private boolean isDiscovering = false;
private boolean isConnected = false;
private boolean retryChannel = false;
//added by Frank
private boolean isReceiverRegistered = false;

private final IntentFilter mIntentFilter = new IntentFilter();

private Handler mHandler;

private WifiDirectServer serverThread = null;

public WifiDirectController(ServerListener listener) {
super(listener);

//mManager = (WifiP2pManager) mListener.getSystemService(Context.WIFI_P2P_SERVICE);
mManager = (WifiP2pManager) mListener.getApplicationContext().getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(listener.getApplicationContext(), mListener.getMainLooper(), this);

// Indicates a change in the Wi-Fi P2P status.
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
// Indicates the state of Wi-Fi P2P connectivity has changed.
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
// Indicates this device's details have changed.
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
// Indicates that discovery has started or stopped
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);

mHandler = new Handler();
}

@Override
public void onStart()
{
Log.d(TAG, "onStart() called");

}

@Override
public void onResume() {
Log.d(TAG, "onResume() called");
Log.e(TAG, "FRANK onResume() called");
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
if (!isReceiverRegistered) {
mListener.registerReceiver(mReceiver, mIntentFilter);
isReceiverRegistered = true;
}
}

@Override
public void onPause()
{
Log.d(TAG, "onPause() called");
mListener.unregisterReceiver(mReceiver);
isReceiverRegistered = false;
stopDiscovery();
}

@Override
public void onStop()
{
Log.d(TAG, "onStop() called");
//added frank
if (isReceiverRegistered) {
mListener.unregisterReceiver(mReceiver);
isReceiverRegistered = false;
}
//
cancelDisconnect();
stopServer();
}

@Override
public void restart()
{
Log.d(TAG, "restart() called");
Log.e(TAG, "FRANK onRestart() called");
cancelDisconnect();
stopServer();
startDiscovery();
}

private boolean startServer()
{
Log.d(TAG, " = startServer() called");
Log.e(TAG, "FRANK startServer() called");
this.serverThread = new WifiDirectServer(this);
this.serverThread.start();
return true;
}

ActivityThread:Activity com.android.settings.SubSettings 泄露了最初在此处注册的 IntentReceiver android.net.wifi.WifiManager$1@61ae52a。您是否错过了对 unregisterReceiver() 的调用? android.app.IntentReceiverLeaked:Activity com.android.settings.SubSettings 泄露了最初在此处注册的 IntentReceiver android.net.wifi.WifiManager$1@61ae52a。您是否错过了对 unregisterReceiver() 的调用?

最佳答案

您必须使用一种方法来检查接收器是否已注册,这是因为当您按下后退按钮时, Activity 被销毁,因此变量返回到其原始值,因此在 Resume 方法中变量 isReceiverRegistered始终为 false,并尝试再次注册接收者。

  • 您可以在 OnPause 方法中取消注册接收者,而不是OnStop 方法。
  • 或者你可以存储覆盖变量的值onSaveInstanceState 方法和 onRestoreInstanceState 中的 recoverit方法。
  • 或者您可以使用 ViewModel 来保存变量的值。
  • 或者您可以尝试使用一个类来管理您的接收器。 slinden77在这个 thread 中给出了一个可能的解决方案
    public class ReceiverManager {

private static List<BroadcastReceiver> receivers = new ArrayList<BroadcastReceiver>();
private static ReceiverManager ref;
private Context context;

private ReceiverManager(Context context){
this.context = context;
}

public static synchronized ReceiverManager init(Context context) {
if (ref == null) ref = new ReceiverManager(context);
return ref;
}

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter intentFilter){
receivers.add(receiver);
Intent intent = context.registerReceiver(receiver, intentFilter);
Log.i(getClass().getSimpleName(), "registered receiver: "+receiver+" with filter: "+intentFilter);
Log.i(getClass().getSimpleName(), "receiver Intent: "+intent);
return intent;
}

public boolean isReceiverRegistered(BroadcastReceiver receiver){
boolean registered = receivers.contains(receiver);
Log.i(getClass().getSimpleName(), "is receiver "+receiver+" registered? "+registered);
return registered;
}

public void unregisterReceiver(BroadcastReceiver receiver){
if (isReceiverRegistered(receiver)){
receivers.remove(receiver);
context.unregisterReceiver(receiver);
Log.i(getClass().getSimpleName(), "unregistered receiver: "+receiver);
}
}
}

希望对你有帮助

关于android - 按下后退按钮后如何解决 IntentReceiverLeaked,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57397993/

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