RePlugin集成AndroidAutoSize

RePlugin集成AndroidAutoSize一、屏幕适配你可能会问“都2021年了还折腾屏幕适配?直接用dp单位适配不好吗?”,确实,如果公司的UI设计师、产品经理以及老板,能明白为什么一套UI在不同设备上显现出来的一些差异并不是bug时,开发者直接用dp单位配合一些布局技巧来进行适配是可以的,但是,实现多数情况下并不是如此美好,他们更希望看到的是UI在不同屏幕上,仅仅只是缩放的区别,为了满足这种要求,应用第三方屏幕适配方案就非常有必要了。根据在网上查到的比较好的原生屏幕适配方案有两种:smallestWidth

大家好,又见面了,我是你们的朋友全栈君。

一、屏幕适配

你可能会问 “都 2021 年了还折腾屏幕适配?直接用 dp 单位适配不好吗?”, 确实,如果公司的 UI 设计师、产品经理以及老板,能明白为什么一套 UI 在不同设备上显现出来的一些差异并不是 bug 时,开发者直接用 dp 单位配合一些布局技巧来进行适配是可以的,但是,实现多数情况下并不是如此美好,他们更希望看到的是 UI 在不同屏幕上,仅仅只是缩放的区别,为了满足这种要求,应用第三方屏幕适配方案就非常有必要了。根据在网上查到的比较好的原生屏幕适配方案有两种:

  • smallestWidth 限定符适配方案
  • 今日头条屏幕适配方案

两者的原理,以及优缺点这里不废话,有兴趣的可通过下方链接了解:

考虑到 apk 体积包大小问题,最终还是选择了 AndroidAutoSize,同时项目中有使用到插件化框架 RePlugin,需要在插件中集成 AndroidAutoSize,然而网上又几乎没有相关的集成踩坑资料,于是便有了本篇文章~

二、问题与解决方案

AndroidAutoSize 的使用说明及已知问题汇总请访问以下链接查看:

按作者的集成步骤,在 app 作为单品运行时是没有任何问题的,但是,如果你项目中使用了 RePlugin,一旦 app 作为插件运行中,你就会发现,一点用都没有!!!

注意:本文基于关闭常驻进程的前提完成的论证及测试,即:persistentEnable = false

1、框架初始化

不可否认,AndroidAutoSize 的框架设计很优秀,利用 ContentProvider 实现框架自动初始化工作,然而,这种”黑科技”在个别情况下不好使,比如有些魔改 ROM,还有就是作为 RePlugin 插件的时候,所以,AndroidAutoSize 没起作用的一方面原因是框架未能正常初始化,插件 AndroidManifest.xml 中声明的 ContentProvider 并不会自动被执行创建,也就是 InitProvider 没被执行到,好在该库提供了手动初始化的方式:

class MyApplication : Application() { 
   

    override fun onCreate() { 
   
        super.onCreate()
        // 手动直接执行 AutoSizeConfig#init()
        AutoSize.checkAndInit(this)

        // 通过启动InitProvider,再由InitProvider执行 AutoSizeConfig#init()
        // AutoSize.initCompatMultiProcess(this)
    }
}

AutoSize.checkAndInit(this) 亲测有效,AutoSize.initCompatMultiProcess(this) 没有测试过,理论上也是可以的,但大可不必。

通过上面的代码就可以解决 AndroidAutoSize 的初始化问题。另外,如果你担心 app 作为单品时,AutoSizeConfig#init() 会被 AutoSize.checkAndInit(this)InitProvider 执行多次的话,你可以选择把 InitProvider 移除掉:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
    <application ... android:name=".MyApplication">

        <provider tools:node="remove" android:name="me.jessyan.autosize.InitProvider" android:exported="false" android:multiprocess="true" android:authorities="${your application id}.autosize-init-provider" />
    </application>

</manifest>

关键点是 tools:node="remove",可以把 aar 中的 AndroidManifest.xml 声明好的组件移除。此处的 ${your application id} 需要根据你当前 app 的 appid 来修改,不知道怎么改的话,可以先正常打个包,再反编译看看 AndroidManifest.xml 中原来的 InitProvider 声明是怎样的就明白了。

