IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android静态Shortcuts启动模式问题 -> 正文阅读

[移动开发]Android静态Shortcuts启动模式问题

? ? 最近开发个快捷启动某个功能的需求,需要用到安卓的Shortcuts,其中遇到个启动模式的坑,这里记录一下。

? ? 首先,Google提供的快捷方式有三种(详情见官方文档):

1. 静态快捷方式:7.1开始支持,在Manifest的Launcher Activity中注册;

2. 动态快捷方式:7.1开始支持,通过ShortcutManager动态添加、移除或更新;

3. 固定快捷方式:8.0开始支持,在启动器中显示为单独的图标,通过ShortcutManager申请添加。

? ?这里要讲的是静态快捷方式,静态快捷方式在xml下的xxx.xml文件中定义Intent,但是其启动模式(Intent Flag)是由系统自定义的,官方文档这一段话非常重要:

? ? 也就是说,系统启动我们在xxx.xml中定义的Activity时,会自动加上FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK标记,这样会导致一个问题:应用在运行时,此时启动快捷方式,会将应用的任务栈(特别是MainActivity)给清除掉,然后启动我们的快捷方式Acitivity。关于这两个Flag的介绍,我给贴一下,特别注意其中标红的部分:

FLAG_ACTIVITY_NEW_TASK

If set, this activity will become the start of a new task on this history stack. A task (from the activity that started it to the next task activity) defines an atomic group of activities that the user can move to. Tasks can be moved to the foreground and background; all of the activities inside of a particular task always remain in the same order. See?Tasks and Back Stack?for more information about tasks.

This flag is generally used by activities that want to present a "launcher" style behavior: they give the user a list of separate things that can be done, which otherwise run completely independently of the activity launching them.

When using this flag, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in. See?FLAG_ACTIVITY_MULTIPLE_TASK?for a flag to disable this behavior.

This flag can not be used when the caller is requesting a result from the activity being launched.

FLAG_ACTIVITY_CLEAR_TASK

If set in an Intent passed to?Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started. That is, the activity becomes the new root of an otherwise empty task, and any old activities are finished. This can only be used in conjunction with?FLAG_ACTIVITY_NEW_TASK.

? ? 一般情况下,这样处理也没多大问题,但是在有些情况下,MainActivity的启动是非常耗时的,将MainActivity给finish掉是难以接受的,那这种情况要怎么处理呢?

? ?其实官方已经给了一个思路,就是将快捷方式定义的Activity作为一个跳板,其taskAffinity定义为""(taskAffinity的缺省值是应用的包名,也就是将其启动在非缺省的任务栈),然后在这个跳板Activity(A)中启动要真正启动的Acitivity(B),示例代码如下所示:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate " + getTaskId() + " " + hashCode());

        Intent intent = new Intent(this, ShortcutMainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        overridePendingTransition(0, 0);
        finish();
    }

? ?注意A启动B的启动模式,由于A启动后处于taskAffinity=""的任务栈,而B需要回到主任务栈,所以需要标记FLAG_ACTIVITY_NEW_TASK,至于是否需要标记FLAG_ACTIVITY_CLEAR_TOP,则根据自己的需要。

FLAG_ACTIVITY_CLEAR_TOP

If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.

For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.

The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. If it has declared its launch mode to be "multiple" (the default) and you have not set?FLAG_ACTIVITY_SINGLE_TOP?in the same intent, then it will be finished and re-created; for all other launch modes or if?FLAG_ACTIVITY_SINGLE_TOP?is set then this Intent will be delivered to the current instance's onNewIntent().

This launch mode can also be used to good effect in conjunction with?FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task, it will bring any currently running instance of that task to the foreground, and then clear it to its root state. This is especially useful, for example, when launching an activity from the notification manager.

? ?注:上面的解决方案似乎并不复杂,但由于业务的复杂性(SDK开发受到诸多限制,Launcher Activity动不得,MainAcitivity动不得,还受到SDK的初始化问题的限制(核心SDK(仍然是动不得)设计问题,不能重复初始化...,甚至不能重复调用初始化接口)),再加上对不同任务栈的切换和Acitivity的启动模式的了解并不全面,这其间走了一些弯路,所以这里记录一下,共勉。

参考资料:

创建快捷方式 ?|? Android 开发者 ?|? Android Developers

Android7.1Shortcuts - 老弟,来啦? - OSCHINA - 中文开源技术交流社区

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-06 15:23:13  更:2021-12-06 15:23:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:03:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码