android LayoutInflater源码分析以及换肤框架实现原理(2)

上一节android LayoutInflater源码分析以及换肤框架实现原理(1)了解完布局加载的源码后,这篇就是带大家去实现换肤框架。

主题换肤框架的实现思路?

什么是Android动态加载技术?

动态加载的定义态加载的定

         Android中动态加载的核心思想是动态调用外部的 dex文件。极端的情况下,Android APK自身带有的Dex文件只是一个程序的入口(或者说空壳),所有的功能都通过从服务器下载最新的Dex文件完成;应用在运行的时候去加载一些本地的可执行文件实现一些特定的功能

动态加载什么文件?

动态加载so库;

动态加载dex/jar/apk文件;

应该怎样去进行资源替换?

整理思路

Q1 怎样去获取皮肤包中的资源?

2 怎么确定当前客户端中有哪些资源要进行替换?

3 怎样进行资源替换?

4 在什么时候将皮肤包中的资源替换到当前客户端中?

A 1    怎样去获取皮肤包中的资源?

首先从服务端下载皮肤包进手机存储控件,因为动态加载的格式要求,所以文件的格式需对应。对资源文件的加载我们需要用到Resources。

是不是通过context.getResources()就可以拿到了呢? 不可以!每一个Resources管理的是一个文件路径下的资源。而我们要加载的外部资源肯定与我们在当前应用获取资源的路径不一样,所以我们需要去重新创建一个加载外部文件的Resources对象。

                                                                (图2)

在Resources的构造函数中需要传入assetManager 对象,assetManager是真正管理资源的类,而且其构造函数被hidden,所以无法直接new,只能通过反射的方式去创建对象。

获取到resources后,我们要拿到资源包响应资源可以调用api

int identifier = resources.getIdentifier(resourceEntryName,
        resourceTypeName, skinPackageName);

这里的返回值是int类型,就是在R文件中的资源id。通过是需要传入资源定义的name,类型,与资源的包名,包名在图二中已经获取到了,至于name ,为了更好的去匹配需要替换的资源,一般我们会去将资源包中的资源name 跟 原apk 中资源name 定义一致,不同的只是name对应的资源的值。

A 2   怎么确定当前客户端中有哪些资源要进行替换?'

       至于哪些资源需要替换,我们肯定得需要替换得资源加上某个标识。

我们可以自定义资源属性,新增一个是否需要替换的属性。然后在布局文件中申明,该属性是否需要替换。如下图

   

                                                         (图3)

标识已经加上,那什么时候能够获取到该属性呢?

在上一遍文章中android LayoutInflater源码分析以及换肤框架实现原理(1)我们知道了view的生成都是通过Factory2的实现类进行初始化的,那么我们要对View进行资源替换,就得去自定义Foctory2来代码系统的实现。

                                                           (图4)

这里注意Factory2 的生成设置必须在super.onCreate(savedInstanceState);之前,也就是说我们自定义的Factory2要在系统生成的之前。

SkinFactory implements LayoutInflater.Factory2需要实现两个方法。
public View onCreateView(View view, String s, Context context, AttributeSet attributeSet) {}
public View onCreateView(String s, Context context, AttributeSet attributeSet) {}

这两个重载方法我们也在上篇文章中分析过,三个参数的是老版本继承Activity的实现方法。四个参数的是继承AppCompatActivity的实现方法。

可以看到他们都要一个AttributeSet参数.这个参数就是每一个View的资源集合。

那么我们既然拿到了资源集合,那就可以通过遍历的方式找到需要去替换的资源了。这里把遍历的过程封装到paserView方法中。

                                                                (图5)

这里为了方便后面更好的去替换资源,我们使用了一个SkinItem集合

                                

                                                                 (图6)

A 3 怎样进行资源替换?

    从图5的代码中可以看到,这里获取到需要替换的资源的id,name与类型,并赋值到  SkinItem中。既然已经拿到了需要资源替换的资源下一步我们就要将对应的资源包资源进行替换。我们通过遍历SkinItems集合,对其一一替换。

        

                                                                (图7)

                                                                (图8)

图8是对图7红框的地方进行补充。可以看的我们将应用本身的资源id传了下去,我们通过应用自身的resoures获取该资源的name,与类型。这两个参数同时与外包资源的name,与类型也是保持一致的,那么通过我们新建的外部资源管理器resoures就可以拿到外包资源id了。最后就可以进行控件的属性赋值了。这里只对Color属性进行了演示,对于Drawble也是类似的操作。资源的替换我们也完成了。

A 4 在什么时候将皮肤包中的资源替换到当前客户端中?

具体业务决定

    

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值