博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
迁移到 AndroidX 过程中遇到的各种问题
阅读量:2121 次
发布时间:2019-04-30

本文共 20883 字,大约阅读时间需要 69 分钟。

该博文用来整理开源项目 迁移到 AndroidX 过程中遇到的各种问题。

? Android-References 是一个 Android 示例程序项目:包含了 MVP, MVVM, 组件化, ARouter, RxJava, EventBus, ButterKnife, 视频播放, 视频直播, 网络访问, 布局和控件整理等,感性却可以到 Gihub: 参考源码。

因为该项目包含了各种 support 包控件,并且各种组件化、架构模式和各种常见的功能一应俱全,因此,比较具有代表性。这里我们使用它来作为一个示例来将我们的项目迁移到 AndroidX。

1、关于 AndroidX

关于 AndroidX,可以参考:

AndroidX 用来统一 Android 中的 support 包,之前我们通过引入 support 包的各个版本来使用支持包,现在我们可以通过使用 AndroidX 来使用支持包。从长远来看这当然是大有好处的,可以避免使用支持包中遇到的版本冲突、升级带来的各种问题。

不过,如果项目完全迁移到 AndroidX 风险还是太大。如果项目紧急的话,引入 AndroidX 成本都有些高,主要是因为一些三方库的原因。虽然一些使用特别多的三方库,比如 Glide 等都已经开始支持 AndroidX。当然,还有一些潜在的问题,比如使用字符串来获取类的 Behavior 等,迁移的时候可能就不会被照顾到。

为了迁移到 AndroidX,Google 给开发者提供了一个工具:在 AS 的 Refactor 中提供了一项 Migrate to AndroidX 的选项。但选择了迁移之后,出现一些问题还需要开发者自己手动解决。

2、着手迁移

2.1 第一个问题:Execution failed for task ‘:app:transformClassesWithMultidexlistForAlphaDebug’

这里我们迁移之后在 build 的时候出现了标题的问题:

* What went wrong:Execution failed for task ':app:transformClassesWithMultidexlistForAlphaDebug'.> com.android.build.api.transform.TransformException: Error while generating the main dex list.

显然是将 class 转换成 dex 的过程中出现了一些问题,不过只是上面的这行日志我们无法定位问题。所以,我们需要让 gradle 输出更多的错误信息,于是我们执行:

gradlew build --stacktrace

来让 Gradle 输出错误栈信息:

Caused by: com.android.builder.multidex.D8MainDexList$MainDexListException: com.android.tools.r8.errors.CompilationError: Program type already present: com.alibaba.android.arouter.routes.ARouter$$Group$$library        at com.android.builder.multidex.D8MainDexList.generate(D8MainDexList.java:87)        at com.android.build.gradle.internal.transforms.D8MainDexListTransform.transform(D8MainDexListTransform.kt:131)        ... 54 more

显然是 ARouter$$Group$$library 类的问题,我们使用 Ctrl+N 来搜索这个类,发现出现了两个同样的类。这个类是使用阿里的 ARouter 的时候在编译期间生成的:

在这里插入图片描述

按照上面的错误提示,该类同时出现在了我们的两个模块 librarieslayout 下面,因而类冲突了。所以,接下来的问题就是要发现为什么会出现类冲突。

经过一层层排查发现是一个地方写错了:

在这里插入图片描述

这个是 layout 模块下面的冲突的类,我们发现它的路由地址是 /library/swipe_back,所以因为路由的地址是 library 的原因它在 layout 的模块下面生成了 ARouter$$Group$$Library。按照正确的写法它应该是出现在 layout 模块下面,并且路由的地址是 /layout/swipe_back,那样就应该被生成到 ARouter$$Group$$Layout 下面,就不会多出一个类 ARouter$$Group$$Library 了。

虽然,最终问题的原因很简单,但是我们看到,发现问题的过程中需要自己有思路的去排查,而不是除了问题立刻 Google 或者 SOF。

2.2 android.view.InflateException: Binary XML file line #14: Error inflating class

修改了上面的问题之后,我们的程序可以编译并且安装了。

然后,我们又遇到下面的问题:

android.view.InflateException: Binary XML file line #14: Error inflating class

