资源加载源码分析

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;}}}

插件式换肤框架搭建 - 资源加载源码分析相关推荐

  1. Cocos Creator2.4.8 资源加载源码阅读

    最近用到资源加载的问题:加载的资源进度条倒退问题,现在只是用临时的解决方案 - 加载进度如果出现会倒退的问题还是用原来的数值.抽时间看了下cocos creator 资源加载的源码,整理了一下脑图 一 ...

  2. springboot环境变量(environment)加载源码分析

    代码入口 //SpringApplication run 环境变量初始化入口 prepareEnvironment(listeners, bootstrapContext, applicationAr ...

  3. spring boot实战(第十篇)Spring boot Bean加载源码分析

    前言 前面的文章描述了Application对应Bean的创建,本篇将阐述spring boot中bean的创建过程 refresh 首先来看SpringApplication#run方法中refre ...

  4. hanlp中文语言处理--词典加载源码过程分析及自定义用户词汇添加

    一.hanlp本地词典加载源码分析 hanlp在调用提供的函数处理文本时会先初始化本地词典,加载词典进入内存中 以中文分词接口为例子 1.调用分词函数入口 public class DemoAtFir ...

  5. 换肤方案,换肤策略,App插件式换肤实现方案

    UI换皮肤或白天黑夜模式,从产品上来看,是两种不同产品设计模式:白天黑夜模式只有两种模式:而换皮肤可以有多套,可以进行商业化,并盈利. 换肤的本质就是去替换资源文件.我们知道,Android应用程序由 ...

  6. android换肤动画,Android换肤(二) — 插件式换肤

    ###前言 上节我们讲到了`Android-skin-support`库的应用内换肤,大家感兴趣的可以参看文章: [Android换肤(一) - 应用内换肤](http://www.demodashi ...

  7. Android 手写实现插件化换肤框架 兼容Android10 Android11

    目录 一.收集所有需要换肤的view及相关属性 二.统一为所有Activity设置工厂(兼容Android9以上) 三.加载皮肤包资源 四.处理支持库或者自定义view的换肤 五.处理状态栏换肤 六. ...

  8. (源码阅读)插件式换肤的demo的实现

    在通过阅读Resources资源加载的流程后,知道了Android的资源加载都是通过Resources这个类来加载的,所以我们也来写一个小型的插件式换肤的demo 主要就是在Activiy里面写了,主 ...

  9. android 换肤框架搭建及使用 (3 完结篇)

    本系列计划3篇: Android 换肤之资源(Resources)加载(一) setContentView() / LayoutInflater源码分析(二) 换肤框架搭建(三) - 本篇 tips: ...

最新文章

  1. 6个整改!2018年国家重点实验室评估结果公布
  2. 浅谈通信编程(二)--如何分离通信物理接口和应用程序
  3. php 编辑器中使用短代码,php-在WooCommerce短代码输出中更改标记
  4. Android 之UID and PID
  5. 【转载】创建型-工厂方法模式
  6. mysql 赋给用户权限 grant all privileges on
  7. Apache OpenJPA 2.1.0 发布
  8. ubuntu进程管理方法
  9. 文员常用的8个excel函数
  10. Linux驱动开发(九)---树莓派I2C设备驱动开发(BME280)
  11. 抖音快手短视频去水印小程序解析接口API开发文档
  12. zookeeper学习笔记(一)--快速入门与集群部署
  13. 自定义View——弹性滑动
  14. 年后跳槽全过程总结(上)——从面试准备到拿到offer
  15. 基于离散小波变换 (DWT)的图像信息隐藏算法
  16. Python如何导入自己编写的py文件(.pyx文件 .pyd文件)
  17. unity文本隐藏_AI论文中隐藏的笑话,全看懂的绝对是高手!
  18. 调用百度地图api实现地图查询功能
  19. PYQT5(13)-基本窗口控件-拖曳与剪贴板
  20. python爬虫什么书好_python爬虫什么书

热门文章

  1. K13252 [国王游戏2]
  2. 《中国通史》纪录片100集笔记(持更)
  3. 《中国通史 2016》_12_读后感
  4. 购物网站商城系统,购物网站毕业设计,B2C网上购物系统毕业设计
  5. 盗将行——微信群防骗指南
  6. ERD图“乌鸦脚”形式表示的关系的使用方法与理解
  7. 2022 年终奖个税计算方法,看看你被多收割了多少
  8. 重磅上线!万兴科技旗下亿图图示12.0打造全新智能绘图体验
  9. sql 一张表递归_查看我的递归视觉指南(因为一张图片价值1,000字)
  10. POP3, SMTP, IMAP 和 Exchange 的区别