Sự khác biệt giữa Bối cảnh hoạt động và Bối cảnh ứng dụng


233

Điều này làm tôi bối rối, tôi đã sử dụng điều này trong SDK Android 2.1-r8:

ProgressDialog.show(getApplicationContext(), ....);

và cũng trong

Toast t = Toast.makeText(getApplicationContext(),....);

sử dụng getApplicationContext()sự cố cả hai ProgressDialogToast.... dẫn tôi đến câu hỏi này:

Sự khác biệt thực tế giữa bối cảnh hoạt động và bối cảnh ứng dụng, mặc dù chia sẻ từ ngữ 'Bối cảnh' là gì?


Đây là những gì tôi đã tìm thấy stackoverflow.com/questions/1561804/ trên ....
t0mm13b

14
Điều này sẽ giúp làm rõ một số điều: Bối cảnh, Bối cảnh gì?
toobsco42

Câu trả lời:


250

Cả hai đều là các phiên bản của Ngữ cảnh , nhưng phiên bản ứng dụng được gắn với vòng đời của ứng dụng, trong khi đối tượng Activity được gắn với vòng đời của một Hoạt động. Vì vậy, họ có quyền truy cập vào thông tin khác nhau về môi trường ứng dụng.

Nếu bạn đọc các tài liệu tại getApplicationContext, nó lưu ý rằng bạn chỉ nên sử dụng tài liệu này nếu bạn cần một bối cảnh có vòng đời tách biệt với bối cảnh hiện tại. Điều này không áp dụng trong một trong các ví dụ của bạn.

Bối cảnh Hoạt động có lẽ có một số thông tin về hoạt động hiện tại cần thiết để hoàn thành các cuộc gọi đó. Nếu bạn hiển thị thông báo lỗi chính xác, có thể chỉ ra chính xác những gì nó cần.

Nhưng nói chung, sử dụng bối cảnh hoạt động trừ khi bạn có lý do chính đáng để không.


1
Tôi đã nhận được 'java.lang.reflect.InvocationTargetException' khi sử dụng getApplicationContext, thật thú vị, khi tôi đổi sang this, nó không gặp sự cố và hoạt động như mong đợi .... vì vậy nếu cả hai đều là phiên bản của Ngữ cảnh, tại sao một cái không hoạt động và cái kia không? Thông tin này sẽ giúp ích cho những người khác Tôi hy vọng ... :) cảm ơn vì câu trả lời nhanh chóng của bạn ...
t0mm13b

2
Tôi cần xem stacktrace ngoại lệ đầy đủ để có thể nói bất cứ điều gì. Tuy nhiên, như tôi đã nói các trường hợp bối cảnh có thông tin khác nhau. Có lẽ để hiển thị hộp thoại hoặc bánh mì nướng trên màn hình yêu cầu thông tin về Hoạt động mà chỉ có đối tượng Hoạt động mới có.
Cheryl Simon

73
Tôi sẽ nói sử dụng bối cảnh ứng dụng trừ khi bạn không có lý do chính đáng (ví dụ như đối với hộp thoại hoặc bánh mì nướng). Thật dễ dàng để chạy vào rò rỉ bộ nhớ bằng cách sử dụng bối cảnh hoạt động trong các tình huống khác nhau để an toàn nhất :) android-developers.blogspot.com/2009/01/ Kẻ
Dori

10
Dave Smith đã đăng một mục blog rất tốt để hiểu cách sử dụng bối cảnh, xem tại đây . Hãy chắc chắn rằng bạn cũng đọc các bình luận!
ChrLipp

1
Vấn đề là, ngay cả Dianna Hackborn cũng khuyên bạn nên sử dụng bối cảnh hoạt động. stackoverflow.com/questions/5228160/ Mạnh Nhưng dường như bản thân cô không hoàn toàn chắc chắn về điều này.
JacksOnF1re 18/03/2015

177

Tôi thấy bảng này siêu hữu ích để quyết định khi nào nên sử dụng các loại bối cảnh khác nhau:

nhập mô tả hình ảnh ở đây

  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.

Bài viết gốc tại đây .



Còn việc lấy tài nguyên thì sao? Tôi nghĩ bạn tốt hơn nên thêm nó vào bảng của bạn. và bạn có thể truy cập tài nguyên với bối cảnh vỗ tay.
Amir Ziarati

Chúng ta có thể bắt đầu hoạt động từ Bối cảnh ứng dụng
Duy Phan

Bài viết cũng có thể được tìm thấy ở đây: wundermanthndrymobile.com/2013/06/context
Cuộc sống

34

Đây rõ ràng là sự thiếu hụt của thiết kế API. Ở vị trí đầu tiên, bối cảnh hoạt động và bối cảnh ứng dụng là các đối tượng hoàn toàn khác nhau, vì vậy các tham số phương thức nơi bối cảnh được sử dụng nên sử dụng ApplicationContexthoặc Activitytrực tiếp, thay vì sử dụng bối cảnh lớp cha. Ở vị trí thứ hai, tài liệu nên chỉ định bối cảnh sẽ sử dụng hoặc không rõ ràng.


