Activity 已泄露 IntentReceiver - LollipopBrowserAccessibilityManager [英] Activity has leaked IntentReceiver - LollipopBrowserAccessibilityManager

查看:26
本文介绍了Activity 已泄露 IntentReceiver - LollipopBrowserAccessibilityManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能在这里找到一些帮助,因为我不熟悉 Android 中的广播接收器.这段代码打开一个 WebView,将您重定向到登录页面,并在检测到 URL 更改后接收登录令牌.之后,Activity 关闭.

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);mLoginWebView = (WebView) findViewById(R.id.webview_login);redirectUrl = getString(R.string.app_redirect_url);//接收平台ID捆绑包 = getIntent().getExtras();如果(捆绑!= null){平台 = bundle.getInt(ConstantsHelper.LOGIN_EXTRA_TOKEN);}mLoginWebView.setWebViewClient(new WebViewClient() {@覆盖public boolean shouldOverrideUrlLoading(WebView view, String url) {Log.d(TAG, "已检测到 URL 更改为 " + url + "");if (url.contains(redirectUrl) || url.contains("passport.twitch.tv")) {Log.d(TAG, "使用平台登录" + 平台);开关(平台){//获取Instagram授权令牌case ConstantsHelper.ID_INSTAGRAM:{String accessToken = url.split("=")[1];SharedPreferenceHelper.putString(ConstantsHelper.PREF_INST_ACCESS_TOKEN, accessToken);NetworkManager.getInstance().catchTokens();}//获取抽搐授权令牌case ConstantsHelper.ID_TWITCH:{String accessToken = url.substring(url.indexOf("=") + 1, url.indexOf("&"));SharedPreferenceHelper.putString(ConstantsHelper.PREF_TWITCH_ACCESS_TOKEN, accessToken);NetworkManager.getInstance().catchTokens();}}结束();//活动关闭返回真;}返回假;}});开关(平台){案例1:mLoginWebView.loadUrl(NetworkManager.getInstance().getInstagramAuthUrl(getApplicationContext()));案例4:mLoginWebView.loadUrl(NetworkManager.getInstance().getTwitchAuthUrl(getApplicationContext()));}}

没有任何反应,LogCat 显示此错误:

Activity com.maximutan.socialmedia_feed_merger.activities.LoginActivity 已经泄露了最初在这里注册的 IntentReceiver org.chromium.content.browser.accessibility.LollipopBrowserAccessibilityManager$1@25014a.您是否错过了对 unregisterReceiver() 的调用?android.app.IntentReceiverLeaked:Activity com.maximutan.socialmedia_feed_merger.activities.LoginActivity 已经泄露了最初在这里注册的 IntentReceiver org.chromium.content.browser.accessibility.LollipopBrowserAccessibilityManager$1@25014a.您是否错过了对 unregisterReceiver() 的调用?在 android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:962)在 android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:763)在 android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1179)在 android.app.ContextImpl.registerReceiver(ContextImpl.java:1159)在 android.app.ContextImpl.registerReceiver(ContextImpl.java:1153)在 android.content.ContextWrapper.registerReceiver(ContextWrapper.java:554)在 android.content.ContextWrapper.registerReceiver(ContextWrapper.java:554)在 org.chromium.content.browser.accessibility.LollipopBrowserAccessibilityManager.(LollipopBrowserAccessibilityManager.java:3)在 org.chromium.content.browser.accessibility.BrowserAccessibilityManager.create(BrowserAccessibilityManager.java:2)在 org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(本机方法)在 org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:7)在 android.os.Handler.dispatchMessage(Handler.java:102)在 android.os.Looper.loop(Looper.java:148)在 android.app.ActivityThread.main(ActivityThread.java:5527), 在 java.lang.reflect.Method.invoke(Native Method)在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

我的问题是我不知道我必须注销哪个 BroadcastReceiver,因为我没有创建和初始化一个.

感谢您的帮助

解决方案

当 WebView 仍然附加到其父视图时,在 WebView 上调用 destroy() 时会出现此问题.

崩溃可以通过在调用 destroy() 之前首先从其父视图中删除 Webview 来解决.

请注意,即使您没有手动调用 destroy()(就像我的情况),这种崩溃仍然可能发生.我发现关键是您必须显式销毁 WebView(至少在片段中),因为 Android 不会为您处理此问题,在此之前,您必须将其从其父视图中删除.

