目前,我有一个Application
类,我希望在整个应用程序生命周期中都能看到它。
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。
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);
}
}
您是否知道为什么在ConnectivityChangeBroadcastReceiver
中触发onReceive
时,单身MyApplication.instance()
返回null时会出现罕见的可能性?
答案 0 :(得分:0)
我意识到很高的可能性,就是我泄漏了应用程序上下文,这使得OS没有机会垃圾收集它
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());