2010-03-11 27 views
55

Tôi có hoạt động A với android:launchMode="singleTop" trong tệp kê khai.Mục đích mới() bắt đầu phiên bản mới bằng Android: launchMode = "singleTop"

Nếu tôi đi đến Hoạt động B, C, và D đó tôi có các phím tắt menu để quay trở lại hoạt động gốc ứng dụng của tôi (A).

Mã này trông như thế này:

Intent myIntent = new Intent(getBaseContext(), MainActivity.class); 
startActivity(myIntent); 

Tuy nhiên, thay vì trở về trường hợp đã tồn tại A của tôi MainActivity.class nó tạo ra một trường hợp mới -> nó đi để onCreate() thay vì onNewIntent().

Đây không phải là hành vi mong đợi, đúng không?

Trả lời

65

Điều này sẽ thực hiện thủ thuật.

<activity ... android:launchMode="singleTop" /> 

Khi bạn tạo ra một ý định để bắt đầu sử dụng ứng dụng:

Intent intent= new Intent(context, YourActivity.class); 
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

này là nên cần thiết.

+2

Điều này không hiệu quả đối với tôi.: (Các dòng mã dưới đây hoạt động tốt. Ý định myIntent = new Intent (getBaseContext(), MainActivity.class); myIntent.setFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (myIntent); –

14

Trích từ documentation:

Các "tiêu chuẩn" và "singleTop" chế độ khác nhau chỉ trong một tôn trọng: Mỗi khi có mới ý định cho một hoạt động "chuẩn", một mới thể hiện của lớp học được tạo ra để trả lời ý định đó. Mỗi trường hợp xử lý một mục đích duy nhất. Tương tự, phiên bản mới của hoạt động "singleTop" cũng có thể được tạo để xử lý mục đích mới. Tuy nhiên, nếu nhiệm vụ mục tiêu đã có một thể hiện của hoạt động ở phía trên cùng của stack của nó, dụ rằng sẽ nhận được mục đích mới (trong một onNewIntent() cuộc gọi); một cá thể mới không được tạo.

Tôi không chắc chắn 100% "hiện đã có hoạt động hiện tại ở đầu ngăn xếp" có nghĩa là, nhưng có lẽ hoạt động của bạn không đáp ứng điều kiện này.

Liệu singleTask hoặc singleInstance có phù hợp với bạn không? Hoặc có lẽ bạn có thể thử thiết lập FLAG_ACTIVITY_SINGLE_TOP về mục đích mà bạn đang tạo để xem điều đó có tạo nên sự khác biệt hay không, mặc dù tôi không nghĩ điều đó sẽ xảy ra.

+0

Điều đó có nghĩa là ngăn tác vụ (ngăn xếp ứng dụng) hiện đang hoạt động có một hoạt động trên đầu trang (ví dụ: hoạt động đang bắt đầu một bản sao khác của hoạt động đó khi nó tập trung). Các trường hợp khác của cùng một hoạt động có thể tồn tại trên các tác vụ khác (ứng dụng). –

+0

Vì vậy, nếu ý chí của tôi là để khởi động một thể hiện mới của hoạt động trong cùng một áp dụng, nhưng tôi đã TẬP TRUNG trên một ví dụ previouse của hoạt động đó, làm thế nào tôi sẽ làm điều đó? – rayman

+0

@rayman sử dụng chế độ chuẩn tôi giả sử? nó nói trong doc "Mỗi khi có ý định mới cho một hoạt động" chuẩn ", một thể hiện mới của lớp được tạo ra để đáp ứng với ý định đó." –

27

Điều gì thực sự làm việc cho tôi cuối cùng là thế này:

Intent myIntent = new Intent(getBaseContext(), MainActivity.class); 
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(myIntent); 
+0

Làm việc điều trị, nhờ –

+0

Bạn có thể gặp phải một số [hành vi bất ngờ] (https://github.com/cleverua/android_startup_activity) với hoạt động singleTop. https://github.com/cleverua/android_startup_activity) –

+0

Tuyệt vời! Cảm ơn bạn, thưa ngài. :) –

6

Bạn có thể trở lại trường hợp hiện tại cùng với Hoạt động android:launchMode="singleInstance"

trong biểu hiện. Khi bạn quay trở lại A từ B, có thể cần thiết finish() để tiêu hủy B.

1

Thứ nhất, cấu trúc ngăn xếp có thể được kiểm tra. Đối với chế độ khởi chạy: singleTop
Nếu một thể hiện của cùng một hoạt động đã ở trên cùng của ngăn tác vụ, thì trường hợp này sẽ được sử dụng lại để phản hồi mục đích.

Mọi hoạt động được giữ trong ngăn xếp ("đầu tiên trong cuối cùng out") vì vậy nếu hoạt động hiện tại của bạn là ở phía trên cùng của ngăn xếp và nếu bạn định nghĩa nó trong manifest.file như singleTop

android:name=".ActivityA" 
android:launchMode="singleTop" 

nếu bạn đang ở trong ActivityA tạo lại hoạt động nó sẽ không nhập onCreate sẽ tiếp tục onNewIntent() và bạn có thể thấy bằng cách tạo ra một thông báo Không: İf bạn không thực hiện onNewIntent (Intent) bạn sẽ không có ý định mới.

Intent activityMain = new Intent(ActivityA.this, 
         ActivityA.class); 

       activityMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
         | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
       startActivity(activityMain); 




    @Override 
     protected void onNewIntent(Intent intent) { 

      super.onNewIntent(intent); 

      notify("onNewIntent"); 
     } 

     private void notify(String methodName) { 

      String name = this.getClass().getName(); 
      String[] strings = name.split("\\."); 

      Notification noti = new Notification.Builder(this) 
        .setContentTitle(methodName + "" + strings[strings.length - 1]) 
        .setAutoCancel(true).setSmallIcon(R.drawable.ic_launcher) 
        .setContentText(name).build(); 
      NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
      notificationManager.notify((int) System.currentTimeMillis(), noti); 

     } 
0

Điều này là do hoạt động gốc đã bị hủy khi bạn khởi động từ B, C hoặc D. Do đó, onCreate sẽ được gọi thay cho onNewIntent(). Một cách để giải quyết điều này là luôn phá hủy A hiện tại (sử dụng FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK kết hợp khi startActivity) trước khi bắt đầu A mới, do đó onCreate sẽ luôn được gọi, và bạn đặt mã onNewIntent() vào onCreate bằng cách kiểm tra if getIntent () là ý định bạn bắt đầu.

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