Android 使用 Universal ImageLoader (UIL) 時,配置代碼寫在自定義 Application 子類中,但清單文件未聲明該類,導致 onCreate() 不被調用,初始化失敗,運行時拋出「未配置」異常。
public class GlobalApplication extends Application {
public static ImageLoader imageLoader = ImageLoader.getInstance();
@Override
public void onCreate() {
super.onCreate();
initImageLoader(getApplicationContext()); // 此處配置 UIL
// ... 省略 options 構建
}
// ... initImageLoader 方法
}
// Fragment 中使用
GlobalApplication.imageLoader.displayImage(url, imageView, GlobalApplication.options);
報錯:IllegalStateException: ImageLoader must be init with configuration before using
AndroidManifest.xml 中 <application> 標籤缺少 android:name=".GlobalApplication",系統創建默認 Application 實例,自定義類 onCreate() 從未執行,UIL 未初始化。
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.app">
<application
android:name=".GlobalApplication" <!-- 關鍵:指定自定義 Application 類 -->
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<!-- Activities, Services... -->
</application>
</manifest>
UIL 初始化應在主進程執行,避免 :push/:remote 進程重複初始化:
@Override
public void onCreate() {
super.onCreate();
// 僅主進程初始化 UIL
if (getApplicationInfo().packageName.equals(getProcessName())) {
initImageLoader(this);
}
}
private String getProcessName() {
int pid = android.os.Process.myPid();
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo info : am.getRunningAppProcesses()) {
if (info.pid == pid) return info.processName;
}
return "";
}
private void initImageLoader(Context context) {
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.threadPoolSize(3) // 線程池大小
.threadPriority(Thread.NORM_PRIORITY - 1)
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new LruMemoryCache(2 * 1024 * 1024)) // 2MB 內存緩存,推薦 Lru
.memoryCacheSize(2 * 1024 * 1024)
.diskCacheSize(50 * 1024 * 1024) // 50MB 磁盤緩存
.diskCacheFileCount(100)
.diskCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)
.writeDebugLogs() // 僅 Debug 模式開啟
.build();
ImageLoader.getInstance().init(config);
}
| 問題 | 癥狀 | 解決 |
|---|---|---|
| Manifest 未聲明 Application 子類 | onCreate 不執行、單例未初始化 | 添加 android:name=".YourApplication" |
| 多進程重複初始化 | 緩存衝突、日志刷屏 | 主進程判斷守護 |
| 磁盤緩存路徑無權限 | 緩存寫入失敗、圖片不顯示 | getCacheDir()/getExternalCacheDir() |
| 網絡圖片 URL 為空/異常 | displayImage 靜默失敗 | 調用前非空判斷、添加佔位圖 |
| 使用舊版 UIL (1.9.0 前) | API 差異大、Bug 多 | 升級至 1.9.5+ 或遷移至 Glide/Picasso/Coil |
UIL 官方已停止維護(最後更新 2016 年)。新項目建議:
// Glide 使用示例
Glide.with(fragment)
.load(url)
.placeholder(R.drawable.ic_launcher)
.error(R.drawable.ic_launcher)
.into(imageView);
UIL 報「未配置」90% 是 Manifest 未註冊自定義 Application 類。檢查 android:name 屬性,確保 onCreate() 執行初始化。長期項目建議遷移至 Glide/Coil,獲得更好維護性與性能。