Android-skin-support icon indicating copy to clipboard operation
Android-skin-support copied to clipboard

升4.0.5后 (AndroidX) , 加载第三方内容错误 youtube

Open KingsleyWu opened this issue 5 years ago • 5 comments

不使用Skin或使用3.1.4版本,能正常初始化view,升级到4.0.5后无法初始化 反编译过youtube也使用的是androidx,embedded_ad_overlay布局中使用的也是普通layout 添加的依赖: implementation "skin.support:skin-support:4.0.5" implementation "skin.support:skin-support-appcompat:4.0.5" implementation "skin.support:skin-support-design:4.0.5" implementation "skin.support:skin-support-constraint-layout:4.0.5" implementation "skin.support:skin-support-cardview:4.0.5"

Application中的初始化: SkinCompatManager.withoutActivity(this) .addInflater(new SkinAppCompatViewInflater()) // 基础控件换肤初始化 .addInflater(new SkinMaterialViewInflater()) // material design .addInflater(new SkinConstraintViewInflater()) // ConstraintLayout .addInflater(new SkinCardViewInflater()) // CardView .setSkinWindowBackgroundEnable(false) // 关闭windowBackground换肤 .loadSkin(); 在recyclerView item点击时初始化 YouTubePlayerSupportFragmentX 加载youtube 的YouTubePlayerView 时 出错

YouTubePlayerSupportFragmentX youTubePlayerFragment = YouTubePlayerSupportFragmentX.newInstance(); fragmentManager.getSupportFragmentManager() .beginTransaction() .replace(viewHolder.mVideoContainer.getId(), youTubePlayerFragment) .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out) .commit();

出错日志: 2020-08-12 17:21:55.168 19972-19972/?E/YouTubeAndroidPlayerAPI: Error creating YouTubePlayerView com.google.android.youtube.player.internal.w$a: Exception thrown by invoked constructor in com.google.android.youtube.api.jar.client.RemoteEmbeddedPlayer at com.google.android.youtube.player.internal.w.a(Unknown Source:143) at com.google.android.youtube.player.internal.w.a(Unknown Source:4) at com.google.android.youtube.player.internal.w.a(Unknown Source:36) at com.google.android.youtube.player.internal.ac.a(Unknown Source:4) at com.google.android.youtube.player.YouTubePlayerView.a(Unknown Source:8) at com.google.android.youtube.player.YouTubePlayerView$1.a(Unknown Source:12) at com.google.android.youtube.player.internal.r.g(Unknown Source:73) at com.google.android.youtube.player.internal.r$c.a(Unknown Source:66) at com.google.android.youtube.player.internal.r$b.a(Unknown Source:4) at com.google.android.youtube.player.internal.r$a.handleMessage(Unknown Source:98) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:237) at android.app.ActivityThread.main(ActivityThread.java:7948) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.newInstance0(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:343) at com.google.android.youtube.player.internal.w.a(Unknown Source:41) at com.google.android.youtube.player.internal.w.a(Unknown Source:4)  at com.google.android.youtube.player.internal.w.a(Unknown Source:36)  at com.google.android.youtube.player.internal.ac.a(Unknown Source:4)  at com.google.android.youtube.player.YouTubePlayerView.a(Unknown Source:8)  at com.google.android.youtube.player.YouTubePlayerView$1.a(Unknown Source:12)  at com.google.android.youtube.player.internal.r.g(Unknown Source:73)  at com.google.android.youtube.player.internal.r$c.a(Unknown Source:66)  at com.google.android.youtube.player.internal.r$b.a(Unknown Source:4)  at com.google.android.youtube.player.internal.r$a.handleMessage(Unknown Source:98)  at android.os.Handler.dispatchMessage(Handler.java:107)  at android.os.Looper.loop(Looper.java:237)  at android.app.ActivityThread.main(ActivityThread.java:7948)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)  Caused by: android.view.InflateException: Binary XML file line #6 in com.google.android.youtube:layout/embedded_ad_overlay: Can't convert value at index 5 to dimension: type=0x1 Caused by: java.lang.UnsupportedOperationException: Can't convert value at index 5 to dimension: type=0x1 at android.content.res.TypedArray.getDimensionPixelSize(TypedArray.java:786) at android.view.ViewGroup$MarginLayoutParams.(ViewGroup.java:9175) at android.widget.RelativeLayout$LayoutParams.(RelativeLayout.java:1296) at android.widget.RelativeLayout.generateLayoutParams(RelativeLayout.java:1110) at android.widget.RelativeLayout.generateLayoutParams(RelativeLayout.java:89) at android.view.LayoutInflater.rInflate(LayoutInflater.java:1125) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084) at android.view.LayoutInflater.inflate(LayoutInflater.java:682) at android.view.LayoutInflater.inflate(LayoutInflater.java:534) at android.view.LayoutInflater.inflate(LayoutInflater.java:481) at ptw.a(Unknown Source:26) at amqr.a(PG:16) at pin.(PG:49) at com.google.android.youtube.api.jar.client.RemoteEmbeddedPlayer.(PG:5) at com.google.android.youtube.api.jar.client.RemoteEmbeddedPlayer.(PG:36) at java.lang.reflect.Constructor.newInstance0(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:343) at com.google.android.youtube.player.internal.w.a(Unknown Source:41) at com.google.android.youtube.player.internal.w.a(Unknown Source:4) at com.google.android.youtube.player.internal.w.a(Unknown Source:36) at com.google.android.youtube.player.internal.ac.a(Unknown Source:4) at com.google.android.youtube.player.YouTubePlayerView.a(Unknown Source:8) at com.google.android.youtube.player.YouTubePlayerView$1.a(Unknown Source:12) at com.google.android.youtube.player.internal.r.g(Unknown Source:73) at com.google.android.youtube.player.internal.r$c.a(Unknown Source:66) at com.google.android.youtube.player.internal.r$b.a(Unknown Source:4) at com.google.android.youtube.player.internal.r$a.handleMessage(Unknown Source:98) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:237) at android.app.ActivityThread.main(ActivityThread.java:7948) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 2020-08-12 17:21:55.168 19972-19972/? E/YouTubeAndroidPlayerAPI: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) 2020-08-12 17:21:55.171 19972-19972/? E/VideoBinder: onInitializationFailure: INTERNAL_ERROR 2020-08-12 17:31:59.981 19972-19972/? E/ViewRootImpl@a8ce078[MainActivity]: Surface is not valid.

