2012-03-02 24 views
47

Trong ứng dụng của tôi có một biến tĩnh được đặt thành rỗng khi tôi quay lại ứng dụng của mình từ trình duyệt bên ngoài. Có vẻ như ứng dụng hoặc một phần của nó bị giết nếu trang web bên ngoài mà tôi khởi chạy là đủ phức tạp.null biến tĩnh khi quay lại ứng dụng

Nếu ứng dụng bị giết hoàn toàn và sau đó được khởi động lại từ hoạt động chính sẽ ổn, nhưng khởi chạy lại từ hoạt động khởi động trình duyệt - và không có nghĩa là đặt trạng thái ứng dụng sao cho nó bị lỗi khi truy cập biến tĩnh null. Đây là vấn đề thiết bị một trong sáu thiết bị của tôi nên tôi cần một số lời khuyên.

Có cờ để đặt để ngăn chặn hành vi này không?

+0

"Nếu ứng dụng bị giết hoàn toàn và sau đó được relauched từ hoạt động chính sẽ ổn ..." - Trong trường hợp đó chỉ cần tạo một lớp mở rộng 'Application' và giữ biến tĩnh ở đó. – Squonk

+2

Vì vậy, có một sự khác biệt trong phạm vi của một tĩnh nếu trong Application.java hoặc một số khác? – jchristof

+0

@jchristof đã quá muộn nhưng trường tĩnh của ứng dụng sẽ không tạo sự khác biệt – oscarthecat

Trả lời

33

Đây là hành vi tiêu chuẩn trong hầu hết các hệ điều hành di động, bao gồm Android. Ứng dụng của bạn trên thực tế rất thường bị giết nếu một số ứng dụng khác có mức ưu tiên cao hơn (nói chung, nếu nó ở phía trước ưu tiên cao hơn) cần tài nguyên. Điều này là do bản chất của thiết bị di động có tài nguyên tương đối hạn chế.

Bạn nên lưu dữ liệu của mình ở nơi nào đó có độ bền cao hơn. Bạn có thể tìm thấy bài viết này trên chung Data Storage để có ích. Câu hỏi này cũng nên có liên quan: Saving Android Activity state using Save Instance State

Lưu ý rằng đây thực tế là không phải là một vấn đề thiết bị một trong sáu thiết bị. Đây là "sự cố" trên tất cả các thiết bị, điều này chỉ rõ ràng hơn trên một trong các thiết bị của bạn vì có ít bộ nhớ hơn. Nếu bạn chạy một ứng dụng rất nhiều bộ nhớ trên bất kỳ thiết bị nào khác của bạn, bạn sẽ thấy hành vi tương tự. Ngoài ra không có lá cờ để ngăn chặn điều này. Đây là tiêu chuẩn và dự kiến.

+0

Ok, đây là tuyên bố đúng trong mọi trường hợp: "Tất cả các hoạt động trong tệp kê khai của ứng dụng phải có khả năng là hoạt động khởi chạy để khởi động ứng dụng". – jchristof

+0

Không. Nếu ứng dụng của bạn bị giết trong khi ở chế độ nền trên Hoạt động B trong khi Hoạt động A là hoạt động khởi chạy chính trong ứng dụng của bạn thì Hoạt động A sẽ được khởi chạy khi bạn khởi động lại ứng dụng. Bạn cũng có thể tìm thấy thông tin [tài liệu này] (http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle). – kabuko

+0

Tôi đang bối rối về điểm này vì tất cả những điều này xảy ra trong trường hợp này: Hoạt động B khởi động trình duyệt gốc. Quay lại từ trình duyệt onCreate() của hoạt động B (không phải onResume()). Biến tĩnh là null hợp lệ cho đến khi khởi chạy trình duyệt. – jchristof

4

Không ... bạn không nên lưu trữ dữ liệu trong các biến tĩnh trên Android. Nếu bạn nhấn mạnh vào việc làm nó, bạn sẽ cần để có thể phục hồi từ nó khi nó là null .. bạn nên lưu trạng thái của bạn với bó hoặc các phương tiện khác.

0

Có thể bạn chỉ muốn theo liên kết thứ hai của kabuko. Nhưng nếu bạn muốn giữ lại biến tĩnh của bạn (có lẽ bạn có một số lý do tuyệt vời cho việc này), bạn có thể làm điều này:

