Sự khác biệt giữa getContext (), getApplicationContext (), getBaseContext () và điều này


565

Sự khác nhau giữa là gì getContext(), getApplicationContext(), getBaseContext(), và " this"?

Mặc dù đây là câu hỏi đơn giản nhưng tôi không thể hiểu được sự khác biệt cơ bản giữa chúng. Xin vui lòng cho một số ví dụ dễ dàng nếu có thể.


1
Có một bài viết xuất sắc trong câu trả lời đầu tiên: stackoverflow.com/questions/1026973/
Khăn

Câu trả lời:


528
  • View.getContext(): Trả về bối cảnh mà chế độ xem hiện đang chạy. Thường là Hoạt động hiện đang hoạt động.

  • Activity.getApplicationContext(): Trả về bối cảnh cho toàn bộ ứng dụng (quá trình tất cả các Hoạt động đang chạy bên trong). Sử dụng điều này thay cho bối cảnh Hoạt động hiện tại nếu bạn cần một bối cảnh gắn liền với vòng đời của toàn bộ ứng dụng, không chỉ Hoạt động hiện tại.

  • ContextWrapper.getBaseContext(): Nếu bạn cần quyền truy cập vào Bối cảnh từ trong một bối cảnh khác, bạn sử dụng ContextWrapper. Ngữ cảnh được đề cập từ bên trong ContextWrapper được truy cập thông qua getBaseContext ().


59
và "cái này" thì sao?
CooL i3oY

16
+ CooL i3oY tương tự với getContext
Mikey

13
thực sự tôi đang nhầm lẫn rằng sự định nghĩa đúng đắn của bối cảnh là gì ??
Ravi

11
"cái này" và getContext () đều giống nhau
KCRaju

43
thisgetContext()không phải lúc nào cũng giống nhau, ví dụ như trong lớp Activity, bạn có thể sử dụng thisActivitykế thừa từ Contextnhưng phương thức getContext()không có trong Activitylớp. @mikedroid @KCRaju
nandan

92

Hầu hết các câu trả lời đã bao gồm getContext()getApplicationContext()nhưng getBaseContext () hiếm khi được giải thích.

Phương pháp getBaseContext()chỉ liên quan khi bạn có a ContextWrapper. Android cung cấp một ContextWrapperlớp được tạo xung quanh một hiện có Contextbằng cách sử dụng:

ContextWrapper wrapper = new ContextWrapper(context);

Lợi ích của việc sử dụng a ContextWrapperlà nó cho phép bạn sửa đổi hành vi mà không thay đổi Bối cảnh gốc. Ví dụ: nếu bạn có một hoạt động được gọi myActivitythì có thể tạo một Viewchủ đề khác với myActivity:

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

ContextWrapperthực sự mạnh mẽ bởi vì nó cho phép bạn ghi đè lên hầu hết các chức năng được cung cấp bởi Contextbao gồm cả mã để truy cập tài nguyên (ví dụ openFileInput(), getString()), tương tác với các thành phần khác (ví dụ sendBroadcast(), registerReceiver()), yêu cầu quyền (ví dụ checkCallingOrSelfPermission()) và địa điểm giải quyết hệ thống tập tin (ví dụ getFilesDir()).ContextWrapperthực sự hữu ích để khắc phục các sự cố cụ thể của thiết bị / phiên bản hoặc áp dụng các tùy chỉnh một lần cho các thành phần như Chế độ xem yêu cầu bối cảnh.

Phương thức getBaseContext () có thể được sử dụng để truy cập vào Bối cảnh cơ sở cơ sở cơ sở mà các ContextWrapperkết thúc tốt đẹp. Bạn có thể cần phải truy cập vào “cơ sở” bối cảnh nếu bạn cần, ví dụ, kiểm tra xem đó là một Service, Activityhoặc 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");
    }
    ...
  }
}

Hoặc nếu bạn cần gọi phiên bản chưa được mở của phương thức của phương thức:

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

17
Tôi muốn nói, đây là câu trả lời quan trọng nhất sau khi được chấp nhận.
0leg

