gpt4 book ai didi

android - 当单例应用程序对象有时为空时

转载 作者:太空狗 更新时间:2023-10-29 14:43:24 26 4
gpt4 key购买 nike

目前,我有一个 Application 类,我希望它在整个应用程序生命周期中都是可见的。

我的应用程序.java

public class MyApplication extends android.support.multidex.MultiDexApplication  {
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}

public static MyApplication instance() {
return me;
}

@SuppressLint("NewApi")
@Override
public void onCreate(){
super.onCreate();

me = this;

registerNetworkCallback(MyApplication.instance());

但是,在极少数情况下,MyApplication.instance() 在连接更改广播接收器中返回 null。

ConnectivityChangeBroadcastReceiver.java

public class ConnectivityChangeBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// MyApplication.instance() is returning null?!?!

}

我如何注册网络回调

public static void registerNetworkCallback(final Context context) {
/*
Apps targeting Android 7.0 (API level 24) do not receive CONNECTIVITY_ACTION broadcasts if
they register to receive them in their manifest. Apps that are running can still listen for
CONNECTIVITY_CHANGE on their main thread by registering a BroadcastReceiver with
Context.registerReceiver().
*/
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return;
}

try {
if (!connectivityChangeBroadcastReceiverDisabled) {
// Although ConnectivityChangeBroadcastReceiver will not be triggered, just to be extra
// caution...
PackageManager pm = context.getPackageManager();
ComponentName compName = new ComponentName(context, ConnectivityChangeBroadcastReceiver.class);
pm.setComponentEnabledSetting(
compName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
connectivityChangeBroadcastReceiverDisabled = true;
}

if (networkCallback == null) {
networkCallback = new ConnectivityManager.NetworkCallback() {
/**
* @param network
*/
@Override
public void onAvailable(Network network) {
Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
@Override
public void run() {
ConnectivityChangeBroadcastReceiver.onReceive(context);
}
};
handler.post(runnable);
}
};
}

ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
NetworkRequest networkRequest = builder.build();
connectivityManager.registerNetworkCallback(networkRequest, networkCallback);
} catch (Exception e) {
Log.e(TAG, "", e);
}
}

您是否知道为什么有一种罕见的可能性,当 onReceive 中触发 ConnectivityChangeBroadcastReceiver 时,单例 MyApplication.instance() 是返回空值?

最佳答案

我意识到很有可能是我泄露了应用程序上下文,这使得操作系统没有机会对其进行垃圾回收

应用上下文泄露!

registerNetworkCallback(MyApplication.instance());

public static void registerNetworkCallback(final Context context) {
...
networkCallback = new ConnectivityManager.NetworkCallback() {
/**
* @param network
*/
@Override
public void onAvailable(Network network) {
Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
@Override
public void run() {
ConnectivityChangeBroadcastReceiver.onReceive(context);

不再有应用程序上下文泄漏!

registerNetworkCallback(MyApplication.instance());

// No more final on context, to avoid it is being used in anonymous class.
public static void registerNetworkCallback(Context context) {
...
networkCallback = new ConnectivityManager.NetworkCallback() {
/**
* @param network
*/
@Override
public void onAvailable(Network network) {
Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
@Override
public void run() {
ConnectivityChangeBroadcastReceiver.onReceive(MyApplication.instance());

关于android - 当单例应用程序对象有时为空时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44095139/

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