private static MyObjType getVariable() 
{ 
    if (myVar == null) 
    myVar = new MyObjType(); // do whatever else you need to here 

    return myVar; 
} 

Bằng cách đó bạn có thể thay thế các cuộc gọi của bạn để myVar.test() với getVariable(). test() và bạn biết nó sẽ không bao giờ gây ra một ngoại lệ con trỏ null.

+1

Điều này có điều kiện chủng tộc –

4

Các giải pháp để sử dụng tĩnh của (singleton) trong Android là rất dễ dàng:

Thực hiện một lớp mà kéo dài android.app.Application và làm tất cả khởi singleton của bạn trong vòng onCreate()

Lập luận:

  • lớp mở rộng Ứng dụng được thực thi trước tiên, ngay cả khi quá trình của ứng dụng của bạn bị giết do tình trạng bộ nhớ thấp
  • ứng dụng của bạn có ngữ cảnh ngay sau đó s Application.onCreate() được gọi là
+1

lớp mở rộng Ứng dụng được thực hiện * trước tiên ?? Thực hiện nghĩa là gì? Hơn nữa - bạn có thể cung cấp tài liệu cho khiếu nại này không? –

+0

cũng thêm chúng vào tệp kê khai như Qamar

0

Sử dụng lớp ứng dụng cho những thứ như vậy. Nó luôn được khởi tạo trước khi bất kỳ thành phần nào (hoạt động, dịch vụ, người nhận) của ứng dụng của bạn sẽ bắt đầu. Vì vậy, bạn chắc chắn rằng tất cả các biến tĩnh là có và khởi tạo.

1

Bạn phải lưu các giá trị của mình trong onSaveInstanceState và đưa nó trở lại trênRestoreInstanceState vì khi một hoạt động chuyển sang vòng đời trạng thái dừng, tất cả các giá trị tĩnh sẽ là rỗng.

vd:

 /* save my satatic hashmap in case of activity stopped to retrieve it again in onRestoreInstanceState method*/ 
     @Override 
     protected void onSaveInstanceState(Bundle outState) { 
      super.onSaveInstanceState(outState); 

    //Common.PERMISION_MAP static hashmap 
      if (Common.PERMISION_MAP != null) { 
       Iterator<Permission> iterator = Common.PERMISION_MAP.values() 
         .iterator(); 
       ArrayList<Permission> permissionList = new ArrayList<Permission>(); 
       while (iterator.hasNext()) { 
        Permission permission = (Permission) iterator.next(); 
        permissionList.add(permission); 

       } 
       outState.putParcelableArrayList("PERMISSION_LIST", permissionList); 
      } 


     } 

     /* restore my satatic hashmap when activity stopped */ 
     @Override 
     protected void onRestoreInstanceState(Bundle savedInstanceState) { 
      super.onRestoreInstanceState(savedInstanceState); 

      try { 
       ArrayList<Permission> permissionList = savedInstanceState 
         .getParcelableArrayList("PERMISSION_LIST"); 

       if (Common.PERMISION_MAP == null) 
        Common.PERMISION_MAP = new HashMap<Permission, Permission>(); 
for (Permission permission : permissionList) { 
       Common.PERMISION_MAP.put(permission, permission); 

      } 
       } catch (Exception ex) { 
       String string = ex != null ? ex.getMessage() : ""; 
       Log.e(TAG, (string != null ? string : "")); 
       ex.printStackTrace(); 

      } 
     } 
17

Thường điều này xảy ra khi thiết bị chuyển sang chế độ ngủ .

Hành vi này của thiết bị có thể được mô phỏng theo các bước sau:

  1. chạy các ứng dụng và bấm nút Home
  2. Trong Android Studio ở góc dưới bên trái, chọn sửa lỗi ứng dụng và nhấn nút X (ứng dụng chấm dứt) ở bên trái tên ứng dụng. (Không biết làm thế nào để Eclipse, nhưng tôi nghĩ tương tự)
  3. Nhấp vào biểu tượng ứng dụng trên thiết bị.

Nếu Task đã hoạt động, ứng dụng sẽ mở cửa vào hoạt động cuối cùng và (rất có thể) sẽ tạo ra một lỗi, vì tất cả các biến tĩnh đã được lá.

+1

Đây là các bước tái tạo hữu ích. Bây giờ, ứng dụng đã gỡ lỗi được phân loại thành tab ** Màn hình Android **. –

+0

Làm thế nào về các biến không tĩnh? –

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