KingsleyWu avatar Aug 12 '20 09:08 KingsleyWu

最终定位到: SkinAppCompatViewInflater 的 wrapContext方法中 final boolean inheritContext = isPre21 && shouldInheritContext(context, (ViewParent) parent); 与AppCompatDelegateImpl 源码中不一致 inheritContext = (attrs instanceof XmlPullParser) // If we have a XmlPullParser, we can detect where we are in the layout ? ((XmlPullParser) attrs).getDepth() > 1 // Otherwise we have to use the old heuristic : shouldInheritContext((ViewParent) parent); 替换一致后问题解决

KingsleyWu avatar Aug 12 '20 11:08 KingsleyWu

@ximsfei

KingsleyWu avatar Aug 12 '20 11:08 KingsleyWu

另外SkinCompatDelegate 中的createView 方法 中的 wrapper.wrapContext(mContext, parent, attrs); 替换为 传进来的context wrapper.wrapContext(context, parent, attrs); public View createView(View parent, final String name, @NonNull Context context, @NonNull AttributeSet attrs) { if (mSkinCompatViewInflater == null) { mSkinCompatViewInflater = new SkinCompatViewInflater(); }

    List<SkinWrapper> wrapperList = SkinCompatManager.getInstance().getWrappers();
    for (SkinWrapper wrapper : wrapperList) {
        Context wrappedContext = wrapper.wrapContext(context, parent, attrs);
        if (wrappedContext != null) {
            context = wrappedContext;
        }
    }
    return mSkinCompatViewInflater.createView(parent, name, context, attrs);
}

KingsleyWu avatar Aug 28 '20 10:08 KingsleyWu

主要出现 这种问题是因为 youtube 使用的context 是从youtube的应用中传过来的,在换肤的框架中把这个context替换成了本app的context导致获取资源获取不到

KingsleyWu avatar Aug 28 '20 10:08 KingsleyWu

补充个

另外SkinCompatDelegate 中的createView 方法 中的 wrapper.wrapContext(mContext, parent, attrs); 替换为 传进来的context wrapper.wrapContext(context, parent, attrs); public View createView(View parent, final String name, @nonnull Context context, @nonnull AttributeSet attrs) { if (mSkinCompatViewInflater == null) { mSkinCompatViewInflater = new SkinCompatViewInflater(); }

    List<SkinWrapper> wrapperList = SkinCompatManager.getInstance().getWrappers();
    for (SkinWrapper wrapper : wrapperList) {
        Context wrappedContext = wrapper.wrapContext(context, parent, attrs);
        if (wrappedContext != null) {
            context = wrappedContext;
        }
    }
    return mSkinCompatViewInflater.createView(parent, name, context, attrs);
}

华为机器的长按弹出actionMode,会出现显示异常,原因是华为定制了actionMode样式,原因也是他说的一样,在换肤的框架中把这个context替换成了本app的context导致获取资源获取不到。 把mContext改成context就解决了。 这个问题跟了我3天时间,中间放弃了,后面通过替换方式才跟踪到问题点,上来一搜才发现有这个。 问题不好定位,一度崩溃。

SjAndy88 avatar Nov 18 '20 11:11 SjAndy88