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

  • 相关阅读:
    FZU 2150 Fire Game
    POJ 3414 Pots
    POJ 3087 Shuffle'm Up
    POJ 3126 Prime Path
    POJ 1426 Find The Multiple
    POJ 3278 Catch That Cow
    字符数组
    HDU 1238 Substing
    欧几里德和扩展欧几里德详解 以及例题CodeForces 7C
    Codeforces 591B Rebranding
  • 原文地址:https://www.cnblogs.com/ly570/p/11284697.html
Copyright © 2011-2022 走看看