4
Tôi muốn nói rằng sự tồn tại của ContextWrappermột trong những quyết định tồi tệ nhất từng được đưa ra bởi các nhà phát triển của khung Android. Khi họ nhận ra rằng họ đã tạo ra cả một gia đình Thần, thay vì làm đúng và tái cấu trúc mã theo Trách nhiệm đơn lẻ, họ đã thêm một hack xấu xí cho phép thay đổi hành vi Bối cảnh bằng cách đào sâu cây thừa kế. Kỹ thuật phần mềm xấu ở mức xấu nhất của nó. Đối với chúng tôi, các nhà phát triển, IMHO không ai nên sử dụng getBaseContext()hoặc ContextWrapper. Nếu bạn làm thế - đó là một "mùi mã" rất lớn.
Vasiliy

Tôi muốn xem CustomToastmã hoàn chỉnh . THANKS Tiết))
Alston

39

getApplicationContext () - Trả về bối cảnh cho tất cả các hoạt động đang chạy trong ứng dụng.

getBaseContext () - Nếu bạn muốn truy cập Ngữ cảnh từ một ngữ cảnh khác trong ứng dụng, bạn có thể truy cập.

getContext () - Trả về chế độ xem ngữ cảnh chỉ hoạt động hiện tại đang chạy.


1
Vui lòng kết hợp chữ A và B vào định nghĩa của bạn về bối cảnh với bối cảnh, không rõ ràng trong bất kỳ câu trả lời nào về bối cảnh được truy cập.
Hy vọng hữu ích

29

Câu hỏi "Bối cảnh là gì" là một trong những câu hỏi khó nhất trong vũ trụ Android.

Bối cảnh xác định các phương thức truy cập tài nguyên hệ thống, truy xuất tài sản tĩnh của ứng dụng, kiểm tra quyền, thực hiện các thao tác UI và nhiều hơn nữa. Về bản chất, Contextlà một ví dụ về mô hình chống đối tượng God trong sản xuất.

Khi nói đến loại nào Contextchúng ta nên sử dụng, nó trở nên rất phức tạp bởi vì ngoại trừ là Đối tượng Thần, cây phân cấp của các Contextlớp con vi phạm Nguyên tắc thay thế Liskov một cách tàn nhẫn.

Bài đăng trên blog này cố gắng tóm tắt Contextkhả năng ứng dụng của các lớp trong các tình huống khác nhau.

Hãy để tôi sao chép bảng chính từ bài đăng đó cho đầy đủ:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | 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. Một ứng dụng CÓ THỂ bắt đầu một Hoạt động từ đây, nhưng nó yêu cầu một tác vụ mới được tạo. Điều này có thể phù hợp với các trường hợp sử dụng cụ thể, nhưng có thể tạo ra các hành vi ngăn xếp ngược không chuẩn trong ứng dụng của bạn và thường không được khuyến nghị hoặc coi là thực hành tốt.
  2. Điều này là hợp pháp, nhưng lạm phát sẽ được thực hiện với chủ đề mặc định cho hệ thống mà bạn đang chạy, không phải là những gì được xác định trong ứng dụng của bạn.
  3. Được phép nếu máy thu là null, được sử dụng để lấy giá trị hiện tại của truyền phát dính, trên Android 4.2 trở lên.

ảnh chụp màn hình


Bài đăng blog tuyệt vời mà bạn liên kết đến!
lejonl

28

Contextcung cấp thông tin về ActvityhoặcApplication các thành phần mới được tạo.

ContextCần liên quan đến các thành phần mới được tạo (cho dù bối cảnh ứng dụng hay bối cảnh hoạt động)

Activitylà một lớp con của Context, người ta có thể sử dụng thisđể có được bối cảnh của hoạt động đó


Đâu là lời giải thích của bạn về baseContext?
IgorGanapolsky

1

Từ tài liệu này

Tôi hiểu rằng bạn nên sử dụng:

Hãy thử sử dụng ứng dụng ngữ cảnh thay vì hoạt động theo ngữ cảnh


0

getApplicationContext ()

cái này được sử dụng cho cấp ứng dụng và tham khảo tất cả các hoạt động.

getContext () và getBaseContext ()

rất có thể giống nhau. những điều này chỉ được giới thiệu hoạt động hiện tại đang hoạt động.

điều này

được giới thiệu đối tượng lớp hiện tại luôn.


0

A Contextlà:

  • một lớp trừu tượng có triển khai được cung cấp bởi hệ thống Android.
  • Nó cho phép truy cập vào các tài nguyên và các lớp dành riêng cho ứng dụng, cũng như các cuộc gọi lên cho các hoạt động ở cấp ứng dụng như các hoạt động khởi chạy, phát sóng và nhận ý định, v.v.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.