Layar terbaru

Layar Terbaru, yang juga disebut layar Ringkasan, daftar tugas terbaru, atau layar aplikasi terbaru, adalah UI tingkat sistem yang mencantumkan aktivitas dan tugas yang terakhir diakses. Pengguna dapat menavigasi daftar, memilih tugas untuk dilanjutkan, atau menghapus tugas dari daftar dengan menggesernya.

Layar Terbaru menggunakan model berorientasi dokumen—yang diperkenalkan di Android 5.0 (level API 21)—yang memungkinkan beberapa instance aktivitas yang sama yang berisi berbagai dokumen muncul sebagai tugas di layar Terbaru. Misalnya, Google Drive mungkin memiliki tugas tersendiri untuk beberapa dokumen Google. Setiap dokumen akan muncul sebagai tugas di layar Terbaru:

Layar Terbaru yang menampilkan dua dokumen Google Drive, masing-masing ditampilkan sebagai tugas terpisah.

Contoh umum lainnya adalah saat pengguna menggunakan browser mereka, lalu mengetuk Bagikan > Gmail. Layar Tulis aplikasi Gmail akan muncul. Mengetuk tombol Terbaru pada saat itu akan menampilkan Chrome dan Gmail berjalan sebagai tugas terpisah:

Layar Terbaru yang menampilkan Chrome dan Gmail berjalan sebagai tugas terpisah.

Biasanya, Anda membiarkan sistem menentukan bagaimana tugas dan aktivitas Anda ditampilkan di layar Terbaru. Anda tidak perlu mengubah perilaku ini. Namun, aplikasi Anda dapat menentukan bagaimana dan kapan aktivitas muncul di layar Terbaru.

Class ActivityManager.AppTask memungkinkan Anda mengelola tugas, dan flag aktivitas class Intent memungkinkan Anda menentukan kapan aktivitas ditambahkan atau dihapus dari layar Terbaru. Selain itu, atribut <activity> memungkinkan Anda menetapkan perilaku dalam manifes.

Menambahkan tugas ke layar Terbaru

Menggunakan flag class Intent untuk menambahkan tugas akan memberi Anda kontrol yang lebih besar terhadap waktu dan cara membuka atau membuka ulang dokumen di layar Terbaru. Jika menggunakan atribut <activity>, Anda dapat memilih antara selalu membuka dokumen di tugas baru atau menggunakan kembali tugas yang ada untuk dokumen tersebut.

Menggunakan flag Intent untuk menambahkan tugas

Saat membuat dokumen baru untuk aktivitas, Anda memanggil metode startActivity() dan meneruskannya ke intent yang meluncurkan aktivitas tersebut. Untuk menyisipkan jeda logis agar sistem memperlakukan aktivitas Anda sebagai tugas baru di layar Terbaru, teruskan tanda FLAG_ACTIVITY_NEW_DOCUMENT dalam metode addFlags() dari Intent yang meluncurkan aktivitas.

Jika Anda menetapkan flag FLAG_ACTIVITY_MULTIPLE_TASK saat membuat dokumen baru, sistem akan selalu membuat tugas baru dengan aktivitas target sebagai root. Setelan ini memungkinkan dokumen yang sama dibuka di lebih dari satu tugas. Kode berikut menunjukkan cara aktivitas utama melakukan hal ini dan memulai Aktivitas baru dari composable Anda:

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")
    }
}

Saat aktivitas utama meluncurkan aktivitas baru, sistem akan menelusuri tugas yang ada untuk intent yang cocok dengan nama komponen intent dan data intent untuk aktivitas tersebut. Jika tugas tidak ditemukan, atau intent berisi flag FLAG_ACTIVITY_MULTIPLE_TASK, tugas baru akan dibuat dengan aktivitas tersebut sebagai root-nya.

Jika sistem menemukan tugas yang intentnya cocok dengan nama komponen intent dan data intent, sistem akan membawa tugas tersebut ke depan dan meneruskan intent baru ke onNewIntent(). Aktivitas baru mendapatkan intent dan membuat dokumen baru di layar Terbaru, seperti yang ditunjukkan dalam contoh berikut:

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")
    }
}

Dalam kode sebelumnya, Aktivitas menangani perutean tingkat OS (onCreate dan onNewIntent), sementara fungsi @Composable hanya bertanggung jawab untuk merender UI berdasarkan status yang diberikan.

Menggunakan atribut aktivitas untuk menambahkan tugas

