如何修复 ViewPager class 膨胀异常,该异常仅可在已发布的 Google Play 商店版本中重现
How to fix ViewPager class inflating exception which is reproducable only with the released Google Play Store version
我不久前将一个应用程序从较旧的 AppCompat 转换为 AndroidX。我在我的开发环境中测试了我的更新,一切看起来都很好。然而令我惊讶的是,从 Google Play Store 全新安装的应用程序在启动后立即崩溃。即使使用干净擦除的冷启动模拟器,无论是调试版本还是发布版本,我都无法重现崩溃。
这是整个应用程序的源代码:https://github.com/gdgfresno/androidify-yourself
(README.md 指的是 AndroidX 之前的状态,不要介意)和商店列表 https://play.google.com/store/apps/details?id=com.valleydevfest.androidify
当我使用商店分布式应用重现崩溃时,我在调用堆栈上遇到此崩溃:
2020-07-30 11:02:28.417 31599-31599/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.valleydevfest.androidify, PID: 31599
android.view.InflateException: Binary XML file line #30 in com.valleydevfest.androidify:layout/fragment_main: Binary XML file line #30 in com.valleydevfest.androidify:layout/fragment_main: Error inflating class android.support.v4.view.ViewPager
Caused by: android.view.InflateException: Binary XML file line #30 in com.valleydevfest.androidify:layout/fragment_main: Error inflating class android.support.v4.view.ViewPager
Caused by: java.lang.ClassNotFoundException: android.support.v4.view.ViewPager
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:454)
at android.view.LayoutInflater.createView(LayoutInflater.java:815)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1006)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1126)
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 com.valleydevfest.androidify.PlaceholderFragment.onCreateView(PlaceholderFragment.java:48)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1514)
at android.app.Activity.performStart(Activity.java:7838)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3398)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2109)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.ClassNotFoundException: android.support.v4.view.ViewPager
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:454)
at android.view.LayoutInflater.createView(LayoutInflater.java:815)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1006)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1126)
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 com.valleydevfest.androidify.PlaceholderFragment.onCreateView(PlaceholderFragment.java:48)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1514)
at android.app.Activity.performStart(Activity.java:7838)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3398)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2109)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
问题是执行运行时出于某种原因搜索了 AndroidX 之前的 ViewPager android.support.v4.view.ViewPager
但是应该是 androidx.viewpager.widget.ViewPager
.
这就是我的布局 https://github.com/gdgfresno/androidify-yourself/blob/master/src/main/res/layout/fragment_main.xml
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_weight="90"
android:layout_width="match_parent"
android:layout_height="0dp"
android:padding="1dp"
android:orientation="vertical"
android:background="@drawable/border">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPagerHead"
android:layout_weight="30"
android:layout_width="match_parent"
android:layout_height="0dp" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPagerBody"
android:layout_weight="30"
android:layout_width="match_parent"
android:layout_height="0dp" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPagerLegs"
android:layout_weight="30"
android:layout_width="match_parent"
android:layout_height="0dp" />
</androidx.appcompat.widget.LinearLayoutCompat>
...
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.ViewPager;
...
final View rootView = inflater.inflate(R.layout.fragment_main, container, false);
mViewPagerHead = rootView.findViewById(R.id.viewPagerHead);
mViewPagerBody = rootView.findViewById(R.id.viewPagerBody);
mViewPagerLegs = rootView.findViewById(R.id.viewPagerLegs);
FragmentManager fm = getActivity().getSupportFragmentManager();
mViewPagerHead.setAdapter(new AndroidifyViewPagerAdapter(fm, AndroidDrawables.getHeads()));
mViewPagerBody.setAdapter(new AndroidifyViewPagerAdapter(fm, AndroidDrawables.getBodies()));
mViewPagerLegs.setAdapter(new AndroidifyViewPagerAdapter(fm, AndroidDrawables.getLegs()));
崩溃发生在 final View rootView = inflater.inflate(R.layout.fragment_main, container, false);
行。我清除了 gradle 缓存 (rm -rf $HOME/.gradle/cache
)。我擦除模拟器,卸载应用程序,重建应用程序。当一切都是 androidx
时,它从哪里得到 android.support.v4.view.ViewPager
?
我还在 build.gradle 中包含了 implementation 'androidx.fragment:fragment:1.2.5'
包,尽管这不是成功编译所必需的。提交项目问题 https://github.com/gdgfresno/androidify-yourself/issues/2
我继续按照本指南和我的常识将应用程序使用的 ViewPager 转换为 ViewPager2:https://developer.android.com/training/animation/vp2-migration
这是提交:https://github.com/gdgfresno/androidify-yourself/commit/df74fc3f0f2d98c3ae59969db11d3678d57a923a
显然,这消除了所有歧义和底层框架拉出一个不恰当的旧ViewPager
“魔术帽中的兔子”的机会。
我不久前将一个应用程序从较旧的 AppCompat 转换为 AndroidX。我在我的开发环境中测试了我的更新,一切看起来都很好。然而令我惊讶的是,从 Google Play Store 全新安装的应用程序在启动后立即崩溃。即使使用干净擦除的冷启动模拟器,无论是调试版本还是发布版本,我都无法重现崩溃。
这是整个应用程序的源代码:https://github.com/gdgfresno/androidify-yourself (README.md 指的是 AndroidX 之前的状态,不要介意)和商店列表 https://play.google.com/store/apps/details?id=com.valleydevfest.androidify
当我使用商店分布式应用重现崩溃时,我在调用堆栈上遇到此崩溃:
2020-07-30 11:02:28.417 31599-31599/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.valleydevfest.androidify, PID: 31599
android.view.InflateException: Binary XML file line #30 in com.valleydevfest.androidify:layout/fragment_main: Binary XML file line #30 in com.valleydevfest.androidify:layout/fragment_main: Error inflating class android.support.v4.view.ViewPager
Caused by: android.view.InflateException: Binary XML file line #30 in com.valleydevfest.androidify:layout/fragment_main: Error inflating class android.support.v4.view.ViewPager
Caused by: java.lang.ClassNotFoundException: android.support.v4.view.ViewPager
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:454)
at android.view.LayoutInflater.createView(LayoutInflater.java:815)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1006)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1126)
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 com.valleydevfest.androidify.PlaceholderFragment.onCreateView(PlaceholderFragment.java:48)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1514)
at android.app.Activity.performStart(Activity.java:7838)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3398)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2109)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.ClassNotFoundException: android.support.v4.view.ViewPager
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:454)
at android.view.LayoutInflater.createView(LayoutInflater.java:815)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1006)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1126)
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 com.valleydevfest.androidify.PlaceholderFragment.onCreateView(PlaceholderFragment.java:48)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1514)
at android.app.Activity.performStart(Activity.java:7838)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3398)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2109)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
问题是执行运行时出于某种原因搜索了 AndroidX 之前的 ViewPager android.support.v4.view.ViewPager
但是应该是 androidx.viewpager.widget.ViewPager
.
这就是我的布局 https://github.com/gdgfresno/androidify-yourself/blob/master/src/main/res/layout/fragment_main.xml
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_weight="90"
android:layout_width="match_parent"
android:layout_height="0dp"
android:padding="1dp"
android:orientation="vertical"
android:background="@drawable/border">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPagerHead"
android:layout_weight="30"
android:layout_width="match_parent"
android:layout_height="0dp" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPagerBody"
android:layout_weight="30"
android:layout_width="match_parent"
android:layout_height="0dp" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPagerLegs"
android:layout_weight="30"
android:layout_width="match_parent"
android:layout_height="0dp" />
</androidx.appcompat.widget.LinearLayoutCompat>
...
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.ViewPager;
...
final View rootView = inflater.inflate(R.layout.fragment_main, container, false);
mViewPagerHead = rootView.findViewById(R.id.viewPagerHead);
mViewPagerBody = rootView.findViewById(R.id.viewPagerBody);
mViewPagerLegs = rootView.findViewById(R.id.viewPagerLegs);
FragmentManager fm = getActivity().getSupportFragmentManager();
mViewPagerHead.setAdapter(new AndroidifyViewPagerAdapter(fm, AndroidDrawables.getHeads()));
mViewPagerBody.setAdapter(new AndroidifyViewPagerAdapter(fm, AndroidDrawables.getBodies()));
mViewPagerLegs.setAdapter(new AndroidifyViewPagerAdapter(fm, AndroidDrawables.getLegs()));
崩溃发生在 final View rootView = inflater.inflate(R.layout.fragment_main, container, false);
行。我清除了 gradle 缓存 (rm -rf $HOME/.gradle/cache
)。我擦除模拟器,卸载应用程序,重建应用程序。当一切都是 androidx
时,它从哪里得到 android.support.v4.view.ViewPager
?
我还在 build.gradle 中包含了 implementation 'androidx.fragment:fragment:1.2.5'
包,尽管这不是成功编译所必需的。提交项目问题 https://github.com/gdgfresno/androidify-yourself/issues/2
我继续按照本指南和我的常识将应用程序使用的 ViewPager 转换为 ViewPager2:https://developer.android.com/training/animation/vp2-migration
这是提交:https://github.com/gdgfresno/androidify-yourself/commit/df74fc3f0f2d98c3ae59969db11d3678d57a923a
显然,这消除了所有歧义和底层框架拉出一个不恰当的旧ViewPager
“魔术帽中的兔子”的机会。