2015-08-06 15 views
6

Tôi có một ứng dụng, bắt đầu bằng SplashScreenActivity. Sau đó, LoginActivity được hiển thị hoặc nếu người dùng đã đăng nhập, một MainActivity sẽ được hiển thị. Nếu ứng dụng đang chạy, SplashScreenActivity được bác bỏ với những điều sau đâyAndroid: BackStack hành vi sai trái, nếu ứng dụng được bắt đầu từ một ứng dụng khác

//SplashScreenActivity 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    //Adding this check for following cases 
    if (!isTaskRoot()) 
    { 
     String intentAction = getIntent().getAction(); 
     if (getIntent().hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) { 
      finish(); 
      return; 
     } 

     if(getIntent().getCategories().contains(GCMIntentService.INTENT_CATEGORY_GH_NOTIFICATION)){ 
      finish(); 
      return; 
     } 
    } 

Vấn đề xảy ra

Nếu tôi khởi động ứng dụng từ một hoạt động như PlayStore, nó lại ở hoạt động đúng nếu đang chạy. Đây là Intent Tôi đang sử dụng để tái tạo trong một ứng dụng thứ hai

//AnotherApplication.apk 
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("my.package.name"); 
startActivity(launchIntent); 

Tuy nhiên, hành động này là bằng cách nào đó phá vỡ Backstack. Thay vì đóng ứng dụng trên backpress trong MainActivity, nó khởi động lại ứng dụng.

//MainActivity.class 
@Override 
public void onBackPressed() { 
    if (getNavDrawerMain().isDrawerOpen()) { 
     getNavDrawerMain().closeDrawer(); 
    } else { 
     closeApp(); 
    } 
} 

protected void closeApp() { 
    if (doubleBackToExitPressedOnce) { 
     //super.onBackPressed(); //i tried both, but behaviour is the same 
     finish(); 
     return; 
    } 
    this.doubleBackToExitPressedOnce = true; 

    new Handler().postDelayed(new Runnable() { 

     @Override 
     public void run() 
      doubleBackToExitPressedOnce = false; 
     } 
    }, 500); 
} 

tôi đã sử dụng breakpoint và phát hiện ra rằng MainActivity: onDestroy() được gọi, nhưng thay vì nối lại ứng dụng vào màn hình chính, nó luôn luôn khởi động lại và tôi không biết tại sao.

Tôi đã thử các cách sau: - Đã sử dụng các bản khởi chạy khác nhau như singleTasksingleInstance, nhưng nó không tạo ra bất kỳ sự khác biệt nào. onNewIntent được gọi, nhưng nếu tôi gọi finish, HomeActivity khởi động lại - như commeted dưới đây, tôi đã cố gắng moveTaskToBack(true), nhưng Hoạt động được restaring quá (và chúng tôi thực sự muốn đóng ứng dụng thay vì di chuyển nó vào BackStack)

+1

Theo kinh nghiệm của tôi, 'getLaunchIntentForPackage (...)' * không * trả về ý định của trình khởi chạy. Một ý định phóng sẽ nâng cao nhiệm vụ hiện có, nhưng các intent được trả về bởi 'getLaunchIntentForPackage (...)' sẽ thực sự bắt đầu một nhiệm vụ mới. Ứng dụng của bạn có thể không khởi động lại khi bạn thoát khỏi ứng dụng; bạn có thể chỉ cần nhìn thấy một bản sao của nó. –

+1

@KevinKrumwiede: Intent có loại sau 'android.intent.action.MAIN', tôi vừa thêm một số mã bổ sung, cách tôi xử lý mục đích – longilong

+1

Tôi không thể tìm thấy bất kỳ điều gì rõ ràng nói như vậy, nhưng tôi nghi ngờ rằng chỉ có hệ thống là được phép nhận 'ACTION_MAIN'. –

Trả lời

1

Cố gắng thêm cờ này để ý định của bạn bắt đầu ứng dụng của bạn: RESET_TASK_IF_NEEDED, URL = http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

những gì nó:

Nếu thiết lập, và hoạt động này là một trong hai được bắt đầu trong một nhiệm vụ mới hoặc đưa lên hàng đầu một nhiệm vụ hiện có, sau đó nó sẽ được đưa ra như là cánh cửa trước của nhiệm vụ.

Bạn cũng có thể sử dụng: http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_REORDER_TO_FRONT

Những gì nó:

Nếu đặt trong Intent truyền cho Context.startActivity(), lá cờ này sẽ làm cho hoạt động đưa ra để được đưa đến trước mặt ngăn xếp lịch sử của nhiệm vụ nếu nó đang chạy.

Loại nào bạn sử dụng tùy thuộc vào kết quả mong muốn.

Nếu bạn không thể kiểm soát ai bắt đầu bạn, bạn cần đặt hoặc khởi chạy chế độ thành công việc đơn lẻ hoặc đơn lẻ.

mô tả ở đây:

http://inthecheesefactory.com/blog/understand-android-activity-launchmode/en

Phần thú vị:

singleTask

Chế độ này là khá khác biệt so với tiêu chuẩn và singleTop.Một hoạt động với singleTask launchMode được phép chỉ có một cá thể trong hệ thống (a.k.a. Singleton). Nếu có một cá thể Activity tồn tại trong hệ thống, toàn bộ Task giữ instance sẽ được di chuyển lên đầu trong khi Intent sẽ được gửi thông qua phương thức onNewIntent(). Nếu không, Hoạt động mới sẽ được tạo và được đặt trong Nhiệm vụ phù hợp.

+0

vấn đề là, 'Intent' nơi tôi nên thêm cờ được bắt đầu từ (trong trường hợp của chúng tôi)' Google Play Store' hoặc 'HockeyApp', vì vậy chúng tôi không thể thay đổi chúng. Hay tôi đã hiểu lầm câu hỏi của bạn? – longilong

+0

Ồ, sau đó bạn chỉ cần một nhiệm vụ cá thể duy nhất, câu trả lời được cập nhật. – JohanShogun

+0

"... đã thử các bản khởi chạy khác nhau, nhưng nó không tạo ra bất kỳ sự khác biệt nào ..." có lẽ tôi nên làm cho điểm này rõ ràng hơn. Tôi đã thử 'singleTop',' singleTask' vv ... Không tạo ra bất kỳ sự khác biệt nào. Tôi thấy, hoạt động đó bị phá hủy, nhưng thay vì nối lại với ngăn xếp prevoius, nó gọi lại 'onCreate()' một lần nữa – longilong

1

Hãy thử với moveTaskToBack(true); thay vì finish(); để đóng ứng dụng. Sau đó nó sẽ đi đến OnRestart() và sau đó OnStart() -> OnResume() (và sẽ không đi đến OnCreate).

Và đảm bảo bạn không có "Không lưu giữ hoạt động" được đánh dấu tại Tùy chọn nhà phát triển trong Cài đặt Android của bạn (hủy mọi hoạt động ngay khi người dùng rời khỏi nó).

+1

cảm ơn cho bình luận, tôi chỉ cố gắng nhưng hành vi vẫn giữ nguyên ... – longilong

+0

Hãy chắc chắn rằng bạn không có "Không giữ hoạt động" được đánh dấu tại Tùy chọn nhà phát triển trong Cài đặt Android của bạn (tiêu diệt mọi hoạt động ngay khi người dùng rời khỏi hoạt động). –

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