android - context用法 - getContext(),getApplicationContext(),getBaseContext()和“this”之間的區別




this context (5)

getApplicationContext() - 返回在應用程序中運行的所有活動的上下文。

getBaseContext() - 如果要從應用程序中的其他上下文訪問您可以訪問的上下文。

getContext() - 僅返回當前正在運行的活動的上下文視圖。

getContext()getApplicationContext()getBaseContext()和“ this ”有什麼getBaseContext()

雖然這是一個簡單的問題,但我無法理解它們之間的基本區別。 請盡可能提供一些簡單的例子。


“背景是什麼”這個問題是Android世界中最困難的問題之一。

Context定義了訪問系統資源,檢索應用程序的靜態資產,檢查權限,執行UI操作等的方法。 實質上, Context是生產中上帝對象反模式的一個例子。

當涉及到我們應該使用哪種Context ,它變得非常複雜,因為除了作為上帝對象之外, Context子類的層次結構樹殘酷地違反了里斯科替換原則。

本博客文章試圖總結Context類在不同情況下的適用性。

讓我從該帖子復制主表以確保完整性:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | Application | Activity | Service | ContentProvider | BroadcastReceiver |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
| Show a Dialog              | NO          | YES      | NO      | NO              | NO                |
| Start an Activity          | NO¹         | YES      | NO¹     | NO¹             | NO¹               |
| Layout Inflation           | NO²         | YES      | NO²     | NO²             | NO²               |
| Start a Service            | YES         | YES      | YES     | YES             | YES               |
| Bind to a Service          | YES         | YES      | YES     | YES             | NO                |
| Send a Broadcast           | YES         | YES      | YES     | YES             | YES               |
| Register BroadcastReceiver | YES         | YES      | YES     | YES             | NO³               |
| Load Resource Values       | YES         | YES      | YES     | YES             | YES               |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
  1. 應用程序可以從這裡開始一個活動,但它需要創建一個新的任務。 這可能適合特定的用例,但可以在應用程序中創建非標準的後退堆棧行為,通常不被推薦或被認為是良好的做法。
  2. 這是合法的,但通貨膨脹將使用您正在運行的系統的默認主題完成,而不是您的應用程序中定義的內容。
  3. 如果接收器為空(在Android 4.2及更高版本上用於獲取粘性廣播的當前值),則允許使用。

- screenshot


getApplicationContext()

這用於應用程序級別並引用所有活動。

getContext()和getBaseContext()

很可能是相同的。這些僅僅是當前的活動。

這個

始終引用當前類對象。


大多數答案已經覆蓋了getContext()getApplicationContext()getBaseContext()很少被解釋。

方法getBaseContext()只有在有ContextWrapper 。 Android提供了一個ContextWrapper類,它使用以下命令在現有的Context創建:

ContextWrapper wrapper = new ContextWrapper(context);

使用ContextWrapper的好處是它可以讓你“在不改變原始上下文的情況下修改行為”。 例如,如果您有一個名為myActivity的活動,則可以使用與myActivity不同的主題創建一個View

ContextWrapper customTheme = new ContextWrapper(myActivity) {
  @Override
  public Resources.Theme getTheme() { 
    return someTheme;
  }
}
View myView = new MyView(customTheme);

ContextWrapper功能非常強大,因為它可以覆蓋Context提供的大部分函數,包括訪問資源的代碼(例如openFileInput()getString() ),與其他組件交互(例如sendBroadcast()registerReceiver() ),請求權限(例如checkCallingOrSelfPermission() )和解析文件系統位置(例如getFilesDir() )。 ContextWrapper對解決設備/特定版本問題或將一次性定制應用於需要上下文的組件(如視圖)非常有用。

方法getBaseContext()可用於訪問ContextWrapper包裝的“基本”上下文。 例如,您可能需要訪問“基本”上下文,例如,檢查它是ServiceActivity還是Application

public class CustomToast {
  public void makeText(Context context, int resId, int duration) {
    while (context instanceof ContextWrapper) {
      context = context.baseContext();
    }
    if (context instanceof Service)) {
      throw new RuntimeException("Cannot call this from a service");
    }
    ...
  }
}

或者,如果你需要調用一個方法的“unwrapped”版本:

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}

  • View.getContext() :返回視圖當前運行的上下文。通常是當前活動的Activity。

  • Activity.getApplicationContext() :返回整個應用程序的上下文(處理所有活動在裡面運行)。 如果您需要一個與整個應用程序的生命週期相關的上下文,而不僅僅是當前的活動,則使用它而不是當前的活動上下文。

  • ContextWrapper.getBaseContext() :如果需要從另一個上下文中訪問Context,則使用ContextWrapper。 從ContextWrapper引用的Context是通過getBaseContext()來訪問的。





android-context