AssetManager2::GetResource()
AssetManager2::FindEntry
AssetManager2::FindEntryInternal
/**
* Representation of a value in a resource, supplying type
* information.
*/
struct Res_value
{
// Number of bytes in this structure.
uint16_t size;
// Always set to 0.
uint8_t res0;
uint8_t dataType;
// The data for this item, as interpreted according to dataType.
typedef uint32_t data_type;
data_type data;
}
for String , Res_value#data is the String index in String pool .
In: ResourceValues.cpp
bool String::Flatten(android::Res_value* out_value) const {
// Verify that our StringPool index is within encode-able limits.
if (value.index() > std::numeric_limits<uint32_t>::max()) {
return false;
}
out_value->dataType = android::Res_value::TYPE_STRING;
out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
LOG(WARNING)<<"String::Flatten, out_value->data: "<<out_value->data;
LOG(WARNING)<<"String::Flatten, out_value->dataType: TYPE_STRING:"<<static_cast<uint32_t>(out_value->dataType);
return true;
}
for any other type , Res_value#data is the actual data .
In ResourceValues.cpp:
bool BinaryPrimitive::Flatten(::android::Res_value* out_value) const {
LOG(WARNING)<<"BinaryPrimitive::Flatten:";
out_value->dataType = value.dataType;
out_value->data = util::HostToDevice32(value.data);
return true;
}
do the load:
std::unique_ptr<LoadedArsc> LoadedArsc::Load(incfs::map_ptr<void> data,
const size_t length,
const LoadedIdmap* loaded_idmap,
const package_property_t property_flags) {
ATRACE_NAME("LoadedArsc::Load");
// Not using make_unique because the constructor is private.
std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc());
ChunkIterator iter(data, length);
while (iter.HasNext()) {
const Chunk chunk = iter.Next();
switch (chunk.type()) {
case RES_TABLE_TYPE:
if (!loaded_arsc->LoadTable(chunk, loaded_idmap, property_flags)) {
return {};
}
break;
default:
LOG(WARNING) << StringPrintf("Unknown chunk type '%02x'.", chunk.type());
break;
}
}
if (iter.HadError()) {
LOG(ERROR) << iter.GetLastError();
if (iter.HadFatalError()) {
return {};
}
}
return loaded_arsc;
}
Memory Layout :
ResChunk_header | data | ResChunk_header | data | ResChunk_header | data | …
ResChunk_header
/**
* Header that appears at the front of every data chunk in a resource.
*/
struct ResChunk_header
{
// Type identifier for this chunk. The meaning of this value depends
// on the containing chunk.
uint16_t type;
// Size of the chunk header (in bytes). Adding this value to
// the address of the chunk allows you to find its associated data
// (if any).
uint16_t headerSize;
// Total size of this chunk (in bytes). This is the chunkSize plus
// the size of any data associated with the chunk. Adding this value
// to the chunk allows you to completely skip its contents (including
// any child chunks). If this value is the same as chunkSize, there is
// no data associated with the chunk.
uint32_t size;
};
AssetManager.createSystemAssetsInZygoteLocked
ZygoteInit.preloadClasses()
Who use ResChunk_header?
ResStringPool_header
ResTable_header
ResTable_package
ResTable_typeSpec
ResTable_type