其实并不需要担心 AutoSizeConfig#init() 会被执行多次的问题,框架肯定有做好防护措施的,但如果你很严谨,不想有意外情况发生的话,强烈建议把 InitProvider 移除,这样的话,不管是单品还是插件,初始化逻辑都将是一样的。

2、启动屏幕适配功能

解决完框架初始化的问题,现在 AndroidAutoSize 还是无法起作用的。通过 AndroidAutoSize 源码可以得知,框架会给 Application 注册一个 ActivityLifecycleCallbacks,用于执行各个 Activity 初始化时的适配工作,然后,当 app 作为插件时这个 ActivityLifecycleCallbacks 是不会回调的-_-

怎么用宿主的 Application 注册 ActivityLifecycleCallbacks 呢?Easy,在初始化 AndroidAutoSize 的时候用宿主的 Application 即可:

// if (RePlugin.getHostContext() != null) { // 插件
// AutoSize.checkAndInit(RePlugin.getHostContext().applicationContext as Application)
// } else { // 单品
// AutoSize.checkAndInit(this)
// }

// 简洁写法:
AutoSize.checkAndInit(RePlugin.getHostContext()?.applicationContext as? Application ?: this)

好了,到这里 AndroidAutoSize 就起作用了。

这个 ActivityLifecycleCallbacks (也就是 ActivityLifecycleCallbacksImpl) 相当重要,它生效了, CancelAdaptCustomAdapt 才能正常使用。

3、指定设计图尺寸

现在框架初始化,以及屏幕适配功能都已经没有问题了,接下来就是配置工作,默认情况下,AndroidAutoSize 会读取开发者在 AndroidManifest.xml 中预先填写好的 meta 设计图尺寸,用于计算 DisplayMetrics#density,然而当 app 作为插件时,你会发现这个配置也是无效的。

  • 原因:框架中通过 context 拿到的是宿主的 AndroidManifest.xml 信息,因为上面 AutoSize#checkAndInit() 传入的是宿主的 Application
  • 解决方案:由于 AutoSizeConfig#getMetaData(final Context context) 是私有方法,所以,你有 2 种选择:
    • 反射调用 AutoSizeConfig#getMetaData() 并传入插件的 Application
    • 改为代码配置的方式,给 AutoSizeConfig 直接指定设计图尺寸

别跟我说什么在宿主的 AndroidManifest.xml 中配置设计图尺寸,太 low 了-_-

怎么简单怎么来,这里就通过代码方式给 AutoSizeConfig 直接指定设计图尺寸:

AutoSize.checkAndInit(RePlugin.getHostContext()?.applicationContext as? Application ?: this)

// 注意:一定要在框架初始化之后再进行配置,否则框架内部拿不到正确的设计图尺寸(会被 AutoSizeConfig#init() 重置)
AutoSizeConfig.getInstance()
    // 手动指定设计图尺寸,不读取清单文件
    .setDesignWidthInDp(1280)
    .setDesignHeightInDp(720)
    // 设置使用冷门尺寸单位作为副单位
    .unitsManager
    .setSupportDP(false)
    .setSupportSP(false)
    .setSupportSubunits(Subunits.MM)

至此,AndroidAutoSize 无论是单品还是插件都能正常运作了,Nice~

三、其他

这里就已经和 RePlugin 的坑没有关系了,只是记录一些 AndroidAutoSize 的使用问题。

1、重写 Activity#getResources() 导致 CancelAdaptCustomAdapt 失效

原因是在 getResources()方法中没有判断当前 Activity 是否有实现 CancelAdaptCustomAdapt,一股脑全部适配导致的,只需要做个判断就好了:

abstract class BaseActivity : AppCompatActivity() { 
   

    ...

