質問
API 25 から、Android に 3D Touch に似た機能、つまりデスクトップ アイコンを長押ししてショートカット メニュー (最大 4 つ) がポップアップ表示される機能が追加されたことは誰もが知っています。初期の国内システムのデスクトップランチャーはこの機能に積極的に対応していなかったので、主要なアプリケーションはあまりにも怠惰で、後に徐々に改善されました。現在、WeChat、Alipay などを含め、長押しするとショートカットがポップアップ表示され、Alipay は動的構成をサポートしています。
公式の開発ドキュメントを参照してください: https://developer.android.com/guide/topics/ui/shortcuts、静的ショートカットの適応は非常に簡単で、xml ファイルを追加するだけで完了するため、ここでは説明しません。ここで詳細を説明します。
しかし、実際のエクスペリエンス開発プロセスでは、ショートカットを通じてアプリケーションの対応するページを開いた後、他のアクティビティが破棄されることがわかります。これは私たちが望んでいる効果ではありません。
簡易分析
この現象は、アクティビティの開始時にCLEAR_TASKフラグを設定してタスク スタックをクリアする場合と非常によく似ています。ただし、次の使用例から判断すると、静的ショートカットはインテントのフラグを設定できず、関連するロジックはシステム SDK によって内部的に実装されます。
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="compose"
android:enabled="true"
android:icon="@drawable/compose_icon"
android:shortcutShortLabel="@string/compose_shortcut_short_label1"
android:shortcutLongLabel="@string/compose_shortcut_long_label1"
android:shortcutDisabledMessage="@string/compose_disabled_message1">
<!-- 例1 -->
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.example.myapplication"
android:targetClass="com.example.myapplication.ComposeActivity" />
<!-- 例2 -->
<intent
android:action="android.intent.action.VIEW"
android:data="xxx://xxx/xxx" />
</shortcut>
<!-- Specify more shortcuts here. -->
</shortcuts>
その後、公式文書に次のような文章を見つけました。
静的ショートカットにはカスタム インテント タグを含めることはできません。静的ショートカットの最初のインテントには、常に Intent.FLAG_ACTIVITY_NEW_TASK と Intent.FLAG_ACTIVITY_CLEAR_TASK が設定されています。これは、アプリがすでに実行されている場合、静的ショートカットが開始されると、アプリ内のすべての既存のアクティビティが破棄されることを意味します。この動作を望まない場合は、トランポリン アクティビティを使用できます...
解決する
この Trampoline は、ターゲットのアクティビティを配布して開始するためのスプリングボード アクティビティをセットアップすることを意味し、このスプリングボード アクティビティとアプリケーションの他のアクティビティを同じスタックに含めないようにする必要があります。非常に簡単で、プロパティを設定するだけですtaskAffinity
。
<!-- AndroidManifest.xml -->
<activity
android:name=".TrampolineActivity"
android:taskAffinity="" />
<!-- xml/shortcuts.xml -->
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.example.myapplication"
android:targetClass="com.example.myapplication.TrampolineActivity" />
taskAffinityの設定は表示されず、デフォルト値はパッケージ名となっているので、スプリングボードActivityにはパッケージ名以外の文字列を設定するだけです。これにより、デスクトップ上のショートカットを長押ししてアプリケーションを開いた際に、他のページが破壊されることがなくなります。