Aktivitas juga dapat menentukan dalam manifesnya bahwa aktivitas tersebut akan selalu diluncurkan ke tugas baru menggunakan atribut <activity> android:documentLaunchMode. Atribut ini memiliki empat nilai, yang menghasilkan efek berikut saat pengguna membuka dokumen dengan aplikasi:

intoExisting
Aktivitas menggunakan ulang tugas yang ada untuk dokumen. Ini sama dengan menyetel flag FLAG_ACTIVITY_NEW_DOCUMENT tanpa menyetel flag FLAG_ACTIVITY_MULTIPLE_TASK, seperti yang dijelaskan di bagian Menggunakan flag Intent untuk menambahkan tugas.
always
Aktivitas membuat tugas baru untuk dokumen, meskipun jika dokumen tersebut sudah dibuka. Menggunakan nilai ini sama dengan menyetel flag FLAG_ACTIVITY_NEW_DOCUMENT dan FLAG_ACTIVITY_MULTIPLE_TASK.
none
Aktivitas tidak membuat tugas baru untuk dokumen. Layar Terbaru memperlakukan aktivitas seperti yang akan terjadi secara default. Tugas tunggal ditampilkan untuk aplikasi, yang dilanjutkan dari aktivitas apa pun yang terakhir dipanggil pengguna.
never
Aktivitas tidak membuat tugas baru untuk dokumen. Menetapkan nilai ini akan menggantikan perilaku flag FLAG_ACTIVITY_NEW_DOCUMENT dan FLAG_ACTIVITY_MULTIPLE_TASK. Jika salah satunya ditetapkan dalam intent, dan layar Terbaru menampilkan satu tugas untuk aplikasi, aplikasi akan dilanjutkan dari aktivitas apa pun yang terakhir dipanggil pengguna.

Menghapus tugas

Secara default, tugas dokumen otomatis keluar dari layar Terbaru saat aktivitasnya selesai. Anda dapat mengganti perilaku ini dengan class ActivityManager.AppTask, dengan tanda Intent, atau dengan atribut <activity>.

Anda selalu dapat mengecualikan tugas dari layar Terbaru sepenuhnya dengan menetapkan atribut <activity> android:excludeFromRecents ke true.

Anda dapat menetapkan jumlah maksimum tugas yang dapat disertakan aplikasi Anda di layar Terbaru dengan menetapkan atribut <activity> android:maxRecents ke nilai bilangan bulat. Setelah jumlah tugas maksimum tercapai, tugas yang paling jarang digunakan akan menghilang dari layar Terbaru. Nilai defaultnya adalah 16, dan nilai maksimumnya adalah 50 (25 pada perangkat dengan memori rendah). Nilai kurang dari 1 tidak valid.

Menggunakan class AppTask untuk menghapus tugas

Dalam aktivitas yang membuat tugas baru di layar Terbaru, Anda dapat menentukan waktu untuk menghapus tugas dan menyelesaikan semua aktivitas yang terkait dengannya dengan memanggil metode 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")
    }
}

Mempertahankan tugas yang telah selesai

Jika Anda ingin menyimpan tugas di layar Terbaru, meskipun aktivitasnya telah selesai, teruskan flag FLAG_ACTIVITY_RETAIN_IN_RECENTS dalam metode addFlags() pada intent yang meluncurkan aktivitas.

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())
        }

Untuk mendapatkan hasil yang sama, tetapkan atribut <activity> android:autoRemoveFromRecents ke false. Nilai defaultnya adalah true untuk aktivitas dokumen dan false untuk aktivitas reguler. Penggunaan atribut ini akan menggantikan flag FLAG_ACTIVITY_RETAIN_IN_RECENTS.

Mengaktifkan berbagi URL terbaru (khusus Pixel)

Di perangkat Pixel yang menjalankan Android 12 atau yang lebih tinggi, pengguna dapat membagikan link ke konten web yang baru-baru ini dilihat langsung dari layar Terbaru. Setelah mengunjungi konten dalam aplikasi, pengguna dapat menggeser ke layar Terbaru dan menemukan aplikasi tempat mereka melihat konten, lalu mengetuk tombol link untuk menyalin atau membagikan URL.

Layar Terbaru dengan link untuk membagikan konten web yang baru dilihat.

Aplikasi apa pun dapat mengaktifkan penautan Terbaru untuk pengguna dengan menyediakan UI web dan mengganti onProvideAssistContent(), seperti yang ditunjukkan dalam contoh berikut:

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)
    }
}