这种问题比较常见,是 XML 的某个地方写错了,经过排查发现有一行代码,当我们为控件添加 Behavior 的时候使用了字符串形式的类名。在迁移的时候没有被照顾到:

在这里插入图片描述

事实上在 Google 的新的 material 包下面的 values.xml 文件中定义了一些 Behavior,新的包中这些字符串的值已经被替换过。但是像我们上面的这种情况,因为使用的是字符串而不是引用的资源,所以就没有被替换过去。因此,引用非自定义的 Behavior 的时候需要注意使用字符串资源进行引用而不是使用字符串:

在这里插入图片描述

2.3 android.view.InflateException: Binary XML file line #12: Binary XML file line #12: Error inflating class com.google.android.material.button.MaterialButton

这里的类 Support28Activity 用来整理原来的 support-28 包里面的一些控件,迁移之后页面打开的时候立即崩溃。然后留下了一地鸡毛(异常):

java.lang.RuntimeException: Unable to start activity ComponentInfo{me.shouheng.references/me.shouheng.layout.view.support28.Support28Activity}: android.view.InflateException: Binary XML file line #12: Binary XML file line #12: Error inflating class com.google.android.material.button.MaterialButton

我们尝试在程序中寻找 MaterialButton,发现确实能够找到这个类,但这里加载失败是什么原因呢?

于是我们继续查看输出的错误日志,从这里我们获取到了更多的信息。

Process: me.shouheng.references, PID: 22961    java.lang.RuntimeException: Unable to start activity ComponentInfo{me.shouheng.references/me.shouheng.layout.view.support28.Support28Activity}: android.view.InflateException: Binary XML file line #12: Binary XML file line #12: Error inflating class com.google.android.material.button.MaterialButton        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3037)        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3172)        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1906)        at android.os.Handler.dispatchMessage(Handler.java:106)        at android.os.Looper.loop(Looper.java:193)        at android.app.ActivityThread.main(ActivityThread.java:6863)        at java.lang.reflect.Method.invoke(Native Method)        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)     Caused by: android.view.InflateException: Binary XML file line #12: Binary XML file line #12: Error inflating class com.google.android.material.button.MaterialButton     Caused by: android.view.InflateException: Binary XML file line #12: Error inflating class com.google.android.material.button.MaterialButton     Caused by: java.lang.reflect.InvocationTargetException        at java.lang.reflect.Constructor.newInstance0(Native Method)        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)        at android.view.LayoutInflater.createView(LayoutInflater.java:647)        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790)        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)        at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:126)        at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:95)        at me.shouheng.commons.view.activity.CommonActivity.onCreate(CommonActivity.java:41)        at android.app.Activity.performCreate(Activity.java:7149)        at android.app.Activity.performCreate(Activity.java:7140)        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1288)        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3017)        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3172)        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1906)        at android.os.Handler.dispatchMessage(Handler.java:106)        at android.os.Looper.loop(Looper.java:193)        at android.app.ActivityThread.main(ActivityThread.java:6863)        at java.lang.reflect.Method.invoke(Native Method)        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)     Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant).        at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:240)        at com.google.android.material.internal.ThemeEnforcement.checkMaterialTheme(ThemeEnforcement.java:215)        at com.google.android.material.internal.ThemeEnforcement.checkCompatibleTheme(ThemeEnforcement.java:143)2018-11-10 15:21:55.948 22961-22961/me.shouheng.references E/AndroidRuntime:     at com.google.android.material.internal.ThemeEnforcement.obtainStyledAttributes(ThemeEnforcement.java:78)        at com.google.android.material.button.MaterialButton.
(MaterialButton.java:140) at com.google.android.material.button.MaterialButton.
(MaterialButton.java:133) ... 27 more

按照后面几行的意思:

Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant).

这个错误是因为我们设置的主题照成的。按照上面的意思,我们需要更新自己的控件的主题到 Theme.MaterialComponents。除了切换控件的主题,我们可以更新应用的主题,我们可以让自己的应用主题继承 Material Components Bridge 主题:

可以根据自己的需要选择继承下面的几种主题:

