Ekran Ostatnie, zwany też ekranem przeglądu, listą ostatnich zadań lub ekranem ostatnich aplikacji, to interfejs systemu, który zawiera listę ostatnio używanych aktywności i zadań. Użytkownik może poruszać się po liście, wybierać zadania do wznowienia lub usuwać je z listy, przesuwając palcem.
Ekran Ostatnie używa modelu opartego na dokumentach, który został wprowadzony w Androidzie 5.0 (API na poziomie 21). W tym modelu wiele instancji tej samej aktywności zawierających różne dokumenty może pojawiać się na ekranie Ostatnie jako zadania. Na przykład Dysk Google może mieć zadanie dla każdego z kilku dokumentów Google. Każdy dokument jest wyświetlany jako zadanie na ekranie Ostatnie:
Innym typowym przykładem jest sytuacja, w której użytkownik korzysta z przeglądarki i klika Udostępnij > Gmail. Wyświetli się ekran Utwórz w aplikacji Gmail. Kliknięcie przycisku Ostatnie w tym momencie spowoduje wyświetlenie Chrome i Gmaila jako osobnych zadań:
Zwykle to system określa, jak zadania i aktywności są reprezentowane na ekranie Ostatnie. Nie musisz modyfikować tego działania. Aplikacja może jednak określać, jak i kiedy aktywności będą wyświetlane na ekranie Ostatnie.
Klasa
ActivityManager.AppTask
umożliwia zarządzanie zadaniami, a flagi aktywności klasy
Intent pozwalają określać, kiedy aktywność jest dodawana lub usuwana z ekranu Ostatnie. Atrybuty <activity> umożliwiają też ustawienie zachowania w pliku manifestu.
Dodawanie zadań do ekranu Ostatnie
Używanie flag klasy Intent do dodawania zadania daje większą kontrolę nad tym, kiedy i jak dokument jest otwierany lub ponownie otwierany na ekranie Ostatnie. Gdy używasz atrybutów <activity>, możesz wybrać, czy dokument ma być zawsze otwierany w nowym zadaniu, czy w istniejącym zadaniu.
Dodawanie zadania za pomocą flagi Intent
Gdy tworzysz nowy dokument dla swojej aktywności, wywołujesz metodę
startActivity()
i przekazujesz do niej intencję, która uruchamia aktywność. Aby wstawić przerwę logiczną, dzięki której system będzie traktować Twoją aktywność jako nowe zadanie na ekranie Ostatnie, przekaż flagę FLAG_ACTIVITY_NEW_DOCUMENT w metodzie addFlags() interfejsu Intent, która uruchamia aktywność.
Jeśli podczas tworzenia nowego dokumentu ustawisz flagę FLAG_ACTIVITY_MULTIPLE_TASK, system zawsze utworzy nowe zadanie z aktywnością docelową jako elementem głównym. To ustawienie umożliwia otwieranie tego samego dokumentu w więcej niż jednym zadaniu. Poniższy kod pokazuje, jak główna aktywność to robi i uruchamia nową aktywność z funkcji kompozycyjnej:
private fun newDocumentIntent(context: Context): Intent = Intent(context, NewDocumentActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT or Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, documentCounter++) } @Composable fun CreateDocumentButton() { val context = LocalContext.current Button( onClick = { val intent = newDocumentIntent(context) // Add FLAG_ACTIVITY_MULTIPLE_TASK if needed based on state context.startActivity(intent) } ) { Text("Create New Document") } }
Gdy główna aktywność uruchamia nową aktywność, system przeszukuje istniejące zadania w poszukiwaniu takiego, którego intencja pasuje do nazwy komponentu intencji i danych intencji aktywności. Jeśli zadanie nie zostanie znalezione lub intencja zawiera flagę FLAG_ACTIVITY_MULTIPLE_TASK, zostanie utworzone nowe zadanie, którego elementem głównym będzie aktywność.
Jeśli system znajdzie zadanie, którego intencja pasuje do nazwy komponentu intencji i danych intencji, przeniesie to zadanie na pierwszy plan i przekaże nową intencję do onNewIntent().
Nowa aktywność otrzymuje intencję i tworzy nowy dokument na ekranie Ostatnie, jak pokazano w tym przykładzie:
class DocumentCentricActivity : ComponentActivity() { private var documentState by mutableStateOf( DocumentState( count = 0, textResId = R.string.hello_new_document_counter ) ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val initialCount = intent.getIntExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0) documentState = documentState.copy(count = initialCount) setContent { MaterialTheme { DocumentScreen( count = documentState.count, textResId = documentState.textResId ) } } } override fun onNewIntent(newIntent: Intent) { super.onNewIntent(newIntent) // If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this Activity is reused. documentState = documentState.copy( textResId = R.string.reusing_document_counter ) } data class DocumentState(val count: Int, @StringRes val textResId: Int) companion object { const val KEY_EXTRA_NEW_DOCUMENT_COUNTER = "KEY_EXTRA_NEW_DOCUMENT_COUNTER" } } @Composable fun DocumentScreen(count: Int, @StringRes textResId: Int) { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), verticalArrangement = Arrangement.Center ) { // UI reacts to whichever string resource ID was passed down Text(text = stringResource(id = textResId)) Spacer(modifier = Modifier.height(8.dp)) Text(text = "Counter: $count") } }
W powyższym kodzie aktywność obsługuje routing na poziomie systemu operacyjnego (onCreate i onNewIntent), a funkcja @Composable odpowiada tylko za renderowanie interfejsu na podstawie podanego stanu.
Używanie atrybutu aktywności do dodawania zadania
Aktywność może też określić w pliku manifestu, że zawsze uruchamia się w nowym zadaniu, za pomocą atrybutu <activity> android:documentLaunchMode.
Ten atrybut ma 4 wartości, które wywołują następujące efekty, gdy użytkownik otwiera dokument w aplikacji:
intoExisting- Aktywność ponownie wykorzystuje istniejące zadanie dotyczące dokumentu. Jest to równoznaczne z ustawieniem flagi
FLAG_ACTIVITY_NEW_DOCUMENTbez ustawiania flagiFLAG_ACTIVITY_MULTIPLE_TASK, co opisano w sekcji Używanie flagi Intent do dodawania zadania. always- Działanie tworzy nowe zadanie dla dokumentu, nawet jeśli jest on już otwarty. Użycie tej wartości jest równoznaczne z ustawieniem flag
FLAG_ACTIVITY_NEW_DOCUMENTiFLAG_ACTIVITY_MULTIPLE_TASK. none- Aktywność nie tworzy nowego zadania dla dokumentu. Ekran Ostatnie traktuje aktywność tak, jak domyślnie. Wyświetla jedno zadanie dla aplikacji, które jest kontynuowane od ostatniej aktywności użytkownika.
never- Aktywność nie tworzy nowego zadania dla dokumentu. Ustawienie tej wartości zastępuje działanie flag
FLAG_ACTIVITY_NEW_DOCUMENTiFLAG_ACTIVITY_MULTIPLE_TASK. Jeśli któryś z tych elementów jest ustawiony w intencji, a na ekranie Ostatnie wyświetla się jedno zadanie dla aplikacji, wznawia się ona od ostatniego działania wywołanego przez użytkownika.
Usuwanie zadań
Domyślnie zadanie związane z dokumentem jest automatycznie zamykane na ekranie Ostatnie, gdy jego aktywność się zakończy. Możesz zmienić ten sposób działania za pomocą klasy ActivityManager.AppTask, flagi Intent lub atrybutu <activity>.
Zadanie możesz całkowicie wykluczyć z ekranu Ostatnie, ustawiając atrybut <activity>android:excludeFromRecents na true.
Możesz ustawić maksymalną liczbę zadań, które aplikacja może zawierać na ekranie Ostatnie, ustawiając atrybut <activity>android:maxRecents na wartość całkowitą. Gdy osiągniesz maksymalną liczbę zadań, najrzadziej używane zadanie zniknie z ekranu Ostatnie. Wartość domyślna to 16, a maksymalna to 50 (25 na urządzeniach z małą ilością pamięci). Wartości mniejsze niż 1 są nieprawidłowe.
Usuwanie zadań za pomocą klasy AppTask
W aktywności, która tworzy nowe zadanie na ekranie Ostatnie, możesz określić, kiedy usunąć zadanie i zakończyć wszystkie powiązane z nim aktywności, wywołując metodę finishAndRemoveTask():
@Composable fun RemoveTaskButton() { val context = LocalContext.current Button( onClick = { // It is good practice to remove a document from the overview stack if not needed anymore. (context as? Activity)?.finishAndRemoveTask() } ) { Text("Remove from Recents") } }
Zachowywanie ukończonych zadań
Jeśli chcesz zachować zadanie na ekranie Ostatnie, nawet jeśli jego aktywność została zakończona, przekaż flagę FLAG_ACTIVITY_RETAIN_IN_RECENTS w metodzie addFlags() intencji, która uruchamia aktywność.
private fun newDocumentIntent() = Intent(this, NewDocumentActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT or android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, getAndIncrement()) }
Aby osiągnąć ten sam efekt, ustaw atrybut <activity>android:autoRemoveFromRecents na false. Wartość domyślna to true w przypadku aktywności związanych z dokumentami i false w przypadku zwykłych aktywności. Użycie tego atrybutu zastępuje flagę FLAG_ACTIVITY_RETAIN_IN_RECENTS.
Włącz udostępnianie ostatnio używanych adresów URL (tylko Pixel)
Na urządzeniach Pixel z Androidem 12 lub nowszym użytkownicy mogą udostępniać linki do ostatnio wyświetlanych treści internetowych bezpośrednio z ekranu Ostatnie. Po wyświetleniu treści w aplikacji użytkownik może przesunąć palcem do ekranu Ostatnie i znaleźć aplikację, w której wyświetlił treść, a następnie kliknąć przycisk linku, aby skopiować lub udostępnić adres URL.
Każda aplikacja może włączyć linkowanie do ostatnio używanych aplikacji, udostępniając interfejs internetowy i zastępując onProvideAssistContent(), jak pokazano w tym przykładzie:
class MainActivity : ComponentActivity() { // Track the current URL as state so the UI can update it during navigation private var currentWebUri by mutableStateOf("https://example.com/home") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { AppTheme { // Pass a lambda to your Compose UI so it can update the URL state // as the user navigates through your app. MainScreen( onPageChanged = { newUrl -> currentWebUri = newUrl } ) } } } override fun onProvideAssistContent(outContent: AssistContent) { super.onProvideAssistContent(outContent) // The system calls this when the user enters the Recents screen. // Provide the active URI tracked by the Compose state. outContent.webUri = Uri.parse(currentWebUri) } }