插件式换肤框架搭建 - 资源加载源码分析
资源加载源码分析
1.首先我们来看一下ImageView是如何加载资源的:
public ImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);......final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ImageView, defStyleAttr, defStyleRes);final Drawable d = a.getDrawable(R.styleable.ImageView_src);if (d != null) {setImageDrawable(d);}......}@Nullablepublic Drawable getDrawable(@StyleableRes int index) {return getDrawableForDensity(index, 0);}@Nullablepublic Drawable getDrawableForDensity(@StyleableRes int index, int density) {if (mRecycled) {throw new RuntimeException("Cannot make calls to a recycled instance!");}final TypedValue value = mValue;if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {if (value.type == TypedValue.TYPE_ATTRIBUTE) {throw new UnsupportedOperationException("Failed to resolve attribute at index " + index + ": " + value);}if (density > 0) {// If the density is overridden, the value in the TypedArray will not reflect this.// Do a separate lookup of the resourceId with the density override.mResources.getValueForDensity(value.resourceId, density, value, true);}//加载资源其实是通过mResources去获取的return mResources.loadDrawable(value, value.resourceId, density, mTheme);}return null;}
2.Resource创建过程分析:
@Deprecatedpublic Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {this(null);mResourcesImpl = new ResourcesImpl(assets, metrics, config, new DisplayAdjustments());}
AssetManager创建源码:
private static void ensureSystemAssets() {synchronized (sSync) {if (sSystem == null) {AssetManager system = new AssetManager(true);system.makeStringBlocks(null);sSystem = system;}}
aseet对象核心方法:
public final int addAssetPath(String path) {return addAssetPathInternal(path, false);
}private final int addAssetPathInternal(String path, boolean appAsLib) {synchronized (this) {int res = addAssetPathNative(path, appAsLib);makeStringBlocks(mStringBlocks);return res;}
}private native final int addAssetPathNative(String path, boolean appAsLib);
path指的是资源apk路径。
换肤实战
public class MainActivity extends AppCompatActivity {public static final int REQUEST_PERMISSION_CODE = 0x01;private boolean isGetPermission = false;private static String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {if (ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);}else{isGetPermission = true;}}Button btnC = findViewById(R.id.btn_change);final ImageView iv_ = findViewById(R.id.iv_);if (isGetPermission){btnC.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {Resources superRes = getResources();// 创建AssetManager,但是不能直接new所以只能通过反射AssetManager assetManager = AssetManager.class.newInstance();// 反射获取addAssetPath方法Method addAssetPathMethod = AssetManager.class.getDeclaredMethod("addAssetPath",String.class);// 皮肤包的路径: 本地sdcard/plugin.skinString skinPath = Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator+"plugin.skin";// 反射调用addAssetPath方法addAssetPathMethod.invoke(assetManager, skinPath);// 创建皮肤的Resources对象Resources skinResources = new Resources(assetManager,superRes.getDisplayMetrics(),superRes.getConfiguration());// 通过资源名称,类型,包名获取Idint bgId = skinResources.getIdentifier("lzy","drawable","com.example.haunfu01");Drawable bgDrawable = skinResources.getDrawable(bgId);// 设置背景iv_.setImageDrawable(bgDrawable);} catch (Exception e) {e.printStackTrace();}}});}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == REQUEST_PERMISSION_CODE&&grantResults[0]==0&&grantResults[1]==0) {isGetPermission = true;}}}
插件式换肤框架搭建 - 资源加载源码分析相关推荐
- Cocos Creator2.4.8 资源加载源码阅读
最近用到资源加载的问题:加载的资源进度条倒退问题,现在只是用临时的解决方案 - 加载进度如果出现会倒退的问题还是用原来的数值.抽时间看了下cocos creator 资源加载的源码,整理了一下脑图 一 ...
- springboot环境变量(environment)加载源码分析
代码入口 //SpringApplication run 环境变量初始化入口 prepareEnvironment(listeners, bootstrapContext, applicationAr ...
- spring boot实战(第十篇)Spring boot Bean加载源码分析
前言 前面的文章描述了Application对应Bean的创建,本篇将阐述spring boot中bean的创建过程 refresh 首先来看SpringApplication#run方法中refre ...
- hanlp中文语言处理--词典加载源码过程分析及自定义用户词汇添加
一.hanlp本地词典加载源码分析 hanlp在调用提供的函数处理文本时会先初始化本地词典,加载词典进入内存中 以中文分词接口为例子 1.调用分词函数入口 public class DemoAtFir ...
- 换肤方案,换肤策略,App插件式换肤实现方案
UI换皮肤或白天黑夜模式,从产品上来看,是两种不同产品设计模式:白天黑夜模式只有两种模式:而换皮肤可以有多套,可以进行商业化,并盈利. 换肤的本质就是去替换资源文件.我们知道,Android应用程序由 ...
- android换肤动画,Android换肤(二) — 插件式换肤
###前言 上节我们讲到了`Android-skin-support`库的应用内换肤,大家感兴趣的可以参看文章: [Android换肤(一) - 应用内换肤](http://www.demodashi ...
- Android 手写实现插件化换肤框架 兼容Android10 Android11
目录 一.收集所有需要换肤的view及相关属性 二.统一为所有Activity设置工厂(兼容Android9以上) 三.加载皮肤包资源 四.处理支持库或者自定义view的换肤 五.处理状态栏换肤 六. ...
- (源码阅读)插件式换肤的demo的实现
在通过阅读Resources资源加载的流程后,知道了Android的资源加载都是通过Resources这个类来加载的,所以我们也来写一个小型的插件式换肤的demo 主要就是在Activiy里面写了,主 ...
- android 换肤框架搭建及使用 (3 完结篇)
本系列计划3篇: Android 换肤之资源(Resources)加载(一) setContentView() / LayoutInflater源码分析(二) 换肤框架搭建(三) - 本篇 tips: ...
最新文章
- 6个整改!2018年国家重点实验室评估结果公布
- 浅谈通信编程(二)--如何分离通信物理接口和应用程序
- php 编辑器中使用短代码,php-在WooCommerce短代码输出中更改标记
- Android 之UID and PID
- 【转载】创建型-工厂方法模式
- mysql 赋给用户权限 grant all privileges on
- Apache OpenJPA 2.1.0 发布
- ubuntu进程管理方法
- 文员常用的8个excel函数
- Linux驱动开发(九)---树莓派I2C设备驱动开发(BME280)
- 抖音快手短视频去水印小程序解析接口API开发文档
- zookeeper学习笔记(一)--快速入门与集群部署
- 自定义View——弹性滑动
- 年后跳槽全过程总结(上)——从面试准备到拿到offer
- 基于离散小波变换 (DWT)的图像信息隐藏算法
- Python如何导入自己编写的py文件(.pyx文件 .pyd文件)
- unity文本隐藏_AI论文中隐藏的笑话,全看懂的绝对是高手!
- 调用百度地图api实现地图查询功能
- PYQT5(13)-基本窗口控件-拖曳与剪贴板
- python爬虫什么书好_python爬虫什么书
热门文章
- K13252 [国王游戏2]
- 《中国通史》纪录片100集笔记(持更)
- 《中国通史 2016》_12_读后感
- 购物网站商城系统,购物网站毕业设计,B2C网上购物系统毕业设计
- 盗将行——微信群防骗指南
- ERD图“乌鸦脚”形式表示的关系的使用方法与理解
- 2022 年终奖个税计算方法,看看你被多收割了多少
- 重磅上线!万兴科技旗下亿图图示12.0打造全新智能绘图体验
- sql 一张表递归_查看我的递归视觉指南(因为一张图片价值1,000字)
- POP3, SMTP, IMAP 和 Exchange 的区别