Theme.MaterialComponents.BridgeTheme.MaterialComponents.Light.BridgeTheme.MaterialComponents.NoActionBar.BridgeTheme.MaterialComponents.Light.NoActionBar.BridgeTheme.MaterialComponents.Light.DarkActionBar.Bridge

或者在你之前的 AppCompact 主题之上增加一些新的属性:

显然,这里是要求你为了使自己的应用符合 Material 规范,需要预先定义一些属性值,然后会被应用到程序的控件中。

这里我们将主题稍做修改

按照上面的方式,我们成功地打开了该页面。

2.4 java.lang.IllegalArgumentException: Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed

然而打开了页面不久就又发现了问题,这个问题出现在 MaterialButton 的点击的时候:

Process: me.shouheng.references, PID: 5730    java.lang.IllegalArgumentException: Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed        at android.graphics.Canvas.checkValidClipOp(Canvas.java:779)        at android.graphics.Canvas.clipRect(Canvas.java:826)        at com.google.android.material.shape.MaterialShapeDrawable.prepareCanvasForShadow(MaterialShapeDrawable.java:850)        at com.google.android.material.shape.MaterialShapeDrawable.draw(MaterialShapeDrawable.java:746)        at android.view.View.getDrawableRenderNode(View.java:20622)        at android.view.View.drawBackground(View.java:20558)        at android.view.View.draw(View.java:20357)        at android.view.View.updateDisplayListIfDirty(View.java:19241)        at android.view.View.draw(View.java:20094)        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)        at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1246)        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4116)        at android.view.View.updateDisplayListIfDirty(View.java:19232)        at android.view.View.draw(View.java:20094)        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4116)        at android.view.View.updateDisplayListIfDirty(View.java:19232)        at android.view.View.draw(View.java:20094)        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4116)        at android.view.View.updateDisplayListIfDirty(View.java:19232)        at android.view.View.draw(View.java:20094)        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4116)        at android.view.View.updateDisplayListIfDirty(View.java:19232)        at android.view.View.draw(View.java:20094)        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4116)        at android.view.View.updateDisplayListIfDirty(View.java:19232)        at android.view.View.draw(View.java:20094)        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4116)        at android.view.View.draw(View.java:20369)        at com.android.internal.policy.DecorView.draw(DecorView.java:781)        at android.view.View.updateDisplayListIfDirty(View.java:19241)        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:690)        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:696)        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:805)        at android.view.ViewRootImpl.draw(ViewRootImpl.java:3515)        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3312)        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2681)        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1633)        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7786)        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1004)        at android.view.Choreographer.doCallbacks(Choreographer.java:816)        at android.view.Choreographer.doFrame(Choreographer.java:751)        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:990)        at android.os.Handler.handleCallback(Handler.java:873)        at android.os.Handler.dispatchMessage(Handler.java:99)        at android.os.Looper.loop(Looper.java:193)        at android.app.ActivityThread.main(ActivityThread.java:6863)        at java.lang.reflect.Method.invoke(Native Method)        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

经过排查发现,在 com.google.android.material.shape.MaterialShapeDrawable 中的 prepareCanvasForShadow() 方法中使用了 Region.Op.REPLACE

