R.drawable.image1 是 int 常量,無法直接用字符串拼接 "image"+i 獲取。
| 方案 | 優點 | 缺點 |
|---|---|---|
| 反射獲取 R.drawable 字段 | 代碼少、無需改動資源命名 | 反射較慢、混淆後字段名變更失效 |
| 資源名數組映射 | 無反射、編譯期安全、支持混淆 | 需手動維護數組 |
getResources().getIdentifier() | API 簡單、支持動態包名 | 比反射更慢、不推薦高頻調用 |
// 1. 定義資源 ID 數組(編譯期常量,無反射)
private static final int[] IMG_RES = {
R.drawable.image1, R.drawable.image2, R.drawable.image3,
R.drawable.image4, R.drawable.image5 /*, ... */
};
private static final int[] IMG_VIEW_ID = {
R.id.imageView1, R.id.imageView2, R.id.imageView3,
R.id.imageView4, R.id.imageView5
};
// 2. 循環設置
for (int i = 0; i < IMG_RES.length; i++) {
ImageView iv = findViewById(IMG_VIEW_ID[i]);
if (iv != null) {
iv.setImageResource(IMG_RES[i]);
}
}
for (int i = 1; i <= 5; i++) {
try {
// 獲取 drawable 字段
Field drawableField = R.drawable.class.getField("image" + i);
int resId = drawableField.getInt(null); // static 字段傳 null
// 獲取 id 字段
Field idField = R.id.class.getField("imageView" + i);
int viewId = idField.getInt(null);
ImageView iv = findViewById(viewId);
if (iv != null) iv.setImageResource(resId);
} catch (Exception e) {
Log.w("IMG", "Resource not found for index " + i, e);
}
}
-keepclassmembers class **.R$* {
public static <fields>;
}
-keep class **.R$drawable { *; }
-keep class **.R$id { *; }
**能用數組映射絕不反射**。反射僅作為「資源名完全動態(如服務端下發)」的最後手段。數組映射編譯期檢查、運行期零開銷、混淆友好,是工程標準解法。