場景:工具類(非 Activity/Service)需要彈 Toast,直接 Toast.makeText(context, ...) 卻報 NullPointerException: context is null。典型的 Context 傳遞缺失問題。
MainActivity → CameraUtil.takePhoto() → UploadUtil.upload(),若中間未層層透傳 Context,最後拿到的就是 null。// UploadUtil.java
public static void upload(Context context, File file, UploadCallback callback) {
// ... 上傳邏輯 ...
runOnUiThread(() -> Toast.makeText(context, "上傳成功", Toast.LENGTH_SHORT).show());
}
// 調用處
UploadUtil.upload(MainActivity.this, photoFile, callback);
// MyApp.java
public class MyApp extends Application {
private static Context sContext;
@Override public void onCreate() { super.onCreate(); sContext = this; }
public static Context getContext() { return sContext; }
}
// 工具類
Toast.makeText(MyApp.getContext(), "成功", Toast.LENGTH_SHORT).show();
⚠️ 注意:Application Context 無法佈局充氣、啟動 Activity、綁定 Service,但彈 Toast、訪問資源、啟動廣播完全可用。嚴禁持有 Activity Context 導致內存洩漏。
public class ContextHolder {
private static WeakReference<Context> sRef;
public static void init(Context ctx) { sRef = new WeakReference<>(ctx); }
public static Context get() { return sRef != null ? sRef.get() : null; }
}
// Application.onCreate() 調用 ContextHolder.init(this)
@NonNull Context context 參數,IDE 會強制提醒傳值。ApplicationContext,且在 Application 初始化時賦值。EventBus/LiveData/RxJava 解耦,避免層層透傳參數。記住:Context 是有生命周期的,工具類無生命周期,所以 Context 必須從外部傳入,不能內部創建或靜態持有 Activity 引用。