首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 工具類彈 Toast 報 NullPointerException:Context 傳遞最佳實踐

     編輯:程式設計綜合問答

場景:工具類(非 Activity/Service)需要彈 Toast,直接 Toast.makeText(context, ...) 卻報 NullPointerException: context is null。典型的 Context 傳遞缺失問題。

為什麼會空?

  • 工具類無生命周期,不持有 Context。
  • 調用鏈:MainActivity → CameraUtil.takePhoto() → UploadUtil.upload(),若中間未層層透傳 Context,最後拿到的就是 null。

三種解決方案(按推薦度排序)

1. 方法參數強制傳遞(最清晰、無副作用)

// 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);

2. Application 級全局 Context(慎用,防洩漏)

// 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 導致內存洩漏。

3. 靜態持有弱引用(過渡方案)

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)

最佳實踐清單

  1. 優先方法參數傳遞,依賴顯式、可測試、無洩漏風險。
  2. 工具類標註 @NonNull Context context 參數,IDE 會強制提醒傳值。
  3. 若必須用全局 Context,只用 ApplicationContext,且在 Application 初始化時賦值。
  4. 長鏈路調用考慮用 EventBus/LiveData/RxJava 解耦,避免層層透傳參數。

記住:Context 是有生命周期的,工具類無生命周期,所以 Context 必須從外部傳入,不能內部創建或靜態持有 Activity 引用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved