2010-10-16 34 views
14

Trong ứng dụng Android của tôi, tôi quá tải lớp Ứng dụng và tôi đã cập nhật thẻ trong tệp kê khai của mình. Ứng dụng này cũng tạo ra một dịch vụ Android. Tôi đã đặt một số nhật ký trong onCreate của lớp Ứng dụng của tôi và tôi thấy nó được gọi hai lần. Lần đầu tiên là khi ứng dụng của tôi được khởi chạy (điều này được mong đợi) và sau đó, thường là ngay sau khi Dịch vụ được tạo. nhật ký cũng cho thấy rằng một ví dụ thứ hai của Ứng dụng đang được tạo. (Tôi in giá trị "này" và chúng khác nhau).Lớp Ứng dụng Android được gọi hai lần

Tôi nghĩ rằng Ứng dụng sẽ được tạo dưới dạng singleton. Điều đó có xảy ra vì tôi tạo một Dịch vụ không?

Trả lời

1

Vấn đề là một Dịch vụ cũng là một thành phần, với vòng đời của riêng nó, chỉ cần nó không có giao diện người dùng. Bạn nên kiểm tra các developer application fundamental s để biết các lựa chọn thay thế.

+0

có vẻ như vấn đề có thể liên quan đến thực tế là tôi đã khai báo Dịch vụ của mình trong Tệp kê khai bằng cách sử dụng thẻ android: process. nó có hợp lý không? –

+0

Có. Tôi vừa kiểm tra cùng một nguồn thông tin và đó cũng là điều tôi hiểu. Tôi đã không kiểm tra mặc dù. –

+0

nguồn thông tin của bạn là gì? Tôi tò mò muốn biết cách xử lý vụ này. điều này không phải là hiếm khi có một Dịch vụ tạo ra quy trình riêng của mình và lớp Ứng dụng được cho là một "singleton", nơi các đối tượng chung có thể được chia sẻ. –

3

Dịch vụ không được thực sự được coi là Hoạt động và bạn sẽ gặp phải sự cố sau này nếu bạn nghĩ theo cách này. Các Dịch vụ và Hoạt động có thể thuộc cùng một ứng dụng, nếu bạn định nghĩa chúng theo cách của bạn trong số AndroidManifest.xml, nhưng chúng hoạt động khác và có vòng đời khác nhau. Nếu bạn muốn Dịch vụ của mình theo một quy trình khác, thì bạn đặt android:process="string" trong mục <service> để đặt tên cho nó khác với tên ứng dụng của bạn. Bạn sẽ không có quyền truy cập vào các biến toàn cầu khi nó ở trong một quy trình riêng biệt và bạn nên liên lạc với dịch vụ của mình thông qua Intents. Nếu dịch vụ của bạn phức tạp hơn, bạn có thể muốn xem nó làm cho nó có thể gọi từ xa thông qua AIDL. Nếu bạn muốn hoạt động đơn lẻ, hãy đặt launchMode hoạt động của mình thành singleInstance hoặc singleTask. singleInstance có nghĩa là nó sẽ là trường hợp đầu tiên và duy nhất của Hoạt động này trong ngăn xếp nhiệm vụ của nó và sẽ không có phiên bản mới nào được tạo cho bất kỳ Mục đích mới nào. Vì đó là trường hợp duy nhất của Hoạt động này, nó sẽ luôn ở trên cùng của ngăn xếp nhiệm vụ và luôn ở vị trí để xử lý các Mục đích mới hướng vào Hoạt động này. Nếu Activity được khai báo là singleTask, nó cũng sẽ là một singleton nhưng có thể có các Hoạt động khác trong cùng một ngăn tác vụ và thậm chí có thể có Hoạt động ở trên cùng của ngăn tác vụ phía trên nó. Đây là một sự khác biệt quan trọng cần lưu ý. Hãy nhớ điều này: hoạt động singleton là NOT ở đầu ngăn tác vụ không thể xử lý Mục đích mới và Mục đích sẽ bị xóa. Nếu bạn muốn Hoạt động của mình luôn có thể xử lý tất cả các Mục đích mới được đặt trước, thì bạn có thể muốn sử dụng singleInstance

+0

không làm lẫn lộn ngăn xếp nhiệm vụ với nội dung hiển thị trên màn hình. Tôi chỉ muốn làm rõ điều đó ở đây. Ở trên cùng của ngăn tác vụ không có nghĩa là nó hiển thị trên màn hình. Vì vậy, một hoạt động đơn lẻ đó là hoạt động duy nhất trong ngăn xếp nhiệm vụ của nó, có thể là nền phía sau một hoạt động khác (trong một nhiệm vụ khác) vẫn có thể xử lý Intent (và làm như vậy, sẽ đến tiền cảnh) –

26

Có, nếu bạn đã sử dụng android: process thì bạn có nó chạy trong một quá trình riêng biệt, vì vậy khi dịch vụ bắt đầu một quá trình mới được bắt đầu cho nó và do đó một đối tượng Application mới cho quá trình đó cần phải được tạo ra.

Nhưng có một vấn đề cơ bản hơn - nó chỉ là không đúng cho một đối tượng ứng dụng để bắt đầu một trong các dịch vụ của nó. Điều quan trọng là bạn không nhầm lẫn ứng dụng với cách bạn có thể nghĩ về một "ứng dụng" trong một hệ điều hành khác. Đối tượng Application không điều khiển ứng dụng. Nó chỉ là một trạng thái toàn cầu cho ứng dụng trong quá trình đó. Thực tế, đối tượng Application hoàn toàn không cần thiết - bạn không bao giờ cần một ứng dụng để viết một ứng dụng Android. Nói chung tôi thực sự khuyên mọi người không nên sử dụng nó. Nó có nhiều khả năng gây rắc rối hơn bất cứ điều gì khác.

Một cách khác để đặt điều này: những gì thực sự xác định một ứng dụng là tập hợp các hoạt động, dịch vụ, người nhận và thẻ nhà cung cấp. Đó là những gì được "tung ra". Tất cả một ứng dụng là một thứ được tạo ra như là một phần của quá trình khởi tạo một ứng dụng. Nó không có vòng đời của riêng nó, nó chỉ ở đó để phục vụ các thành phần thực sự khác trong ứng dụng.

Vì vậy, chỉ cần bỏ qua Ứng dụng khi thiết kế ứng dụng của bạn; nó sẽ làm giảm sự nhầm lẫn. (Ở vị trí của nó, tôi thích sử dụng toàn cầu đơn cho tiểu bang đó.)

Cũng như một quy tắc chung, tôi khuyên bạn không nên sử dụng android: process. Chắc chắn có một số sử dụng cho nó, nhưng phần lớn thời gian nó không cần thiết và chỉ làm cho một ứng dụng sử dụng nhiều RAM, ít hiệu quả hơn và khó viết hơn (vì bạn không thể tận dụng lợi thế của các hình cầu trong một quá trình) . Nó sẽ được rõ ràng cho bạn nếu bạn đạt đến một nơi mà có thực sự là một lý do tốt để sử dụng android: quá trình.

+1

+1 nhiều thông tin. –

+0

+1, mặc dù tôi tự hỏi nếu có một lựa chọn tốt hơn MyApplication.onCreate() khi khởi tạo một lần cho mỗi quá trình là cần thiết. Ví dụ, nơi nào khác tôi sẽ đăng ký một trình xử lý đáng tin cậy cho các trường hợp ngoại lệ không bị bắt buộc? onCreate() hoạt động khi tôi có các hoạt động cũng như một dịch vụ. – orip

Các vấn đề liên quan