frameworks/base/core/java/android/content/res/Resources.java    public CharSequence getText(int id) throws NotFoundException {        CharSequence res = mAssets.getResourceText(id);        if (res != null) {            return res;        }        throw new NotFoundException("String resource ID #0x"                                    + Integer.toHexString(id));    }frameworks/base/core/java/android/content/res/AssetManager.java    /*package*/ final CharSequence getResourceText(int ident) {        synchronized (this) {            TypedValue tmpValue = mValue;            int block = loadResourceValue(ident, (short) 0, tmpValue, true);//进这里看看            if (block >= 0) {                if (tmpValue.type == TypedValue.TYPE_STRING) {                    return mStringBlocks[block].get(tmpValue.data);                }                return tmpValue.coerceToString();            }        }        return null;    }frameworks/base/core/jni/android_util_AssetManager.cppstatic jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject clazz,                                                           jint ident,                                                           jshort density,                                                           jobject outValue,                                                           jboolean resolve){    AssetManager* am = assetManagerForJavaObject(env, clazz);    if (am == NULL) {        return 0;    }    const ResTable& res(am->getResources());    Res_value value;    ResTable_config config;    uint32_t typeSpecFlags;    ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config);在这里获取到了值#if THROW_ON_BAD_ID    if (block == BAD_INDEX) {        jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");        return 0;    }#endif    uint32_t ref = ident;    if (resolve) {        block = res.resolveReference(&value, block, &ref, &typeSpecFlags, &config);#if THROW_ON_BAD_ID        if (block == BAD_INDEX) {            jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");            return 0;        }#endif    }    return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config) : block;}frameworks/base/libs/androidfw/ResourceTypes.cppssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density,        uint32_t* outSpecFlags, ResTable_config* outConfig) const{    if (mError != NO_ERROR) {        return mError;    }    const ssize_t p = getResourcePackageIndex(resID);    const int t = Res_GETTYPE(resID);    const int e = Res_GETENTRY(resID);    if (p < 0) {        if (Res_GETPACKAGE(resID)+1 == 0) {            ALOGW("No package identifier when getting value for resource number 0x%08x", resID);        } else {            ALOGW("No known package when getting value for resource number 0x%08x", resID);        }        return BAD_INDEX;    }    if (t < 0) {        ALOGW("No type identifier when getting value for resource number 0x%08x", resID);        return BAD_INDEX;    }    const Res_value* bestValue = NULL;    const Package* bestPackage = NULL;    ResTable_config bestItem;    memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up    if (outSpecFlags != NULL) *outSpecFlags = 0;    // Look through all resource packages, starting with the most    // recently added.    const PackageGroup* const grp = mPackageGroups[p];    if (grp == NULL) {        ALOGW("Bad identifier when getting value for resource number 0x%08x", resID);        return BAD_INDEX;    }    // Allow overriding density    const ResTable_config* desiredConfig = &mParams;    ResTable_config* overrideConfig = NULL;    if (density > 0) {        overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config));        if (overrideConfig == NULL) {            ALOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno));            return BAD_INDEX;        }        memcpy(overrideConfig, &mParams, sizeof(ResTable_config));        overrideConfig->density = density;        desiredConfig = overrideConfig;    }else{overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config));        if (overrideConfig == NULL) {            ALOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno));            return BAD_INDEX;        }        memcpy(overrideConfig, &mParams, sizeof(ResTable_config));        overrideConfig->smallestScreenWidthDp = 720;        desiredConfig = overrideConfig;}//修改,作测试用.    ssize_t rc = BAD_VALUE;    size_t ip = grp->packages.size();    while (ip > 0) {        ip--;        int T = t;        int E = e;        const Package* const package = grp->packages[ip];        if (package->header->resourceIDMap) {            uint32_t overlayResID = 0x0;            status_t retval = idmapLookup(package->header->resourceIDMap,                                          package->header->resourceIDMapSize,                                          resID, &overlayResID);            if (retval == NO_ERROR && overlayResID != 0x0) {                // for this loop iteration, this is the type and entry we really want                ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);                T = Res_GETTYPE(overlayResID);                E = Res_GETENTRY(overlayResID);            } else {                // resource not present in overlay package, continue with the next package                continue;            }        }        const ResTable_type* type;        const ResTable_entry* entry;        const Type* typeClass;        ssize_t offset = getEntry(package, T, E, desiredConfig, &type, &entry, &typeClass);//最终会进入getEntry,里面作了很多对当前Config的比较处理。        if (offset <= 0) {            // No {entry, appropriate config} pair found in package. If this            // package is an overlay package (ip != 0), this simply means the            // overlay package did not specify a default.            // Non-overlay packages are still required to provide a default.            if (offset < 0 && ip == 0) {                ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n",                        resID, T, E, ip, (int)offset);                rc = offset;                goto out;            }            continue;        }        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) {            if (!mayBeBag) {                ALOGW("Requesting resource %p failed because it is complex\n",                     (void*)resID);            }            continue;        }        TABLE_NOISY(aout << "Resource type data: "              << HexDump(type, dtohl(type->header.size)) << endl);        if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) {            ALOGW("ResTable_item at %d is beyond type chunk data %d",                 (int)offset, dtohl(type->header.size));            rc = BAD_TYPE;            goto out;        }        const Res_value* item =            (const Res_value*)(((const uint8_t*)type) + offset);        ResTable_config thisConfig;        thisConfig.copyFromDtoH(type->config);        if (outSpecFlags != NULL) {            if (typeClass->typeSpecFlags != NULL) {                *outSpecFlags |= dtohl(typeClass->typeSpecFlags[E]);            } else {                *outSpecFlags = -1;            }        }        if (bestPackage != NULL &&            (bestItem.isMoreSpecificThan(thisConfig) || bestItem.diff(thisConfig) == 0)) {            // Discard thisConfig not only if bestItem is more specific, but also if the two configs            // are identical (diff == 0), or overlay packages will not take effect.            continue;        }                bestItem = thisConfig;        bestValue = item;        bestPackage = package;    }    TABLE_NOISY(printf("Found result: package %p\n", bestPackage));    if (bestValue) {        outValue->size = dtohs(bestValue->size);        outValue->res0 = bestValue->res0;        outValue->dataType = bestValue->dataType;        outValue->data = dtohl(bestValue->data);        if (outConfig != NULL) {            *outConfig = bestItem;        }        TABLE_NOISY(size_t len;              printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n",                     bestPackage->header->index,                     outValue->dataType,                     outValue->dataType == bestValue->TYPE_STRING                     ? String8(bestPackage->header->values.stringAt(                         outValue->data, &len)).string()                     : "",                     outValue->data));        rc = bestPackage->header->index;        goto out;    }out:    if (overrideConfig != NULL) {        free(overrideConfig);    }    return rc;}ssize_t ResTable::getEntry(    const Package* package, int typeIndex, int entryIndex,    const ResTable_config* config,    const ResTable_type** outType, const ResTable_entry** outEntry,    const Type** outTypeClass) const{    ALOGV("Getting entry from package %p\n", package);    const ResTable_package* const pkg = package->package;    const Type* allTypes = package->getType(typeIndex);    ALOGV("allTypes=%p\n", allTypes);    if (allTypes == NULL) {        ALOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);        return 0;    }    if ((size_t)entryIndex >= allTypes->entryCount) {        ALOGW("getEntry failing because entryIndex %d is beyond type entryCount %d",            entryIndex, (int)allTypes->entryCount);        return BAD_TYPE;    }            const ResTable_type* type = NULL;    uint32_t offset = ResTable_type::NO_ENTRY;    ResTable_config bestConfig;    memset(&bestConfig, 0, sizeof(bestConfig)); // make the compiler shut up        const size_t NT = allTypes->configs.size();    for (size_t i=0; i<NT; i++) {        const ResTable_type* const thisType = allTypes->configs[i];        if (thisType == NULL) continue;                ResTable_config thisConfig;        thisConfig.copyFromDtoH(thisType->config);        TABLE_GETENTRY(ALOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",                           entryIndex, typeIndex+1, dtohl(thisType->config.size),                           thisConfig.toString().string()));                // Check to make sure this one is valid for the current parameters.        if (config && !thisConfig.match(*config)) {            TABLE_GETENTRY(ALOGI("Does not match config!\n"));            continue;        }//重要                // Check if there is the desired entry in this type.                const uint8_t* const end = ((const uint8_t*)thisType)            + dtohl(thisType->header.size);        const uint32_t* const eindex = (const uint32_t*)            (((const uint8_t*)thisType) + dtohs(thisType->header.headerSize));                uint32_t thisOffset = dtohl(eindex[entryIndex]);        if (thisOffset == ResTable_type::NO_ENTRY) {            TABLE_GETENTRY(ALOGI("Skipping because it is not defined!\n"));            continue;        }                if (type != NULL) {            // Check if this one is less specific than the last found.  If so,            // we will skip it.  We check starting with things we most care            // about to those we least care about.            if (!thisConfig.isBetterThan(bestConfig, config)) {                TABLE_GETENTRY(ALOGI("This config is worse than last!\n"));                continue;            }        }                type = thisType;        offset = thisOffset;        bestConfig = thisConfig;        TABLE_GETENTRY(ALOGI("Best entry so far -- using it!\n"));        if (!config) break;    }        if (type == NULL) {        TABLE_GETENTRY(ALOGI("No value found for requested entry!\n"));        return BAD_INDEX;    }        offset += dtohl(type->entriesStart);    TABLE_NOISY(aout << "Looking in resource table " << package->header->header          << ", typeOff="          << (void*)(((const char*)type)-((const char*)package->header->header))          << ", offset=" << (void*)offset << endl);    if (offset > (dtohl(type->header.size)-sizeof(ResTable_entry))) {        ALOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x",             offset, dtohl(type->header.size));        return BAD_TYPE;    }    if ((offset&0x3) != 0) {        ALOGW("ResTable_entry at 0x%x is not on an integer boundary",             offset);        return BAD_TYPE;    }    const ResTable_entry* const entry = (const ResTable_entry*)        (((const uint8_t*)type) + offset);    if (dtohs(entry->size) < sizeof(*entry)) {        ALOGW("ResTable_entry size 0x%x is too small", dtohs(entry->size));        return BAD_TYPE;    }    *outType = type;    *outEntry = entry;    if (outTypeClass != NULL) {        *outTypeClass = allTypes;    }    return offset + dtohs(entry->size);}

更多相关文章

  1. 2011.10.11——— android GestureDetector 测试OnGestureListen
  2. Android测试教程(2):测试基础
  3. Android 测试工具集01
  4. Android单元测试 Instrumentation
  5. Android自动化测试之环境搭建(二)
  6. android测试

随机推荐

  1. Android 开发环境的搭建 个人笔记
  2. 4412开发板Android和LinuxQT烧写方法
  3. Fedora17 64位 android "failed to creat
  4. 朝花夕拾----新组件的学习和使用
  5. 【ALearning】第二章 Android工程相关知
  6. android.intent.action.MAIN 与 android.
  7. Android在线热更新hot fix - AndFix试用
  8. Android数字签名获取证书指纹(SHA1)
  9. android studio常用的快捷键
  10. 【android】 监听去电和来电电话状态