register too many Broadcast Receivers

最近在友盟上發(fā)現(xiàn)一處崩潰
java.lang.IllegalArgumentException: regist too many Broadcast Receivers at android.app.ContextImpl.registerReceiverInternal
導(dǎo)致這個問題的原因是華為5.1和5.1.1上,有一個針對廣播注冊的限制,HuaWei自家定制的ROM系統(tǒng)中有一個白名單機制,只有加入了白名單的APP才允許注冊超過500個BroadcastReceiver,否則就會拋出Register too many Broadcast Receivers的異常。
也就是說沒有加入該白名單機制的APP最多只能注冊500個BroadcastReceiver。

那么解決這個問題可以分成兩種
1:找到注冊廣播的源頭,解決。
2:用反射黑科技,把自己包名加入到華為白名單里,從而豁免500限制。

反射的辦法網(wǎng)上很多個,參考
https://ishinagimoeta.github.io/2018/10/15/HuaweiRegister2many/、https://github.com/bumptech/glide/issues/1161

我們從源頭排查問題,發(fā)現(xiàn)是glide這個圖片加載框架引起的。

app打開了網(wǎng)絡(luò)權(quán)限("android.permission.ACCESS_NETWORK_STATE"), glide 能監(jiān)聽網(wǎng)絡(luò)變化,在有網(wǎng)、斷網(wǎng)的時候調(diào)整自身的加載策略,核心類是DefaultConnectivityMonitorFactory、DefaultConnectivityMonitor

崩潰發(fā)生在DefaultConnectivityMonitor的注冊廣播函數(shù),華為拋出的IllegalArgumentException無法被捕獲

private void register() {
    if (isRegistered) {
      return;
    }

    // Initialize isConnected.
    isConnected = isConnected(context);
    try {
      // See #1405
      context.registerReceiver(connectivityReceiver,
          new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
      isRegistered = true;
    } catch (SecurityException e) {
      // See #1417, registering the receiver can throw SecurityException.
      if (Log.isLoggable(TAG, Log.WARN)) {
        Log.w(TAG, "Failed to register", e);
      }
    }
  }

好在glide支持模塊自主配置,因此我們在華為的5.0、5.1上不再注冊glide的網(wǎng)絡(luò)監(jiān)聽事件。下面是我們解決的辦法,核心是builder.setConnectivityMonitorFactory(new NoConnectivityMonitorFactory());

@GlideModule
public final class XLOkHttpLibraryGlideModule extends AppGlideModule {
    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        super.applyOptions(context, builder);

        //兼容了華為平板 5.1 5.0機型上,Register too many Broadcast Receivers 的問題
        if (NoConnectivityMonitorFactory.needDisableNetCheck()) {
            builder.setConnectivityMonitorFactory(new NoConnectivityMonitorFactory());
        }
    }
}
**
 * 功能:不做網(wǎng)絡(luò)監(jiān)聽,兼容華為平板
 * 描述:
 * Created by 陳俊杰 on 2019/9/3.
 */
public class NoConnectivityMonitorFactory implements ConnectivityMonitorFactory {
    /**
     * 華為 5.1 5.11機型需要禁用glide網(wǎng)絡(luò)監(jiān)聽功能
     *
     * @return
     */
    public static boolean needDisableNetCheck() {
        return isHuawei() && Build.VERSION.SDK_INT < Build.VERSION_CODES.M;
    }

    static boolean isHuawei() {
        String brand = Build.BRAND.toLowerCase();
        return brand.contains("huawei") || brand.contains("honor");
    }

    @NonNull
    @Override
    public ConnectivityMonitor build(@NonNull Context context, @NonNull ConnectivityMonitor.ConnectivityListener listener) {

        return new ConnectivityMonitor() {

            @Override
            public void onStart() {
                //不做處理
            }

            @Override
            public void onStop() {
//不做處理
            }

            @Override
            public void onDestroy() {
//不做處理
            }
        };
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容