zoukankan      html  css  js  c++  java
  • 如何创建自定义的Resource实例

    由Resource的构造函数Resources(AssetManager assets, DisplayMetrics metrics, Configuration config)了解到,需要获取app外部apk文件资源的Resource对象,首先需要创建对应的AssetManager对象。

    public final class AssetManager implements AutoCloseable {
    /**
    * Create a new AssetManager containing only the basic system assets.
    * Applications will not generally use this method, instead retrieving the
    * appropriate asset manager with {@link Resources#getAssets}. Not for
    * use by applications.
    * {@hide}
    */
    public AssetManager() {
    synchronized (this) {
    if (DEBUG_REFS) {
    mNumRefs = 0;
    incRefsLocked(this.hashCode());
    }
    init(false);
    if (localLOGV) Log.v(TAG, "New asset manager: " + this);
    ensureSystemAssets();
    }
    }
    /**
    * Add an additional set of assets to the asset manager. This can be
    * either a directory or ZIP file. Not for use by applications. Returns
    * the cookie of the added asset, or 0 on failure.
    * {@hide}
    */
    //添加额外的asset路径
    public final int addAssetPath(String path) {
    synchronized (this) {
    int res = addAssetPathNative(path);
    if (mStringBlocks != null) {
    makeStringBlocks(mStringBlocks);
    }
    return res;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    所以通过反射可以创建对应的AssertManager,进而创建出对应的Resource实例,代码如下:

    private final static Resources loadTheme(String skinPackageName, Context context){
    String skinPackagePath = Environment.getExternalStorageDirectory() + "/" + skinPackageName;
    File file = new File(skinPackagePath);
    Resources skinResource = null;
    if (!file.exists()) {
    return skinResource;
    }
    try {
    //创建AssetManager实例
    AssetManager assetManager = AssetManager.class.newInstance();
    Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
    addAssetPath.invoke(assetManager, skinPackagePath);
    //构建皮肤资源Resource实例
    Resources superRes = context.getResources();
    skinResource = new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());

    } catch (Exception e) {
    skinResource = null;
    }
    return skinResource;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    2、如何知道当前属性值在所在Resource中的id
    在Resource的源码中,可以发现

    public class Resources {
    /**
    * 通过给的资源名称,类型和包名返回一个资源的标识id。
    * @param name 资源的描述名称
    * @param defType 资源的类型名称
    * @param defPackage 包名
    *
    * @return 返回资源id,0标识未找到该资源
    */
    public int getIdentifier(String name, String defType, String defPackage) {
    if (name == null) {
    throw new NullPointerException("name is null");
    }
    try {
    return Integer.parseInt(name);
    } catch (Exception e) {
    // Ignore
    }
    return mAssets.getResourceIdentifier(name, defType, defPackage);
    }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    也就是说在任意的apk文件中,只需要知道包名(manifest.xml中指定的包名,用于寻找资源和Java类)、资源类型名称、资源描述名称。
    比如:在包A中有一个defType为"color",name为color_red_1的属性,通过Resource#getIdentifier则可以获取包B中该名称的颜色资源。

    //将skina重View的背景色设置为com.example.skinb中所对应的颜色
    if (attrValue.startsWith("@") && attrName.contains("background")){
    int resId = Integer.parseInt(attrValue.substring(1));
    int originColor = mContext.getResources().getColor(resId);
    if (mResource == null){
    return originColor;
    }
    String resName = mContext.getResources(http://www.my516.com).getResourceEntryName(resId);
    int skinRealResId = mResource.getIdentifier(resName, "color", "com.example.skinb");
    int skinColor = 0;
    try{
    skinColor = mResource.getColor(skinRealResId);
    }catch (Exception e){
    Log.e(TAG, "", e);
    skinColor = originColor;
    }
    view.setBackgroundColor(skinColor);
    }
    --------------------- 

  • 相关阅读:
    第04章-面向切面的Spring
    第03章-高级装配
    第02章-装配Bean
    第01章-Spring之旅
    IntelliJ IDEA打可运行jar包时的错误
    序列化+fastjson和java各种数据对象相互转化
    TinkerPop中的遍历:图的遍历策略
    TinkerPop中的遍历:图的遍历中谓词、栅栏、范围和Lambda的说明
    asp.net动态网站repeater控件使用及分页操作介绍
    HTML入门标签汇总
  • 原文地址:https://www.cnblogs.com/ly570/p/11284697.html
Copyright © 2011-2022 走看看