private void prepareCanvasForShadow(Canvas canvas) {    // ... 无关代码    canvas.clipRect(canvasClipBounds, Region.Op.REPLACE);    // ... 无关代码  }

而在 support-28 中增加了下面的校验(这个校验在 support-27 上面是不存在的),显然是因为我们使用了 Region.Op.REPLACE 属性的原因:

private static void checkValidClipOp(@NonNull Region.Op op) {        if (sCompatiblityVersion >= Build.VERSION_CODES.P                && op != Region.Op.INTERSECT && op != Region.Op.DIFFERENCE) {            throw new IllegalArgumentException(                    "Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed");        }    }

在该方法上面有真么几行注释:

Region.Op values other than Region.Op.INTERSECT and Region.Op.DIFFERENCE have the ability to expand the clip. The canvas clipping APIs are intended to only expand the clip as a result of a restore operation. This enables a view parent to clip a canvas to clearly define the maximal drawing area of its children. The recommended alternative calls are clipRect(Rect) and clipOutRect(Rect)

大体意思是:Region.Op.INTERSECT和Region.Op.DIFFERENCE以外的Region.Op值可以展开 Clip。画布剪辑API仅用于在还原操作后展开Clip。这使视图父级能够剪切画布以清楚地定义其子画面的最大绘制区域。推荐调用clipRect(Rect)和clipOutRect(Rect).

虽然我们找到了问题的原因,但是这个类究竟是在哪里用到的我们还无法定位到,因此,我们还需要进一步进行排查。

经过排查,我们发现出现问题的原因是 material 包中的 BottomAppBar 控件。其实从上面的栈中我们也可以看出这一点:明显是在绘制 View 树的子 View 的时候出现的异常,而且是绘制 CoordinatorLayout。在 BottomAppBar 中使用了 materialShapeDrawable,该变量是 MaterialShapeDrawable。正是出现问题的罪魁祸首。

这个类MaterialShapeDrawable是用来实现 BottomBar 的阴影效果的,虽然它是 BottomBar 的内部类,但是如果不希望它调用上面的那个方法也是可以的。

首先,我发现它要先判断是否具有阴影再调用绘制阴影的方法:

if (hasCompatShadow()) {      // Save the canvas before changing the clip bounds.      canvas.save();      prepareCanvasForShadow(canvas);	  // ...无关代码    }

而这里的判断是否具有阴影的方法如下:

private boolean hasCompatShadow() {    return shadowCompatMode != SHADOW_COMPAT_MODE_NEVER        && shadowCompatRadius > 0        && (shadowCompatMode == SHADOW_COMPAT_MODE_ALWAYS || requiresCompatShadow());  }

我们可以通过为 BottomBar 设置移除阴影效果来避免这个类调用绘制阴影的方法。于是,

虽然效果不好看,但是阴影解决了。

2.5 android.view.InflateException: Binary XML file line #24: Binary XML file line #24: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton

在排查上面问题的过程中,我们同样发现了 FAB 的一个问题。这个 Material 包中的 FAB 与 Support-28 包中的相比做了一些调整。且看下面的异常信息。这里问题显然是类无法记载造成的。那么具体是因为什么呢?我们往下看到错误栈的最后几行,发现是有一个属性没有找到。

2018-11-10 16:56:48.408 27581-27581/me.shouheng.references E/AndroidRuntime: FATAL EXCEPTION: main    Process: me.shouheng.references, PID: 27581    java.lang.RuntimeException: Unable to start activity ComponentInfo{me.shouheng.references/me.shouheng.layout.view.support28.BottomAppBarActivity}: android.view.InflateException: Binary XML file line #24: Binary XML file line #24: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3037)        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3172)        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1906)        at android.os.Handler.dispatchMessage(Handler.java:106)        at android.os.Looper.loop(Looper.java:193)        at android.app.ActivityThread.main(ActivityThread.java:6863)        at java.lang.reflect.Method.invoke(Native Method)        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)     Caused by: android.view.InflateException: Binary XML file line #24: Binary XML file line #24: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton     Caused by: android.view.InflateException: Binary XML file line #24: Error inflating class com.google.android.material.floatingactionbutton.FloatingActionButton     Caused by: java.lang.reflect.InvocationTargetException        at java.lang.reflect.Constructor.newInstance0(Native Method)        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)        at android.view.LayoutInflater.createView(LayoutInflater.java:647)        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790)        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)        at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:126)        at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:95)        at me.shouheng.commons.view.activity.CommonActivity.onCreate(CommonActivity.java:41)        at android.app.Activity.performCreate(Activity.java:7149)        at android.app.Activity.performCreate(Activity.java:7140)        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1288)        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3017)        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3172)        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1906)        at android.os.Handler.dispatchMessage(Handler.java:106)        at android.os.Looper.loop(Looper.java:193)        at android.app.ActivityThread.main(ActivityThread.java:6863)        at java.lang.reflect.Method.invoke(Native Method)        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)     Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f0300b3 a=3}        at android.content.res.TypedArray.getColorStateList(TypedArray.java:565)        at com.google.android.material.resources.MaterialResources.getColorStateList(MaterialResources.java:65)        at com.google.android.material.floatingactionbutton.FloatingActionButton.
(FloatingActionButton.java:204)2018-11-10 16:56:48.408 27581-27581/me.shouheng.references E/AndroidRuntime: at com.google.android.material.floatingactionbutton.FloatingActionButton.
(FloatingActionButton.java:190) ... 27 more

根据错误的栈信息,我们到指定的方法下面去查看问题的原因,发现是设置背景着色的时候出现的问题:

backgroundTint =        MaterialResources.getColorStateList(            context, a, R.styleable.FloatingActionButton_backgroundTint);

但我们并没有为 FAB 添加该属性,那么又是哪里出现的问题呢?原来是因为我们为 FAB 添加了一个 style:

style="@style/Widget.MaterialComponents.FloatingActionButton"

而该 style 的定义是:

    

这样刚好与我们的问题吻合,所以解决的方案就是移除这个属性。

2.6 java.net.UnknownServiceException: CLEARTEXT communication to not permitted by network security policy

按照上面的方式对我们的项目做了调整之后,我们发现项目已经可以运行了。接下来出现的问题是网络访问过程中出现的。当我们访问网络的时候会遇到下面的这个异常:

java.net.UnknownServiceException: CLEARTEXT communication to baobab.kaiyanapp.com not permitted by network security policy

这个是因为 Android P 中新引入了网络安全规则,以上内容会对使用 http 的 URL 出现,默认会禁止访问 http 类型的地址。

当然,通常我们发布的时候会使用 Https 类型的网络协议,而当开发和调试的时候可能就没有那么严格了。所以,为了解决这个问题, Android 新引入了下面的解决方案:

首先,创建配置文件 res/xml/network_security_config.xml,内容如下:

localhost

这里的 ``localhost是 host 的地址,比如我上面的出错的地址应该是kaiyanapp.com`。

然后,我们将其配置到 manifest.xml 中:

在我们的项目中使用了三个不同的地址,并且都是 http 的,所以就需要在该地址下面配置三个域名,然后再次访问网络,问题就解决了。

关于 Android 网络和安全的内容,建议参考官方文档:。

总结

显然迁移到 AndroidX 的过程中还是会出现许多问题的,大多数是与 Android 的支持包有关的。按照我们上面遇到的问题,主要包括以下几点内容:

  1. 主题
  2. 支持库的控件(控件属性,实现方式好像变了一些)
  3. 三方库,许多库并没有迁移,所以会导致程序内标红,但是编译和运行没有问题
  4. 网络安全,网络安全部分做了一些调整

好了,这篇文章大致到这里。也希望通过这篇文章来让你了解下迁移到 AndroidX 过程中可能会出现什么问题,并以此来考虑迁移的成本。


如果您喜欢我的文章,可以在以下平台关注我:

  • 个人主页:
  • 掘金:
  • Github:
  • CSDN:
  • 微博:

转载地址:http://okurf.baihongyu.com/

你可能感兴趣的文章
开源Faac实现PCM编码AAC
查看>>
Windows下wave API 音频采集
查看>>
借船过河:一个据说能看穿你的人性和欲望的心理测试
查看>>
AndroidStudio 导入三方库使用
查看>>
Ubuntu解决gcc编译报错/usr/bin/ld: cannot find -lstdc++
查看>>
解决Ubuntu14.04 - 16.10版本 cheese摄像头灯亮却黑屏问题
查看>>
解决Ubuntu 64bit下使用交叉编译链提示error while loading shared libraries: libz.so.1
查看>>
VS生成DLL文件供第三方调用
查看>>
Android Studio color和font设置
查看>>
Python 格式化打印json数据(展开状态)
查看>>
Centos7 安装curl(openssl)和libxml2
查看>>
Centos7 离线安装RabbitMQ,并配置集群
查看>>
Centos7 or Other Linux RPM包查询下载
查看>>
运行springboot项目出现:Type javax.xml.bind.JAXBContext not present
查看>>
Java中多线程向mysql插入同一条数据冲突问题
查看>>
Idea Maven项目使用jar包,添加到本地库使用
查看>>
FastDFS集群架构配置搭建(转载)
查看>>
HTM+CSS实现立方体图片旋转展示效果
查看>>
FFmpeg 命令操作音视频
查看>>
问题:Opencv(3.1.0/3.4)找不到 /opencv2/gpu/gpu.hpp 问题
查看>>