例如,如果您有一个 WebView 片段:

 @Override公共无效 onDestroyView() {super.onDestroyView();//彻底销毁 WebView如果(mWebView != null){//在调用 destroy 之前,必须从视图层次结构中删除 WebView//防止内存泄漏//参见 https://developer.android.com/reference/android/webkit/WebView.html#destroy%28%29((ViewGroup) mWebView.getParent()).removeView(mWebView);mWebView.removeAllViews();mWebView.destroy();mWebView = null;}}

完全归功于 Billy Brawner:https://brawner.tech/2017/12/03/webview-memory-leak/

I hope to find some help here because I'm not familiar with BroadcastReceivers in Android. This piece of code opens a WebView redirect you to a login page and receives the login token once a URL change is detected. After that, the Activity is closed.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    mLoginWebView = (WebView) findViewById(R.id.webview_login);

    redirectUrl = getString(R.string.app_redirect_url);


    //RECEIVE PLATFORM ID
    Bundle bundle = getIntent().getExtras();
    if(bundle != null){
        platform = bundle.getInt(ConstantsHelper.LOGIN_EXTRA_TOKEN);
    }

    mLoginWebView.setWebViewClient(new WebViewClient() {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {

            Log.d(TAG, "URL change to to " + url + " was detected");

            if (url.contains(redirectUrl) || url.contains("passport.twitch.tv")) {

                Log.d(TAG, "Login with platform " + platform);

                switch (platform){

                    //GET INSTAGRAM AUTH TOKEN
                    case ConstantsHelper.ID_INSTAGRAM:{
                        String accessToken = url.split("=")[1];

                        SharedPreferenceHelper.putString(ConstantsHelper.PREF_INST_ACCESS_TOKEN, accessToken);
                        NetworkManager.getInstance().catchTokens();

                    }

                    //GET TWITCH AUTH TOKEN
                    case ConstantsHelper.ID_TWITCH:{
                        String accessToken = url.substring(url.indexOf("=") + 1, url.indexOf("&"));

                        SharedPreferenceHelper.putString(ConstantsHelper.PREF_TWITCH_ACCESS_TOKEN, accessToken);
                        NetworkManager.getInstance().catchTokens();

                    }

                }
                finish(); //Activity is closed
                return true;
            }
            return false;
        }


    });

    switch (platform){
        case 1: mLoginWebView.loadUrl(NetworkManager.getInstance().getInstagramAuthUrl(getApplicationContext()));
        case 4: mLoginWebView.loadUrl(NetworkManager.getInstance().getTwitchAuthUrl(getApplicationContext()));
    }


}

Nothing happens and LogCat is displaying this error:

Activity com.maximutan.socialmedia_feed_merger.activities.LoginActivity has leaked IntentReceiver org.chromium.content.browser.accessibility.LollipopBrowserAccessibilityManager$1@25014a that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Activity com.maximutan.socialmedia_feed_merger.activities.LoginActivity has leaked IntentReceiver org.chromium.content.browser.accessibility.LollipopBrowserAccessibilityManager$1@25014a that was originally registered here. Are you missing a call to unregisterReceiver()?
at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:962)
at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:763)
at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1179)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1159)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1153)
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:554)
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:554)
at org.chromium.content.browser.accessibility.LollipopBrowserAccessibilityManager.<init>(LollipopBrowserAccessibilityManager.java:3)
at org.chromium.content.browser.accessibility.BrowserAccessibilityManager.create(BrowserAccessibilityManager.java:2)
at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)

at org.chromium.base.SystemMessageHandler.handleMessage(
SystemMessageHandler.java:7)  
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5527)
,at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(
ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

My problem is that I don't know which BroadcastReceiver I have to unregister since I hadn't created and initialized one.

Thanks for your help

解决方案

This issue occurs when destroy() is called on the WebView when the WebView is still attached to its parent view.

The crash can be resolved by first removing the Webview from it's parent view before calling destroy().

Note that even if you are not calling destroy() manually (like was the case for me) this crash can still occur. I found that the key is that you have to explicitly destroy a WebView (at least in a fragment), as Android doesn’t handle this for you, and prior to doing that, you have to remove it from its parent view.

For example, if you have a WebView fragment:

 @Override
    public void onDestroyView() {
        super.onDestroyView();

        // destroy the WebView completely
        if (mWebView != null) {
            // the WebView must be removed from the view hierarchy before calling destroy
            // to prevent a memory leak
            // See https://developer.android.com/reference/android/webkit/WebView.html#destroy%28%29
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.removeAllViews();
            mWebView.destroy();
            mWebView = null;
        }
    }

Full credit to Billy Brawner: https://brawner.tech/2017/12/03/webview-memory-leak/

这篇关于Activity 已泄露 IntentReceiver - LollipopBrowserAccessibilityManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