25
Hoàn toàn đồng ý. Google thả quả bóng vào cái này. Đó là một mớ hỗn độn.
Søren Boisen

@ SørenBoisen android sdk là một mớ hỗn độn
CommonSenseCode

Họ nhận thức được sự lộn xộn, và chắc chắn rằng họ đang cố gắng hết sức để sửa chữa nhiều nhất có thể.
ký hiệu

15

Lý do tôi nghĩ là ProgressDialoggắn liền với hoạt động hỗ trợ cho ProgressDialoghộp thoại vì hộp thoại không thể duy trì sau khi hoạt động bị hủy nên cần phải được thông qua this(ActivityContext) cũng bị hủy cùng với hoạt động trong khi ApplicationContext vẫn còn ngay cả sau khi hoạt động được bị phá hủy.


3

Sử dụng getApplicationContext () nếu bạn cần một cái gì đó gắn liền với một bối cảnh mà chính nó sẽ có phạm vi toàn cầu.

Nếu bạn sử dụng Activity, thì đối tượng Activity mới sẽ có một tham chiếu, trong đó có một tham chiếu ngầm cho Activity cũ và Activity cũ không thể được thu gom rác.


2

Tôi nghĩ rằng khi mọi thứ cần một màn hình để hiển thị (nút, hộp thoại, bố cục ...) chúng ta phải sử dụng hoạt động theo ngữ cảnh và mọi thứ không cần màn hình để hiển thị hoặc xử lý (bánh mì nướng, điện thoại dịch vụ, liên hệ ...) chúng tôi có thể sử dụng bối cảnh ứng dụng


1

Bạn có thể thấy sự khác biệt giữa hai bối cảnh khi bạn khởi chạy ứng dụng của mình trực tiếp từ màn hình chính so với khi ứng dụng của bạn được khởi chạy từ một ứng dụng khác thông qua mục đích chia sẻ.

Dưới đây là một ví dụ thực tế về "hành vi ngăn xếp ngược không chuẩn", được đề cập bởi @CommonSenseCode, có nghĩa là:

Giả sử rằng bạn có hai ứng dụng giao tiếp với nhau, App1App2 .

Khởi chạy App2: MainActivity từ launcher. Sau đó, từ MainActivity khởi chạy App2: juniorActivity . Ở đó, sử dụng bối cảnh hoạt động hoặc bối cảnh ứng dụng, cả hai hoạt động đều sống trong cùng một nhiệm vụ và điều này đều ổn (với điều kiện bạn sử dụng tất cả các chế độ khởi chạy tiêu chuẩn và cờ mục đích). Bạn có thể quay lại MainActivity bằng cách nhấn lại và trong các ứng dụng gần đây, bạn chỉ có một nhiệm vụ.

Giả sử bây giờ bạn đang ở trong App1 và khởi chạy App2: MainActivity với mục đích chia sẻ (ACTION_SEND hoặc ACTION_SEND_MULTIPLE). Sau đó, từ đó cố gắng khởi chạy App2: juniorActivity (luôn có tất cả các chế độ khởi chạy tiêu chuẩn và cờ mục đích). Nhũng gì xảy ra là:

  • nếu bạn khởi chạy App2: Thứ cấp với ngữ cảnh ứng dụng trên Android <10, bạn không thể khởi chạy tất cả các hoạt động trong cùng một tác vụ . Tôi đã thử với Android 7 và 8 và Chương trình phụ luôn được khởi chạy trong một tác vụ mới (tôi đoán là vì App2: Thứ cấp được khởi chạy với bối cảnh ứng dụng App2 nhưng bạn đến từ App1 và bạn không khởi chạy ứng dụng App2 trực tiếp Android có thể nhận ra điều đó và sử dụng FLAG_ACTIVITY_NEW_TASK). Điều này có thể tốt hoặc xấu tùy theo nhu cầu của bạn, vì ứng dụng của tôi rất tệ.
    Trên Android 10, ứng dụng gặp sự cố với thông báo
    "Gọi startActivity () từ bên ngoài ngữ cảnh Hoạt động yêu cầu cờ FLAG_ACTIVITY_NEW_TASK. Đây có thực sự là điều bạn muốn không?" .
    Vì vậy, để làm cho nó hoạt động trên Android 10, bạn phải sử dụng FALG_ACTIVITY_NEW_TASK và bạn không thể chạy tất cả các hoạt động trong cùng một tác vụ.
    Như bạn có thể thấy hành vi khác nhau giữa các phiên bản Android, kỳ lạ.

  • nếu bạn khởi chạy App2: JuniorActivity với bối cảnh hoạt động thì mọi thứ đều ổn và bạn có thể chạy tất cả các hoạt động trong cùng một tác vụ dẫn đến điều hướng backstack tuyến tính.

Tôi hy vọng tôi đã thêm một số thông tin hữu ích

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.