L'incorporamento delle attività ottimizza le app sui dispositivi con schermi grandi dividendo la finestra delle attività di un'applicazione tra due attività o due istanze della stessa attività.
Se la tua app è composta da più attività, l'incorporamento delle attività ti consente di offrire un'esperienza utente migliorata su tablet, pieghevoli e dispositivi ChromeOS.
L'incorporamento delle attività non richiede il refactoring del codice. Puoi determinare in che modo la tua app visualizza le sue attività, affiancate o impilate, creando un file di configurazione XML o effettuando chiamate API Jetpack WindowManager.
Il supporto per gli schermi di piccole dimensioni viene gestito automaticamente. Quando l'app si trova su un dispositivo con uno schermo piccolo, le attività vengono impilate una sull'altra. Su schermi di grandi dimensioni, le attività vengono visualizzate affiancate. Il sistema determina la presentazione in base alla configurazione che hai creato, senza bisogno di una logica di diramazione.
L'incorporamento delle attività si adatta ai cambiamenti di orientamento del dispositivo e funziona perfettamente sui dispositivi pieghevoli, mentre le attività di impilamento e disimpilamento sono disponibili quando il dispositivo si piega e si apre.
L'incorporamento delle attività è supportato sulla maggior parte dei dispositivi con schermi di grandi dimensioni con Android 12L (livello API 32) e versioni successive.
Finestra attività divisa
L'incorporamento delle attività suddivide la finestra delle attività dell'app in due container: principali e secondari. I container contengono attività avviate dall'attività principale o da altre attività già nei container.
Le attività vengono impilate nel container secondario quando vengono avviate e il container secondario viene impilato sopra il container principale su schermi di piccole dimensioni, in modo che lo stack delle attività e la navigazione a ritroso siano coerenti con l'ordine delle attività già integrate nella tua app.
L'incorporamento delle attività consente di visualizzare le attività in diversi modi. L'app può suddividere la finestra delle attività avviando contemporaneamente due attività affiancate:
In alternativa, un'attività che occupa l'intera finestra dell'attività può creare una suddivisione avviando una nuova attività insieme a:
Le attività già in una suddivisione e che condividono una finestra delle attività possono avviare altre attività nei seguenti modi:
A lato sopra un'altra attività:
Di lato e sposta la divisione nascondendo l'attività principale precedente:
Lancia un'attività nella parte superiore, ovvero nella stessa serie di attività:
Avvia una finestra intera dell'attività nella stessa attività:
Navigazione a ritroso
Diversi tipi di applicazioni possono avere regole di navigazione a ritroso diverse in uno stato della finestra delle attività suddivisa a seconda delle dipendenze tra le attività o del modo in cui gli utenti attivano l'evento back, ad esempio:
- Unione: se le attività sono correlate e una non deve essere mostrata senza l'altra, è possibile configurare la navigazione a ritroso per terminare entrambe.
- Passaggio autonomo: se le attività sono completamente indipendenti, la navigazione a ritroso di un'attività non influisce sullo stato di un'altra attività nella finestra dell'attività.
L'evento Indietro viene inviato all'ultima attività attiva quando utilizzi la navigazione con pulsanti. Con la navigazione basata sui gesti, l'evento Indietro viene inviato all'attività in cui si è verificato il gesto.
Layout a più riquadri
Jetpack WindowManager consente di creare un'attività di incorporamento di un layout multi-riquadro su dispositivi con schermi di grandi dimensioni con Android 12L (livello API 32) o versioni successive e su alcuni dispositivi con versioni precedenti della piattaforma. Le app esistenti basate su più attività piuttosto che su frammenti o layout basati sulle visualizzazioni come SlidingPaneLayout
possono fornire un'esperienza utente migliorata su schermi di grandi dimensioni senza dover ricorrere al refactoring del codice sorgente.
Un esempio comune è la suddivisione dei dettagli dell'elenco. Per garantire una presentazione di alta qualità, il sistema avvia l'attività dell'elenco e l'applicazione, quindi, avvia immediatamente l'attività dei dettagli. Il sistema di transizione attende che entrambe le attività vengano tracciate, quindi le visualizza insieme. Per l'utente, le due attività vengono avviate come una sola.
Attributi suddivisi
Puoi specificare la proporzione della finestra delle attività tra i container divisi e la disposizione dei container l'uno rispetto all'altro.
Per le regole definite in un file di configurazione XML, imposta i seguenti attributi:
splitRatio
: imposta le proporzioni del contenitore. Il valore è un numero in virgola mobile nell'intervallo aperto (0,0, 1,0).splitLayoutDirection
: specifica la disposizione dei container suddivisi l'uno rispetto all'altro. I valori includono:ltr
: da sinistra a destrartl
: da destra a sinistralocale
:ltr
ortl
viene determinato dalle impostazioni internazionali
Consulta la sezione Configurazione XML di seguito per alcuni esempi.
Per le regole create utilizzando le API WindowManager, crea un oggetto SplitAttributes
con SplitAttributes.Builder
e chiama i seguenti metodi del builder:
setSplitType()
: imposta le proporzioni dei contenitori suddivisi. ConsultaSplitAttributes.SplitType
per gli argomenti validi, incluso il metodoSplitAttributes.SplitType.ratio()
.setLayoutDirection()
: imposta il layout dei container. VediSplitAttributes.LayoutDirection
per i possibili valori.
Consulta la sezione API WindowManager di seguito per alcuni esempi.
Segnaposto
Le attività segnaposto sono attività secondarie vuote che occupano un'area di una suddivisione attività. In ultima analisi, devono essere sostituite con un'altra attività che include contenuti. Ad esempio, un'attività segnaposto potrebbe occupare il lato secondario di una suddivisione attività in un layout di dettagli elenco fino a quando non viene selezionato un elemento dall'elenco, dopodiché un'attività contenente le informazioni dettagliate per l'elemento dell'elenco selezionato sostituisce il segnaposto.
Per impostazione predefinita, il sistema visualizza i segnaposto solo quando c'è spazio sufficiente per una suddivisione dell'attività. I segnaposto terminano automaticamente quando le dimensioni di visualizzazione cambiano in larghezza o altezza troppo piccole per poter visualizzare una suddivisione. Quando lo spazio lo consente, il sistema riavvia il segnaposto con uno stato reinizializzato.
Tuttavia, l'attributo stickyPlaceholder
di un metodo SplitPlaceholderRule
o setSticky()
di SplitPlaceholder.Builder
può sostituire il comportamento predefinito. Quando l'attributo o il metodo specifica un valore true
, il sistema mostra il segnaposto come attività principale nella finestra dell'attività quando la visualizzazione viene ridimensionata a una visualizzazione a riquadro singolo rispetto a una visualizzazione a due riquadri (per un esempio, consulta Configurazione suddivisa).
Modifiche alle dimensioni della finestra
Quando le modifiche alla configurazione del dispositivo riducono la larghezza della finestra dell'attività in modo che non sia abbastanza grande per un layout a più riquadri (ad esempio, quando un dispositivo pieghevole di grandi dimensioni viene piegato da un tablet a uno smartphone o la finestra dell'app viene ridimensionata in modalità multi-finestra), le attività non segnaposto nel riquadro secondario della finestra dell'attività vengono sovrapposte alle attività nel riquadro principale.
Le attività segnaposto vengono visualizzate solo quando la larghezza di visualizzazione è sufficiente per una suddivisione. Su schermi più piccoli, il segnaposto viene ignorato automaticamente. Quando l'area di visualizzazione diventa di nuovo sufficientemente grande, il segnaposto viene ricreato. Vedi Segnaposto sopra.
L'impilamento delle attività è possibile perché WindowManager ordina le attività nel riquadro secondario sopra le attività nel riquadro principale.
Più attività nel riquadro secondario
L'attività B avvia l'attività C senza ulteriori flag di intent:
determinando il seguente ordine z di attività nella stessa attività:
Quindi, in una finestra delle attività più piccola, l'applicazione si riduce a una singola attività con C in cima all'elenco:
Se torni indietro nella finestra più piccola, puoi spostarti tra le attività impilate una sopra l'altra.
Se la configurazione della finestra delle attività viene ripristinata a una dimensione più grande che può ospitare più riquadri, le attività vengono mostrate di nuovo affiancate.
Suddivisioni in pila
L'attività B inizia l'attività C di lato e sposta la suddivisione lateralmente:
Il risultato è il seguente ordine z di attività nella stessa attività:
In una finestra delle attività più piccola, l'applicazione si riduce a una singola attività con C in alto:
Orientamento verticale fisso
L'impostazione manifest android:screenOrientation consente alle app di limitare le attività all'orientamento verticale o orizzontale. Per migliorare l'esperienza utente sui dispositivi con schermi di grandi dimensioni, come tablet e pieghevoli, i produttori di dispositivi (OEM) possono ignorare le richieste di orientamento dello schermo e utilizzare l'orientamento orizzontale o verticale per l'app sui display orizzontali.
Analogamente, quando l'incorporamento delle attività è abilitato, gli OEM possono personalizzare i dispositivi per le attività letterbox fisse verticali in orientamento orizzontale su schermi di grandi dimensioni (larghezza ≥ 600 dp). Quando un'attività con ritratto fisso avvia una seconda attività, il dispositivo può visualizzare le due attività affiancate in un display a due riquadri.
Aggiungi sempre la proprietà android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED
al file manifest dell'app per informare i dispositivi che la tua app supporta l'incorporamento delle attività (consulta la sezione Configurazione suddivisa di seguito). I dispositivi personalizzati OEM possono quindi determinare se utilizzare le attività letterbox con verticale fisso.
Configurazione suddivisione
Le regole di suddivisione consentono di configurare le suddivisioni delle attività. Puoi definire le regole di suddivisione in un file di configurazione XML o effettuando chiamate API Jetpack WindowManager.
In entrambi i casi, l'app deve accedere alla libreria WindowManager e deve informare il sistema che l'app ha implementato l'incorporamento dell'attività.
Segui questi passaggi:
Aggiungi la dipendenza della libreria WindowManager più recente al file
build.gradle
a livello di modulo della tua app, ad esempio:implementation 'androidx.window:window:1.1.0-beta02'
La libreria WindowManager fornisce tutti i componenti necessari per l'incorporamento delle attività.
Comunica al sistema che la tua app ha implementato l'incorporamento delle attività.
Aggiungi la proprietà
android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED
all'elemento <application> del file manifest dell'app e imposta il valore su true, ad esempio:<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application> <property android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED" android:value="true" /> </application> </manifest>
Nella versione 1.1.0-alpha06 e successive di WindowManager, le suddivisioni di incorporamento delle attività vengono disattivate a meno che la proprietà non venga aggiunta al manifest e impostata su true.
Inoltre, i produttori di dispositivi utilizzano questa impostazione per abilitare funzionalità personalizzate per le app che supportano l'incorporamento delle attività. Ad esempio, i dispositivi possono utilizzare il letterbox un'attività solo verticale sui display orizzontali per orientare l'attività per la transizione a un layout a due riquadri quando inizia una seconda attività (consulta la sezione Orientamento verticale fisso).
Configurazione XML
Per creare un'implementazione basata su XML dell'incorporamento dell'attività, procedi nel seguente modo:
Crea un file di risorsa XML che esegua le seguenti operazioni:
- Definisce le attività che condividono una suddivisione
- Configura le opzioni di suddivisione
- Crea un segnaposto per il contenitore secondario della suddivisione quando il contenuto non è disponibile
- Specifica le attività che non devono mai far parte di una suddivisione
Ecco alcuni esempi:
<!-- main_split_config.xml --> <resources xmlns:window="http://schemas.android.com/apk/res-auto"> <!-- Define a split for the named activities. --> <SplitPairRule window:splitRatio="0.33" window:splitLayoutDirection="locale" window:splitMinWidthDp="840" window:splitMaxAspectRatioInPortrait="alwaysAllow" window:finishPrimaryWithSecondary="never" window:finishSecondaryWithPrimary="always" window:clearTop="false"> <SplitPairFilter window:primaryActivityName=".ListActivity" window:secondaryActivityName=".DetailActivity"/> </SplitPairRule> <!-- Specify a placeholder for the secondary container when content is not available. --> <SplitPlaceholderRule window:placeholderActivityName=".PlaceholderActivity" window:splitRatio="0.33" window:splitLayoutDirection="locale" window:splitMinWidthDp="840" window:splitMaxAspectRatioInPortrait="alwaysAllow" window:stickyPlaceholder="false"> <ActivityFilter window:activityName=".ListActivity"/> </SplitPlaceholderRule> <!-- Define activities that should never be part of a split. Note: Takes precedence over other split rules for the activity named in the rule. --> <ActivityRule window:alwaysExpand="true"> <ActivityFilter window:activityName=".ExpandedActivity"/> </ActivityRule> </resources>
Crea un inizializzatore.
Il componente WindowManager
RuleController
analizza il file di configurazione XML e rende disponibili le regole al sistema. Una libreria Jetpack StartupInitializer
rende il file XML disponibile perRuleController
all'avvio dell'app, in modo che le regole siano applicate all'avvio di un'attività.Per creare un inizializzatore, segui questi passaggi:
Aggiungi la dipendenza più recente della libreria Jetpack Startup al file
build.gradle
a livello di modulo, ad esempio:implementation 'androidx.startup:startup-runtime:1.1.1'
Crea una classe che implementi l'interfaccia
Initializer
.L'inizializzazione rende disponibili le regole di suddivisione per
RuleController
passando l'ID del file di configurazione XML (main_split_config.xml
) al metodoRuleController.parseRules()
.Kotlin
class SplitInitializer : Initializer<RuleController> { override fun create(context: Context): RuleController { return RuleController.getInstance(context).apply { setRules(RuleController.parseRules(context, R.xml.main_split_config)) } } override fun dependencies(): List<Class<out Initializer<*>>> { return emptyList() } }
Java
public class SplitInitializer implements Initializer<RuleController> { @NonNull @Override public RuleController create(@NonNull Context context) { RuleController ruleController = RuleController.getInstance(context); ruleController.setRules( RuleController.parseRules(context, R.xml.main_split_config) ); return ruleController; } @NonNull @Override public List<Class<? extends Initializer<?>>> dependencies() { return Collections.emptyList(); } }
Crea un fornitore di contenuti per le definizioni delle regole.
Aggiungi
androidx.startup.InitializationProvider
al file manifest dell'app come<provider>
. Includi un riferimento all'implementazione dell'inizializzazioneRuleController
,SplitInitializer
:<!-- AndroidManifest.xml --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <!-- Make SplitInitializer discoverable by InitializationProvider. --> <meta-data android:name="${applicationId}.SplitInitializer" android:value="androidx.startup" /> </provider>
InitializationProvider
rileva e inizializzaSplitInitializer
prima di chiamare il metodoonCreate()
dell'app. Di conseguenza, le regole di suddivisione vengono applicate all'inizio dell'attività principale dell'app.
API WindowManager
Puoi implementare l'incorporamento delle attività in modo programmatico con una manciata di chiamate API. Effettua le chiamate nel metodo onCreate()
di una sottoclasse di Application
per assicurarti che le regole vengano applicate prima del lancio di qualsiasi attività.
Per creare una suddivisione attività in modo programmatico:
Crea una regola di suddivisione:
Crea una
SplitPairFilter
che identifichi le attività che condividono la suddivisione:Kotlin
val splitPairFilter = SplitPairFilter( ComponentName(this, ListActivity::class.java), ComponentName(this, DetailActivity::class.java), null )
Java
SplitPairFilter splitPairFilter = new SplitPairFilter( new ComponentName(this, ListActivity.class), new ComponentName(this, DetailActivity.class), null );
Per aggiungere il filtro a un insieme di filtri, procedi nel seguente modo:
Kotlin
val filterSet = setOf(splitPairFilter)
Java
Set<SplitPairFilter> filterSet = new HashSet<>(); filterSet.add(splitPairFilter);
Crea attributi di layout per la suddivisione:
Kotlin
val splitAttributes: SplitAttributes = SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build()
Java
final SplitAttributes splitAttributes = new SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build();
SplitAttributes.Builder
crea un oggetto contenente attributi di layout:setSplitType
: definisce la modalità di allocazione dell'area di visualizzazione disponibile a ciascun contenitore delle attività. Il tipo di suddivisione rapporto specifica la proporzione dell'area di visualizzazione disponibile allocata al contenitore principale; il contenitore secondario occupa la parte rimanente dell'area di visualizzazione disponibile.setLayoutDirection
: specifica la disposizione dei contenitori delle attività l'uno rispetto all'altro, a partire dal contenitore principale.
Crea una
SplitPairRule
:Kotlin
val splitPairRule = SplitPairRule.Builder(filterSet) .setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER) .setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS) .setClearTop(false) .build()
Java
SplitPairRule splitPairRule = new SplitPairRule.Builder(filterSet) .setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER) .setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS) .setClearTop(false) .build();
SplitPairRule.Builder
crea e configura la regola:filterSet
: contiene filtri a coppie divise che determinano quando applicare la regola identificando le attività che condividono una suddivisione.setDefaultSplitAttributes
: applica gli attributi di layout alla regola.setMinWidthDp
: consente di impostare la larghezza minima della visualizzazione (in pixel indipendenti dalla densità, dp) che consente una suddivisione.setMinSmallestWidthDp
: imposta il valore minimo (in dp) che la dimensione più piccola delle due dimensioni di visualizzazione deve avere per attivare una suddivisione indipendentemente dall'orientamento del dispositivo.setMaxAspectRatioInPortrait
: imposta le proporzioni massime della visualizzazione (altezza:larghezza) con orientamento verticale per il quale vengono visualizzate le suddivisioni delle attività. Se le proporzioni di una visualizzazione verticale superano quelle massime, le divisioni vengono disattivate indipendentemente dalla larghezza del display. Nota:il valore predefinito è 1, 4 e indica che le attività occupano l'intera finestra delle attività con orientamento verticale sulla maggior parte dei tablet. Vedi ancheSPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT
esetMaxAspectRatioInLandscape
. Il valore predefinito per l'orientamento orizzontale èALWAYS_ALLOW
.setFinishPrimaryWithSecondary
: imposta in che modo il completamento di tutte le attività nel contenitore secondario influisce sulle attività nel contenitore principale.NEVER
indica che il sistema non deve terminare le attività principali quando tutte le attività nel contenitore secondario sono terminate (consulta la sezione Terminare le attività).setFinishSecondaryWithPrimary
: consente di impostare in che modo il completamento di tutte le attività nel contenitore principale influisce sulle attività nel contenitore secondario.ALWAYS
indica che il sistema deve sempre terminare le attività nel contenitore secondario quando vengono terminate tutte le attività nel contenitore principale (consulta Terminare le attività).setClearTop
: specifica se tutte le attività nel contenitore secondario sono terminate quando viene avviata una nuova attività nel contenitore. False specifica che le nuove attività vengono sovrapposte a quelle già presenti nel contenitore secondario.
Recupera l'istanza singleton di WindowManager
RuleController
e aggiungi la regola:Kotlin
val ruleController = RuleController.getInstance(this) ruleController.addRule(splitPairRule)
Java
RuleController ruleController = RuleController.getInstance(this); ruleController.addRule(splitPairRule);
Crea un segnaposto per il contenitore secondario quando i contenuti non sono disponibili:
Crea una
ActivityFilter
che identifichi l'attività con cui il segnaposto condivide una suddivisione della finestra delle attività:Kotlin
val placeholderActivityFilter = ActivityFilter( ComponentName(this, ListActivity::class.java), null )
Java
ActivityFilter placeholderActivityFilter = new ActivityFilter( new ComponentName(this, ListActivity.class), null );
Per aggiungere il filtro a un insieme di filtri, procedi nel seguente modo:
Kotlin
val placeholderActivityFilterSet = setOf(placeholderActivityFilter)
Java
Set<ActivityFilter> placeholderActivityFilterSet = new HashSet<>(); placeholderActivityFilterSet.add(placeholderActivityFilter);
Crea una
SplitPlaceholderRule
:Kotlin
val splitPlaceholderRule = SplitPlaceholderRule.Builder( placeholderActivityFilterSet, Intent(context, PlaceholderActivity::class.java) ).setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS) .setSticky(false) .build()
Java
SplitPlaceholderRule splitPlaceholderRule = new SplitPlaceholderRule.Builder( placeholderActivityFilterSet, new Intent(context, PlaceholderActivity.class) ).setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS) .setSticky(false) .build();
SplitPlaceholderRule.Builder
crea e configura la regola:placeholderActivityFilterSet
: contiene filtri di attività che determinano quando applicare la regola identificando le attività a cui è associata l'attività segnaposto.Intent
: specifica l'avvio dell'attività segnaposto.setDefaultSplitAttributes
: applica gli attributi di layout alla regola.setMinWidthDp
: imposta la larghezza minima della visualizzazione (in pixel indipendenti dalla densità, dp) che consente una suddivisione.setMinSmallestWidthDp
: consente di impostare il valore minimo (in dp) che la dimensione più piccola delle due dimensioni di visualizzazione deve avere per consentire una suddivisione indipendentemente dall'orientamento del dispositivo.setMaxAspectRatioInPortrait
: imposta le proporzioni massime della visualizzazione (altezza:larghezza) con orientamento verticale per il quale vengono visualizzate le suddivisioni delle attività. Nota:il valore predefinito è 1, 4 e indica che le attività riempiono la finestra delle attività con l'orientamento verticale sulla maggior parte dei tablet. Vedi ancheSPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT
esetMaxAspectRatioInLandscape
. Il valore predefinito per l'orientamento orizzontale èALWAYS_ALLOW
.setFinishPrimaryWithPlaceholder
: consente di impostare in che modo il completamento dell'attività segnaposto influisce sulle attività nel contenitore principale. SEMPRE indica che il sistema deve sempre completare le attività nel contenitore principale al termine del segnaposto (consulta Terminare le attività).setSticky
: determina se l'attività segnaposto viene visualizzata sopra l'elenco attività su display piccoli dopo la prima visualizzazione del segnaposto in una suddivisione con larghezza minima sufficiente.
Aggiungi la regola a WindowManager
RuleController
:Kotlin
ruleController.addRule(splitPlaceholderRule)
Java
ruleController.addRule(splitPlaceholderRule);
Specifica le attività che non devono mai far parte di una suddivisione:
Crea un
ActivityFilter
che identifichi un'attività che deve sempre occupare l'intera area di visualizzazione dell'attività:Kotlin
val expandedActivityFilter = ActivityFilter( ComponentName(this, ExpandedActivity::class.java), null )
Java
ActivityFilter expandedActivityFilter = new ActivityFilter( new ComponentName(this, ExpandedActivity.class), null );
Per aggiungere il filtro a un insieme di filtri, procedi nel seguente modo:
Kotlin
val expandedActivityFilterSet = setOf(expandedActivityFilter)
Java
Set<ActivityFilter> expandedActivityFilterSet = new HashSet<>(); expandedActivityFilterSet.add(expandedActivityFilter);
Crea una
ActivityRule
:Kotlin
val activityRule = ActivityRule.Builder(expandedActivityFilterSet) .setAlwaysExpand(true) .build()
Java
ActivityRule activityRule = new ActivityRule.Builder( expandedActivityFilterSet ).setAlwaysExpand(true) .build();
ActivityRule.Builder
crea e configura la regola:expandedActivityFilterSet
: contiene filtri di attività che determinano quando applicare la regola identificando le attività da escludere dalle suddivisioni.setAlwaysExpand
: specifica se l'attività deve riempire l'intera finestra dell'attività.
Aggiungi la regola a WindowManager
RuleController
:Kotlin
ruleController.addRule(activityRule)
Java
ruleController.addRule(activityRule);
Incorporamento tra applicazioni
Su Android 13 (livello API 33) e versioni successive, le app possono incorporare le attività di altre app. L'incorporamento delle attività per più applicazioni o UID consente l'integrazione visiva delle attività di più app per Android. Il sistema mostra sullo schermo un'attività dell'app host e un'attività incorporata di un'altra app affiancate o in alto e in basso, proprio come per l'incorporamento dell'attività in una singola app.
Ad esempio, l'app Impostazioni potrebbe incorporare l'attività di selezione dello sfondo dall'app BackgroundChooseer:
Modello di attendibilità
I processi di hosting che incorporano attività da altre app sono in grado di ridefinire la presentazione delle attività incorporate, inclusi dimensioni, posizione, ritaglio e trasparenza. Gli host dannosi possono sfruttare questa capacità per ingannare gli utenti e creare clickjacking o altri attacchi di correzione dell'interfaccia utente.
Per impedire l'uso improprio dell'incorporamento delle attività tra app, Android richiede che le app siano attivate per consentire l'incorporamento delle loro attività. Le app possono designare gli host come attendibili o non attendibili.
Host attendibili
Per consentire ad altre applicazioni di incorporare e controllare completamente la presentazione delle attività della tua app, specifica il certificato SHA-256 dell'applicazione host nell'attributo android:knownActivityEmbeddingCerts
degli elementi <activity>
o <application>
del file manifest dell'app.
Imposta il valore di android:knownActivityEmbeddingCerts
come stringa:
<activity
android:name=".MyEmbeddableActivity"
android:knownActivityEmbeddingCerts="@string/known_host_certificate_digest"
... />
oppure, per specificare più certificati, un array di stringhe:
<activity
android:name=".MyEmbeddableActivity"
android:knownActivityEmbeddingCerts="@array/known_host_certificate_digests"
... />
che fa riferimento a una risorsa come la seguente:
<resources>
<string-array name="known_host_certificate_digests">
<item>cert1</item>
<item>cert2</item>
...
</string-array>
</resources>
I proprietari delle app possono ottenere una sintesi del certificato SHA eseguendo l'attività signingReport
Gradle. Il digest del certificato è l'impronta SHA-256 senza i due punti di separazione. Per maggiori informazioni, vedi Eseguire un report sulla firma e Autenticazione del client.
Host non attendibili
Per consentire a un'app di incorporare le attività dell'app e controllarne la presentazione, specifica l'attributo android:allowUntrustedActivityEmbedding
negli elementi <activity>
o <application>
del file manifest dell'app, ad esempio:
<activity
android:name=".MyEmbeddableActivity"
android:allowUntrustedActivityEmbedding="true"
... />
Il valore predefinito dell'attributo è false, che impedisce l'incorporamento dell'attività tra app.
Autenticazione personalizzata
Per ridurre i rischi di incorporamento di attività non attendibili, crea un meccanismo di autenticazione personalizzato che verifichi l'identità dell'host. Se conosci i certificati host, utilizza la libreria androidx.security.app.authenticator
per l'autenticazione. Se l'host si autentica dopo aver incorporato la tua attività, puoi visualizzare i contenuti effettivi. In caso contrario, puoi informare l'utente che l'azione non è stata consentita e bloccare i contenuti.
Utilizza il metodo ActivityEmbeddingController#isActivityEmbedded()
della libreria Jetpack WindowManager per verificare se un host sta incorporando la tua attività, ad esempio:
Kotlin
fun isActivityEmbedded(activity: Activity): Boolean { return ActivityEmbeddingController.getInstance(this).isActivityEmbedded(activity) }
Java
boolean isActivityEmbedded(Activity activity) { return ActivityEmbeddingController.getInstance(this).isActivityEmbedded(activity); }
Limitazione delle dimensioni minime
Il sistema Android applica alle attività incorporate l'altezza e la larghezza minime specificate nell'elemento <layout>
del file manifest dell'app. Se un'applicazione non specifica l'altezza e la larghezza minime, vengono applicati i valori predefiniti di sistema (sw220dp
).
Se l'host tenta di ridimensionare il contenitore incorporato a una dimensione inferiore al minimo, il contenitore incorporato si espande per occupare tutti i limiti delle attività.
<alias-attività>
Affinché l'incorporamento delle attività attendibili o non attendibili funzioni con l'elemento <activity-alias>
, è necessario applicare i android:knownActivityEmbeddingCerts
o android:allowUntrustedActivityEmbedding
all'attività di destinazione anziché all'alias. Il criterio che verifica la sicurezza sul server di sistema si basa sui flag impostati sulla destinazione, non sull'alias.
Applicazione host
Le applicazioni host implementano l'incorporamento dell'attività tra app nello stesso modo in cui implementano l'incorporamento dell'attività in app singola. Gli oggetti SplitPairRule
e SplitPairFilter
o ActivityRule
e ActivityFilter
specificano le attività incorporate e le suddivisioni della finestra delle attività. Le regole di suddivisione vengono definite staticamente in XML o in fase di runtime utilizzando le chiamate API Jetpack WindowManager.
Se un'applicazione host tenta di incorporare un'attività per la quale non è stato attivato l'incorporamento tra app, l'attività occupa tutti i limiti delle attività. Di conseguenza, le applicazioni host devono sapere se le attività di destinazione consentono l'incorporamento tra app.
Se un'attività incorporata avvia una nuova attività nella stessa attività e per la nuova attività non è stata attivata l'incorporamento tra app, l'attività occupa tutti i limiti dell'attività invece di sovrapporsi all'attività nel contenitore incorporato.
Un'applicazione host può incorporare le proprie attività senza restrizioni, purché le attività vengano avviate nella stessa attività.
Esempi di suddivisione
Dividi dalla finestra intera
Non è necessario eseguire il refactoring. Puoi definire la configurazione per la suddivisione
in modo statico o in fase di runtime e poi chiamare
Context#startActivity()
senza parametri aggiuntivi.
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Suddividi per impostazione predefinita
Se la pagina di destinazione di un'applicazione è progettata per essere suddivisa in due container su schermi di grandi dimensioni, l'esperienza utente è ottimale quando entrambe le attività vengono create e presentate contemporaneamente. Tuttavia, i contenuti potrebbero non essere disponibili per il contenitore secondario della suddivisione finché l'utente non interagisce con l'attività nel contenitore principale (ad esempio, l'utente seleziona un elemento da un menu di navigazione). Un'attività segnaposto può riempire il vuoto fino a quando i contenuti non possono essere visualizzati nel contenitore secondario della suddivisione (consulta la sezione Segnaposto sopra).
Per creare una suddivisione con un segnaposto, crea un segnaposto e associalo all'attività principale:
<SplitPlaceholderRule
window:placeholderActivityName=".PlaceholderActivity">
<ActivityFilter
window:activityName=".MainActivity"/>
</SplitPlaceholderRule>
Suddivisione link diretti
Quando un'app riceve un intent, l'attività target può essere mostrata come parte secondaria di una suddivisione attività; ad esempio, una richiesta di mostrare una schermata dei dettagli con informazioni su un elemento di un elenco. Sui display piccoli, il dettaglio viene mostrato nell'intera finestra delle attività; sui dispositivi più grandi, accanto all'elenco.
La richiesta di lancio deve essere indirizzata all'attività principale e l'attività di dettaglio della destinazione deve essere lanciata in una suddivisione. Il sistema sceglie automaticamente la presentazione corretta, in pila o affiancata, in base alla larghezza di visualizzazione disponibile.
Kotlin
override fun onCreate(savedInstanceState Bundle?) { . . . RuleController.getInstance(this) .addRule(SplitPairRule.Builder(filterSet).build()) startActivity(Intent(this, DetailActivity::class.java)) }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { . . . RuleController.getInstance(this) .addRule(new SplitPairRule.Builder(filterSet).build()); startActivity(new Intent(this, DetailActivity.class)); }
La destinazione del link diretto potrebbe essere l'unica attività che dovrebbe essere disponibile per l'utente nello stack di navigazione posteriore e potresti voler evitare di ignorare l'attività dei dettagli e lasciare solo l'attività principale:
Puoi invece completare entrambe le attività contemporaneamente utilizzando l'attributo finishPrimaryWithSecondary
:
<SplitPairRule
window:finishPrimaryWithSecondary="always">
<SplitPairFilter
window:primaryActivityName=".ListActivity"
window:secondaryActivityName=".DetailActivity"/>
</SplitPairRule>
Consulta la sezione Attributi di configurazione di seguito.
Più attività in contenitori suddivisi
L'impilamento di più attività in un container suddiviso consente agli utenti di accedere a contenuti dettagliati. Ad esempio, con una suddivisione dei dettagli elenco, l'utente potrebbe dover accedere a una sezione dei dettagli secondari, ma mantenere attiva l'attività principale:
Kotlin
class DetailActivity { . . . fun onOpenSubDetail() { startActivity(Intent(this, SubDetailActivity::class.java)) } }
Java
public class DetailActivity { . . . void onOpenSubDetail() { startActivity(new Intent(this, SubDetailActivity.class)); } }
L'attività dei dettagli secondari viene posizionata sopra l'attività dei dettagli, nascondendola:
L'utente può quindi tornare al livello di dettaglio precedente accedendo allo stack:
Il comportamento predefinito quando le attività vengono avviate da un'attività nello stesso contenitore secondario è l'impilamento delle attività una sopra l'altra. Anche le attività avviate dal container principale all'interno di una suddivisione attiva finiscono nel container secondario in cima allo stack delle attività.
Attività in una nuova attività
Quando le attività in una finestra di attività divisa ne avviano una in una nuova, la nuova attività è separata dall'attività che include la suddivisione e viene visualizzata a schermo intero. La schermata Recenti mostra due attività: l'attività nella suddivisione e la nuova attività.
Sostituzione attività
Le attività possono essere sostituite nello stack di container secondari, ad esempio quando l'attività principale viene utilizzata per la navigazione di primo livello e l'attività secondaria è una destinazione selezionata. Ogni selezione dalla navigazione di livello superiore deve avviare una nuova attività nel contenitore secondario e rimuovere l'attività o le attività che erano presenti in precedenza.
Se l'app non termina l'attività nel contenitore secondario quando cambia la selezione della navigazione, la navigazione a ritroso potrebbe creare confusione quando la suddivisione è compressa (quando il dispositivo è chiuso). Ad esempio, se è presente un menu nel riquadro principale e le schermate A e B impilate nel riquadro secondario, quando l'utente chiude lo smartphone, B si trova sopra A e A è in cima al menu. Quando l'utente torna indietro da B, al posto del menu compare A.
In questi casi, la schermata A deve essere rimossa dallo stack posteriore.
Il comportamento predefinito quando esegui l'avvio laterale di un nuovo container su una suddivisione esistente prevede l'inserimento dei nuovi container secondari in primo piano e la conservazione di quelli precedenti nello stack precedente. Puoi configurare le suddivisioni in modo da cancellare i container secondari precedenti con clearTop
e avviare nuove attività normalmente.
<SplitPairRule
window:clearTop="true">
<SplitPairFilter
window:primaryActivityName=".Menu"
window:secondaryActivityName=".ScreenA"/>
<SplitPairFilter
window:primaryActivityName=".Menu"
window:secondaryActivityName=".ScreenB"/>
</SplitPairRule>
Kotlin
class MenuActivity { . . . fun onMenuItemSelected(selectedMenuItem: Int) { startActivity(Intent(this, classForItem(selectedMenuItem))) } }
Java
public class MenuActivity { . . . void onMenuItemSelected(int selectedMenuItem) { startActivity(new Intent(this, classForItem(selectedMenuItem))); } }
In alternativa, utilizza la stessa attività secondaria e, dall'attività principale (menu), invia nuovi intent che si risolvono nella stessa istanza, ma attivano un aggiornamento di stato o UI nel container secondario.
Più suddivisioni
Le app possono offrire una navigazione approfondita multilivello avviando attività aggiuntive a lato.
Quando un'attività in un contenitore secondario avvia una nuova attività laterale, viene creata una nuova suddivisione sopra quella esistente.
Lo stack posteriore contiene tutte le attività aperte in precedenza, pertanto gli utenti possono passare alla suddivisione A/B dopo aver terminato C.
Per creare una nuova suddivisione, avvia la nuova attività sul lato dal contenitore secondario esistente. Dichiara le configurazioni sia per le sezioni A/B che per quelle B/C e per l'attività di lancio C normalmente da B:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
<SplitPairFilter
window:primaryActivityName=".B"
window:secondaryActivityName=".C"/>
</SplitPairRule>
Kotlin
class B { . . . fun onOpenC() { startActivity(Intent(this, C::class.java)) } }
Java
public class B { . . . void onOpenC() { startActivity(new Intent(this, C.class)); } }
Reagisci alle modifiche dello stato suddivise
Diverse attività in un'app possono avere elementi UI che svolgono la stessa funzione; ad esempio, un controllo che apre una finestra contenente le impostazioni dell'account.
Se due attività che hanno un elemento UI in comune si trovano in una suddivisione, mostrare l'elemento in entrambe le attività può essere ridondante e forse poco chiaro.
Per sapere quando le attività sono in una suddivisione, controlla il flusso SplitController.splitInfoList
o registra un listener con SplitControllerCallbackAdapter
per le modifiche allo stato di suddivisione. Quindi, modifica l'interfaccia utente di conseguenza:
Kotlin
val layout = layoutInflater.inflate(R.layout.activity_main, null) val view = layout.findViewById<View>(R.id.infoButton) lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { splitController.splitInfoList(this@SplitDeviceActivity) // The activity instance. .collect { list -> view.visibility = if (list.isEmpty()) View.VISIBLE else View.GONE } } }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { . . . new SplitControllerCallbackAdapter(SplitController.getInstance(this)) .addSplitListener( this, Runnable::run, splitInfoList -> { View layout = getLayoutInflater().inflate(R.layout.activity_main, null); layout.findViewById(R.id.infoButton).setVisibility( splitInfoList.isEmpty() ? View.VISIBLE : View.GONE); }); }
Le coroutine possono essere lanciate in qualsiasi stato del ciclo di vita, ma in genere vengono lanciate nello stato STARTED
per risparmiare risorse. Per saperne di più, consulta Utilizzare coroutine Kotlin con componenti sensibili al ciclo di vita.
I callback possono essere effettuati in qualsiasi stato del ciclo di vita, anche quando un'attività viene arrestata. Generalmente i listener devono essere registrati nel dominio onStart()
e non registrati in onStop()
.
modale a finestra intera
Alcune attività impediscono agli utenti di interagire con l'applicazione finché non viene eseguita un'azione specificata; ad esempio, un'attività della schermata di accesso, una schermata di conferma dei criteri o un messaggio di errore. Le attività modali non dovrebbero essere visualizzate in una suddivisione.
È possibile forzare un'attività a riempire sempre la finestra dell'attività utilizzando la configurazione di espansione:
<ActivityRule
window:alwaysExpand="true">
<ActivityFilter
window:activityName=".FullWidthActivity"/>
</ActivityRule>
Termina attività
Gli utenti possono terminare le attività su entrambi i lati del segmento scorrendo dal bordo del display:
Se il dispositivo è configurato per utilizzare il pulsante Indietro anziché la navigazione tramite gesti, l'input viene inviato all'attività attiva, ovvero l'attività che è stata toccata o avviata per ultima.
L'effetto del completamento di tutte le attività in un contenitore sul contenitore avversario dipende dalla configurazione della suddivisione.
Attributi di configurazione
Puoi specificare gli attributi delle regole delle coppie divisali per configurare in che modo il completamento di tutte le attività su un lato della suddivisione influisce sulle attività sull'altro lato della suddivisione. Gli attributi sono:
window:finishPrimaryWithSecondary
: in che modo la fine di tutte le attività nel contenitore secondario influisce sulle attività nel contenitore principalewindow:finishSecondaryWithPrimary
: in che modo la fine di tutte le attività nel contenitore principale influisce sulle attività nel contenitore secondario
I valori possibili degli attributi includono:
always
: completa sempre le attività nel contenitore associatonever
: non completare mai le attività nel contenitore associatoadjacent
: completa le attività nel contenitore associato quando i due contenitori vengono visualizzati uno accanto all'altro, ma non quando sono impilati.
Ecco alcuni esempi:
<SplitPairRule
<!-- Do not finish primary container activities when all secondary container activities finish. -->
window:finishPrimaryWithSecondary="never"
<!-- Finish secondary container activities when all primary container activities finish. -->
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Configurazione predefinita
Quando tutte le attività in un contenitore di una fine intermedia, il contenitore rimanente occupa l'intera finestra:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Completare le attività insieme
Termina automaticamente le attività nel contenitore principale quando tutte le attività nel contenitore secondario sono terminate:
<SplitPairRule
window:finishPrimaryWithSecondary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Termina automaticamente le attività nel contenitore secondario quando tutte le attività nel contenitore principale sono terminate:
<SplitPairRule
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Completa le attività contemporaneamente quando tutte le attività nel contenitore principale o secondario sono terminate:
<SplitPairRule
window:finishPrimaryWithSecondary="always"
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Completa più attività nei container
Se più attività sono raggruppate in un contenitore diviso, il completamento di un'attività in fondo all'elenco non comporta il termine automatico delle attività nella parte superiore.
Ad esempio, se due attività si trovano nel contenitore secondario, C sopra B:
e la configurazione della suddivisione è definita dalla configurazione delle attività A e B:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
se completi l'attività principale, la suddivisione rimane invariata.
Il completamento dell'attività inferiore (principale) del container secondario non rimuove le attività al suo interno e, di conseguenza, conserva anche la suddivisione.
Vengono eseguite anche eventuali regole aggiuntive per completare contemporaneamente le attività, ad esempio terminare l'attività secondaria con quella principale:
<SplitPairRule
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
E quando la suddivisione è configurata per terminare insieme le attività principali e secondarie:
<SplitPairRule
window:finishPrimaryWithSecondary="always"
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Modifica delle proprietà di suddivisione in fase di runtime
Le proprietà di una suddivisione attualmente attiva e visibile non possono essere modificate. La modifica delle regole di suddivisione influisce sull'avvio di attività aggiuntive e sui nuovi container, ma non sulle suddivisioni esistenti e attive.
Per modificare le proprietà dei segmenti attivi, termina l'attività secondaria o le attività nel segmento e avvialo di nuovo a lato con una nuova configurazione.
Estrae un'attività da una suddivisione a finestra intera
Crea una nuova configurazione che mostri l'intera finestra dell'attività laterale, quindi riavvia l'attività con un intent che si risolve nella stessa istanza.
Verifica la presenza del supporto suddiviso in fase di runtime
L'incorporamento delle attività è supportato su Android 12L (livello API 32) e versioni successive, ma è disponibile anche su alcuni dispositivi con versioni precedenti della piattaforma. Per verificare la disponibilità della funzionalità in fase di runtime, utilizza la proprietà SplitController.splitSupportStatus
o il metodo SplitController.getSplitSupportStatus()
:
Kotlin
if (SplitController.getInstance(this).splitSupportStatus == SplitController.SplitSupportStatus.SPLIT_AVAILABLE) { // Device supports split activity features. }
Java
if (SplitController.getInstance(this).getSplitSupportStatus() == SplitController.SplitSupportStatus.SPLIT_AVAILABLE) { // Device supports split activity features. }
Se le suddivisioni non sono supportate, le attività vengono avviate sopra lo stack delle attività (seguendo il modello di incorporamento non delle attività).
Evita override del sistema
I produttori di dispositivi Android (produttori di apparecchiature originali o OEM) possono implementare l'incorporamento delle attività in funzione del sistema del dispositivo. Il sistema specifica regole di suddivisione per le app multiattività, che sostituiscono il comportamento delle finestre delle app. L'override del sistema forza le app multi-attività in una modalità di incorporamento di attività definita dal sistema.
L'incorporamento dell'attività di sistema può migliorare la presentazione dell'app tramite layout multi-riquadro, come list-detail, senza alcuna modifica all'app. Tuttavia, l'incorporamento dell'attività del sistema potrebbe causare anche layout dell'app errati, bug o conflitti con l'incorporamento delle attività implementato dall'app.
La tua app può impedire o consentire l'incorporamento dell'attività di sistema impostando una proprietà nel file manifest dell'app, ad esempio:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<property
android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE"
android:value="true|false" />
</application>
</manifest>
Il nome della proprietà è definito nell'oggetto WindowProperties
di Jetpack WindowManager.
Imposta il valore su false
se la tua app implementa l'incorporamento dell'attività o se vuoi impedire altrimenti al sistema di applicare le sue regole di incorporamento dell'attività alla tua app. Imposta il valore su true
per consentire al sistema di applicare l'incorporamento dell'attività definita dal sistema alla tua app.
Limitazioni, restrizioni e avvertenze
- Solo l'app host dell'attività, identificata come proprietaria dell'attività principale, può organizzare e incorporare altre attività nell'attività. Se le attività che supportano l'incorporamento e le suddivisioni vengono eseguite in un'attività che appartiene a un'altra applicazione, l'incorporamento e le suddivisioni non funzioneranno per queste attività.
- Le attività possono essere organizzate in una sola attività. L'avvio di un'attività in una nuova attività viene sempre collocata in una nuova finestra espansa al di fuori di eventuali suddivisioni esistenti.
- È possibile organizzare e suddividere solo le attività nello stesso processo. Il callback
SplitInfo
segnala solo le attività che appartengono allo stesso processo, poiché non è in alcun modo possibile conoscere le attività nei diversi processi. - Ogni coppia o regola di attività singola si applica solo agli avvii di attività successivi alla registrazione della regola. Al momento non è possibile aggiornare le suddivisioni esistenti o le relative proprietà visive.
- La configurazione del filtro a coppie divise deve corrispondere agli intent utilizzati quando avvii completamente le attività. La corrispondenza si verifica nel momento in cui viene avviata una nuova attività dal processo di applicazione, quindi potrebbe non conoscere i nomi dei componenti che vengono risolti in seguito durante il processo di sistema quando vengono utilizzati intent impliciti. Se il nome di un componente non è noto al momento del lancio, è possibile utilizzare un carattere jolly ("*/*") e applicare i filtri in base all'azione dell'intent.
- Al momento non è possibile spostare le attività tra container o all'interno e all'esterno delle suddivisioni dopo la creazione. Le suddivisioni vengono create dalla libreria WindowManager quando vengono avviate nuove attività con regole corrispondenti, mentre le suddivisioni vengono eliminate al termine dell'ultima attività in un container diviso.
- Le attività possono essere riavviate quando la configurazione cambia, quindi, quando viene creata o rimossa una suddivisione e i limiti delle attività cambiano, l'attività può essere completamente eliminata dall'istanza precedente e creata quella nuova. Di conseguenza, gli sviluppatori di app dovrebbero fare attenzione, ad esempio, al lancio di nuove attività dai callback del ciclo di vita.
- I dispositivi devono includere l'interfaccia delle estensioni finestra per supportare l'incorporamento delle attività. Quasi tutti i dispositivi con schermi di grandi dimensioni con Android 12L (livello API 32) o versioni successive includono l'interfaccia. Tuttavia, alcuni dispositivi con schermi di grandi dimensioni che non sono in grado di eseguire più attività non includono l'interfaccia delle estensioni finestra. Se un dispositivo con schermo grande non supporta la modalità multi-finestra, potrebbe non supportare l'incorporamento delle attività.
Risorse aggiuntive
- Codelab: crea un layout dei dettagli dell'elenco con incorporamento delle attività
- Percorso di apprendimento - Incorporamento delle attività