    override fun getResources(): Resources { 
   
        when (this) { 
   
            is CancelAdapt -> { 
   
                AutoSizeCompat.cancelAdapt(super.getResources())
            }
            is CustomAdapt -> { 
   
                AutoSizeCompat.autoConvertDensityOfCustomAdapt(super.getResources(), this)
            }
            else -> { 
   
                //需要升级到 v1.1.2 及以上版本才能使用 AutoSizeCompat
                AutoSizeCompat.autoConvertDensityOfGlobal((super.getResources())) //如果没有自定义需求用这个方法
                // AutoSizeCompat.autoConvertDensity((super.getResources()), 667f, false)//如果有自定义需求就用这个方法
            }
        }
        return super.getResources()
    }
}

RePlugin集成AndroidAutoSize

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/134862.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • [推荐算法]基于用户的协同过滤算法「建议收藏」

    [推荐算法]基于用户的协同过滤算法「建议收藏」什么是推荐算法推荐算法最早在1992年就提出来了,但是火起来实际上是最近这些年的事情,因为互联网的爆发,有了更大的数据量可以供我们使用,推荐算法才有了很大的用武之地。最开始,所以我们在网上找资料,都是进yahoo,然后分门别类的点进去,找到你想要的东西,这是一个人工过程,到后来,我们用google,直接搜索自己需要的内容,这些都可以比较精准的找到你想要的东西,但是,如果我自己都

    2022年6月29日
    22
  • java servlet容器有哪些_servlet容器是什么

    java servlet容器有哪些_servlet容器是什么Servlet 容器是一个程序 它是与 servlet 交互的 Web 服务器的一部分 它可以从 web 页面接收请求后再将这些请求重定向到 Servlet 对象中 然后将动态生成的结果返回到正确的位置中 在 Java 中 Servlet 容器用于生成动态网页 因此 servlet 容器是与 javaservlet 交互的 Web 服务器的基本部分 接下来将在文章中为大家详细介绍 Servlet 容器是什么 希望对大家有所帮助 推荐

    2025年8月23日
    4
  • 数据结构–最小生成树详解[通俗易懂]

    数据结构–最小生成树详解[通俗易懂]前言Awisemanchangeshismind,afoolnever.Name:WillamTime:2017/3/11、什么是最小生成树现在假设有一个很实际的问题:我们要在n个城市中建立一个通信网络,则连通这n个城市需要布置n-1一条通信线路,这个时候我们需要考虑如何在成本最低的情况下建立这个通信网?于是我们就可以引入连通图来解决我们遇到的问题,n个城市就是图上的n

    2025年7月2日
    3
  • python中关于命名的例子_Python 命名规范入门实例「建议收藏」

    python中关于命名的例子_Python 命名规范入门实例「建议收藏」这篇文章主要为大家详细介绍了Python命名规范入门实例,具有一定的参考价值,可以用来参考一下。对python这个高级语言感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧!一,包名、模块名、局部变量名、函数名全小写+下划线式驼峰example:this_is_var二,全局变量全大写+下划线式驼峰example:GLOBAL_VAR三,类名首字母大写式驼峰example:ClassNa…

    2022年6月25日
    26
  • freehosting申请空间和ssh -D设置

    freehosting申请空间和ssh -D设置前段时间申请了website.org的免费空间,可是有广告.在这时向大家推荐freehosting.com.Freehosting.com是一家创建于1996年的美国网站,国内在2006年有介绍过它的免费PHP空间,不过没能找到演示,目前免费空间的主机放在德国,提供1G存储空间,月流量为10G,采用CPanel控制管理面板(有简体中文版),支持FTP和Web在线文件管理(可在线解压缩),…

    2022年10月8日
    1
  • CSDN博客皮肤设置

    CSDN博客皮肤设置当你看到其他博客主们的博客界面很好看的时候,是不是自己也想设置成这样的呢?不幸的是新版CDSN博客皮肤设置已下线,所以无法在上面直接切换其他皮肤。幸运的是,这里有其他方法,也能切换到你喜欢的皮肤,具体步骤如下:1、打开个人的博客设置,然后按f12打开审查元素,使用选择器,选择当前皮肤。你会在文件中看到有类名为:opt-skin-box的div,这些都是皮肤。…

    2022年7月14日
    19

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号