publicclass Main { publicstaticvoid main(String[] args) throws Exception {
System.loadLibrary(args[0]);
// Feature only enabled for target SDK version Q and later.
setTargetSdkVersion(/* Q */ 29);
if (isDebuggable()) { // Background verification is disabled in debuggable mode. This test makes // no sense then. return;
}
if (!hasOatFile()) { // We only generate vdex files if the oat directories are created. return;
}
setProcessDataDir(DEX_LOCATION);
finalint maxCacheSize = getVdexCacheSize(); finalint numDexFiles = DEX_BYTES_CHECKSUMS.length; if (numDexFiles <= maxCacheSize) { thrownew IllegalStateException("Not enough dex files to test cache eviction");
}
// Simply load each dex file one by one.
check(0, getCurrentCacheSize(), "There should be no vdex files in the beginning"); for (int i = 0; i < numDexFiles; ++i) {
ClassLoader loader = loadDex(i);
waitForVerifier();
check(true, hasVdexFile(loader), "Loading dex file should have produced a vdex");
check(Math.min(i + 1, maxCacheSize), getCurrentCacheSize(), "Unexpected number of cache entries");
}
// More complicated pattern where some dex files get reused. for (int s = 1; s < numDexFiles; ++s) { for (int i = 0; i < maxCacheSize; ++i) {
ClassLoader loader = loadDex(i);
waitForVerifier();
check(true, hasVdexFile(loader), "Loading dex file should have produced a vdex");
check(maxCacheSize, getCurrentCacheSize(), "Unexpected number of cache entries");
}
}
}
privatestaticint getCurrentCacheSize() { int count = 0;
File folder = new File(DEX_LOCATION, "oat");
File[] subfolders = folder.listFiles(); if (subfolders.length != 1) { thrownew IllegalStateException("Expect only one subfolder - isa");
}
folder = subfolders[0]; for (File f : folder.listFiles()) { if (f.isFile() && isAnonymousVdexBasename(f.getName())) {
count++;
}
} return count;
}
privatestaticbyte[] createDex(int index) { if (index >= 100) { thrownew IllegalArgumentException("Not more than two decimals");
}
// Clone the base dex file. This is the dex file for index 0 (class ID "01"). byte[] dex = DEX_BYTES_BASE.clone();
// Overwrite the checksum and sha1 signature.
System.arraycopy(DEX_BYTES_CHECKSUMS[index], 0, dex, DEX_BYTES_CHECKSUM_OFFSET,
DEX_BYTES_CHECKSUM_SIZE);
// Check that the class ID offsets match expectations - they should contains "01". if (dex[DEX_BYTES_CLASS_ID_OFFSET1 + 0] != 0x30 ||
dex[DEX_BYTES_CLASS_ID_OFFSET1 + 1] != 0x31 ||
dex[DEX_BYTES_CLASS_ID_OFFSET2 + 0] != 0x30 ||
dex[DEX_BYTES_CLASS_ID_OFFSET2 + 1] != 0x31) { thrownew IllegalStateException("Wrong class name values");
}
// Checksum/SHA1 signature diff for classes MyClass01 - MyClassXX. // This is just a convenient way of storing many similar dex files. privatestaticfinalbyte[][] DEX_BYTES_CHECKSUMS = newbyte[][] {
Base64.getDecoder().decode("R1Yw40PVkNk0ns2dHsRR9NIb5Sa3p6rz"),
Base64.getDecoder().decode("i1V1U3C8nexVk4uw185lXZd9kzd82iaA"),
Base64.getDecoder().decode("tFPbVPdpzuoDWqH71Ak5HpltBHg0frMU"),
Base64.getDecoder().decode("eFSc7dENiK8nxviKBmd/O2s7h/NAj+l/"),
Base64.getDecoder().decode("DlUfNQ3cuVrCHRyw/cOFhqEe+0r6wlUP"),
Base64.getDecoder().decode("KVaBmdG8Y8kx8ltEPXWyi9OCdL14yeiW"),
Base64.getDecoder().decode("K1bioDTHtPwmrPXkvZ0XYCiripH6KsC2"),
Base64.getDecoder().decode("oVHctdpHG3YTNeQlVCshTkFKVra9TG4k"),
Base64.getDecoder().decode("eVWMFHRY+w4lpn9Uo9jn+eNAmaRK4HEw"),
Base64.getDecoder().decode("/lW3Q3U4ot5A2qkhiv4Aj+s8zv7984MA"),
Base64.getDecoder().decode("BFRB+4HwRbuD164DB3sVy28dc+Ea5YVQ"),
Base64.getDecoder().decode("klQBLEXyr0cviHDHlqFyWPGKaQQnqMiD"),
Base64.getDecoder().decode("jlTcJAkpnbDI/E4msuvMyWqKxNMTN0YU"),
Base64.getDecoder().decode("vlUOrp4aN0PxcaqQrQmm597P+Ymu5Adt"),
Base64.getDecoder().decode("HlXyT1GoJk1m33O8OMaYxqy3K1Byyf1S"),
Base64.getDecoder().decode("d1O5toIKjTXNZkgP3p9RiiafhuKw4gUH"),
Base64.getDecoder().decode("11RsuG9UrFHPipOj9zjuGU9obctMJbq6"),
Base64.getDecoder().decode("dlSW5egObqheoHSRthlR2c2jVKLGQ3QL"),
Base64.getDecoder().decode("ulMgQEhC0XMhmKxHtgdURY6B6JEqNb3E"),
Base64.getDecoder().decode("YFV08vrcs49xYr1OBhrza5H8Ha86FODz"),
Base64.getDecoder().decode("jFKPxTFd3kn6K0p6n8YEPgm0hiozXW1p"),
Base64.getDecoder().decode("LlUZdlCXwAn4qksYL6Urw+bZC/fYuJ1T"),
Base64.getDecoder().decode("K1SuRt9xZX5lAVtbpMauOWLVXs2KooUA"),
Base64.getDecoder().decode("2FJAWIk0JS9EdvkgHjquLL9qdcLeHaRJ"),
Base64.getDecoder().decode("YVResABr9IvZLV8eeIhM3TXfGC+Y6/x1"),
Base64.getDecoder().decode("UVTrkVGIh8u7FBHgcbS9flI0CY5g2E3m"),
Base64.getDecoder().decode("oVIu6RsrT6HgnbPzNGiYZSpKS0cqNi+a"),
Base64.getDecoder().decode("2FR/slWq9YC6kJRDEw21RVGmJhr3/uKZ"),
Base64.getDecoder().decode("CFbaSi70ZVaumL7zsXWlD/ernHxCZPx6"),
Base64.getDecoder().decode("7FTY+T1/qevWQM6Yoe+OwNcUdgcCUomJ"),
};
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.10Bemerkung:
(vorverarbeitet am 2026-09-27)
¤