使用深层链接导航 | MAD Skills

使用深层链接导航 | MAD Skills
www.zeeklog.com  - 使用深层链接导航 | MAD Skills

这是一个新的系列文章,我们称之为 “Modern Android Development 技巧”,简称为 “MAD Skills”。本系列文章致力于帮助开发者们打造更好的现代 Android 开发体验,敬请关注。

今天为大家发布本系列文章中的第四篇: 使用深层链接 (Deep Links) 导航。如果您想回顾过去发布的内容,请参考下面链接查看:

介绍

这篇文章的内容是关于  的,导航 (Navigation) 组件提供了该功能以帮助用户从应用的外部到达应用的深层页面。

有时您会想让用户更便捷地到达应用流程中指定的页面,而不必从初始页一直不断地点击来跳转到那个页面。比如在聊天应用中直接显示正在进行的对话详情页,再比如购物应用中用户的购物车详情页。您可以使用深层链接来实现上述需求,通过点击类似快捷方式和通知等应用的外部链接来到达您应用的深层页面。

导航组件简化了这些深层链接的创建步骤。为了展示其工作原理,我们将再次回顾我在  中使用的甜甜圈记录应用。该应用的  发布在 Github 上,请下载并使用 Android Studio 打开。

代码已经完成,所以我将会逐步解释如何利用导航组件来实现深层链接。

甜甜圈深层链接

在甜甜圈记录应用中,有几个操作如果能快速到达会非常方便。比如我突然发现一个非常不错的甜甜圈,并希望能快速地将其信息记录到列表中,但是我并不想启动应用,再点击 FloatingActionButton 按钮来弹出数据输入对话框。再比如我正在新增或者编辑一个甜甜圈的信息,希望应用能够发送一个通知,这样我就能快速地编辑最近的这个条目。

我为这两个操作都添加了深层链接,一个是为了添加新的甜甜圈,而另一个是为了返回正在编辑的条目。这个 “新增” 操作使用的是 “隐式” 深层链接,***隐式***意味着这个深层链接会带用户到您应用层次结构中的一个固定页面,这个位置也不会随着时间而改变。在我的应用中,该隐式深层链接会一直带您到允许在列表中添加新甜甜圈的表单页。

“继续编辑” 操作使用的是 “显式” 深层链接,显式的意思是我们调用这个深层链接可以带用户到您应用中的一个动态页面。

创建隐式深层链接

我们来先创建新增甜甜圈表单页的隐式深层链接。

首先,我需要使用导航编辑器来创建这个深层链接。点击对话框目的地可以在右边显示这个目的地页面的属性:

www.zeeklog.com  - 使用深层链接导航 | MAD Skills
点击目的地可以显示其属性,我们可以在属性栏中创建一个新的深层链接来导航到这个目的地

点击 Deep Links (深层链接) 旁边的 + 来打开一个对话框,在这个对话框中,我输入了一个 URI (Universal Resource Identifier)。这里我们需要一个应用特有的 URI (而不能是一个通用的 web 地址,不然它会触发浏览器应用),所以我使用了我们应用特有的 “myapp” 作为标识符:

www.zeeklog.com  - 使用深层链接导航 | MAD Skills
创建一个新的深层链接会打开一个对话框,您可以在这输入一个跳转到该目的地的深层链接 URI

接下来,我通过编辑应用的 manifest 文件来通知应用为深层链接创建一个快捷方式:

<activity
    android:name="com.android.samples.donuttracker.MainActivity"
    android:label="@string/app_name"
    android:theme="@style/AppTheme.NoActionBar">
  <nav-graph android:value="@navigation/nav_graph" />
   <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
   <meta-data android:name="android.app.shortcuts"
        android:resource="@xml/shortcuts" />
</activity>

在 meta-data 代码块中,我告诉 activity 关于该深层链接在导航图中的信息。同时我也引用了一个 xml 资源文件夹中的新文件,这个文件包含了到达该 activity 应用快捷方式的信息。

然后我又创建了 xml 文件夹,并且在其中新创建了一个 shortcuts.xml 文件。在这个快捷方式文件中,我输入了关于这个应用快捷方式的信息,包括上面我们看到的 URI:

<shortcuts
    xmlns:android="http://schemas.android.com/apk/res/android">
  <shortcut
    android:shortcutId="NewDonutDialogFragment"
    android:enabled="true"
    android:shortcutShortLabel="@string/static_shortcut_label_short"
    android:shortcutLongLabel="@string/static_shortcut_label_long"
    android:shortcutDisabledMessage=
        "@string/static_shortcut_disabled_message"
    android:icon="@drawable/donut_with_sprinkles">
    <intent
       android:action="android.intent.action.VIEW"
      android:data="myapp://navdonutcreator.com/donutcreator" />
 </shortcut>
</shortcuts>

最重要的部分是 data 字段,它的值是在之前导航工具深层链接对话框中输入的 URI,这也是从应用快捷方式导航到对话框目的地的纽带。

以上内容就是创建一个隐式深层链接所需的操作,我声明了要导航的目的地,并且创建了一个快捷方式来实现导航。如果运行这个应用并长按这个应用的图标,您会看到这个快捷方式,点击这个快捷方式会带您到可以创建新甜甜圈的表单页。

上面介绍的是隐式深层链接,接下来我们来创建一个显式深层链接,这个链接会根据应用的状态动态地被创建。

创建显式深层链接

如果您像我一样,甜甜圈在您的生活里也非常重要,因此当我输入一个新发现的甜甜圈信息时,可能想慢慢来,我可能会先输入一部分信息,当我有机会享用后再回来慢慢补充其他剩余信息。

这可以使用通知来实现,当我输入一个甜甜圈信息的时候,应用会创建一个通知以便之后可以快捷地返回正在编辑的条目。这其实不需要太多的代码来实现,只要创建一个带 PendingIntent 的通知,就可以带我们返回应用的正确页面。

上面的逻辑大部分发生在 DonutEntryDialogFragment 中,在 Done 按钮的 onClick() 监听器回调函数中。我们已经在  中介绍过这个点击监听器的代码,我们可以在这里新增和更新  的数据。我只需要再添加创建通知这一步,如下代码所示:

binding.doneButton.setOnClickListener {
    // 先获取上下文参数,因为 Fragment 可能在下面的 lambda 调用前就消失了
    val context = requireContext().applicationContext
    val navController = findNavController()

    donutEntryViewModel.addData(
        donut?.id ?: 0,
        binding.name.text.toString(),
        binding.description.text.toString(),
        binding.ratingBar.rating.toInt()
    ) { actualId ->
        val arg = DonutEntryDialogFragmentArgs(actualId).toBundle()
        val pendingIntent = navController
            .createDeepLink()
            .setDestination(R.id.*donutEntryDialogFragment*)
            .setArguments(arg)
            .createPendingIntent()

        Notifier.postNotification(actualId, context, pendingIntent)
    }
    dismiss()
}

首先,代码创建了带甜甜圈 id 的参数 arg,可以用这个参数来告诉目的地对话框应该获取哪个甜甜圈信息,来让用户继续编辑。

代码使用了一个 NavigationController 的 API 为深层链接创建 pendingIntent,其目的地被设置为对话框 fragment,这个调用既设置了包括甜甜圈 ID 的参数也创建了 intent。

代码还调用了 Notifer.postNotification(),这是我为了处理通知的创建和发送操作而增加的一个工具类方法。

fun postNotification(id: Long, 
                     context: Context, 
                     intent: PendingIntent) {
    val builder = NotificationCompat.Builder(context, channelId)
    builder.setContentTitle(context
            .getString(R.string.deepLinkNotificationTitle))
        .setSmallIcon(R.drawable.donut_with_sprinkles)
    val text = context.getString(R.string.addDonutInfo)
    val notification = builder.setContentText(text)
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setContentIntent(intent)
        .setAutoCancel(true)
        .build()
    val notificationManager =
        NotificationManagerCompat.from(context)
    notificationManager.cancelAll()
    notificationManager.notify(id.toInt(), notification)
}

首先,这段代码会创建一个 notification builder,而初始化这个 builder 需要一个 channelId,这一初始化过程需要放在 Notifierinit() 方法中 (想了解这些细节,请查阅代码,这也是标准做法)。

接下来,我设置了通知所需要的其他数据,同时设置了 intent,然后构建这个通知。在发送这个通知之前,已存在的通知会被取消 (因为我只想编辑最近的甜甜圈)。

最后,新创建的通知被发送出来,大功告成。现在每一个新编辑 (无论是创建新甜甜圈,还是编辑已存在的甜甜圈) 都会生成一个通知,之后用户可以点击这个通知,回到这个正在编辑的操作中。

总结

在这篇文章中,我先是创建了一个隐式深层链接,这个链接可以带用户进入应用的一个固定页面,用户可以在这个页面输入新甜甜圈的信息。接着,我创建了一个显式深层链接,这个链接可以帮助用户返回其之前没有完成的甜甜圈编辑页面。

甜甜圈记录应用变得越来越好了,不过当然还是不如甜甜圈好,因为什么都不如甜甜圈。这次就到这了,去找个甜甜圈享用吧,这是您应得的。

更多信息

更多关于导航组件的详情,请查看导航组件使用 。

DonutTracker 应用的完整代码,请查看 。

更多现代 Android 开发技巧 (MAD Skills) 系列内容,请查看 。

感谢各位中国 Android 开发者朋友们的一路相伴,我们一直以来都非常重视您的声音,大家的想法和建议我们也都采纳并实施在产品和日常工作中。我们邀请您扫描下方二维码,向 “Android 开发者” 公众号分享您的建议和对我们的期待。

www.zeeklog.com  - 使用深层链接导航 | MAD Skills

Read more

60个“特征工程”计算函数(Python代码)

60个“特征工程”计算函数(Python代码)

转自:coggle数据科学 近期一些朋友询问我关于如何做特征工程的问题,有没有什么适合初学者的有效操作。 特征工程的问题往往需要具体问题具体分析,当然也有一些暴力的策略,可以在竞赛初赛前期可以带来较大提升,而很多竞赛往往依赖这些信息就可以拿到非常好的效果,剩余的则需要结合业务逻辑以及很多其他的技巧,此处我们将平时用得最多的聚合操作罗列在下方。 最近刚好看到一篇文章汇总了非常多的聚合函数,就摘录在下方,供许多初入竞赛的朋友参考。 聚合特征汇总 pandas自带的聚合函数 * 其它重要聚合函数 其它重要聚合函数&分类分别如下。 def median(x):     return np.median(x) def variation_coefficient(x):     mean = np.mean(x)     if mean != 0:         return np.std(x) / mean     else:         return np.nan def variance(x):     return

By Ne0inhk
90w,确实可以封神了!

90w,确实可以封神了!

要说24年一定最热的技术,还得是AIGC! 前段时间阿里旗下的开源项目,登上GitHub热榜! AI大热,如今ChatGPT的优异表现,必然会出现各种细分场景应用的工具软件,和大量岗位项目! 山雨欲来风满楼,强人工智能的出现,所有科技公司已经开始巨量扩招此领域的人才。算法的岗位,近三个月已经增长68%!这件事在HR届也是相当震撼的。 目前各行各业都不景气的市场,人工智能岗位却一直保持常青!甚至同属AI边缘岗都比其他岗薪资高40%! 与此同时,AI算法岗上岸也不简单,竞争激烈,好公司核心岗位不用说,谁都想去。 所以事实就是,想要上岸,门槛也逐渐变高,项目经历、实习经历都很重要,越早明白这个道理就越能提前建立起自己的优势。 但我在b站逛知识区的时候,经常看到有些同学,因为一些客观原因导致无法参加实习,这种情况下,如果你想提升背景,增加项目经历的话,可以试试这个《CV/NLP 算法工程师培养计划》。 目前已经有上千位同学通过该计划拿到offer了,最新一期学员就业薪资最高能拿到78K!年薪94w! 优势就是有BAT大厂讲师带领,手把手带做AI真实企业项目(包含CV、NLP等

By Ne0inhk
再见nohup!试试这个神器,Python Supervisor!

再见nohup!试试这个神器,Python Supervisor!

👇我的小册 45章教程:() ,原价299,限时特价2杯咖啡,满100人涨10元。 作者丨Ais137 https://juejin.cn/post/7354406980784373798 1. 概述 Supervisor 是一个 C/S 架构的进程监控与管理工具,本文主要介绍其基本用法和部分高级特性,用于解决部署持久化进程的稳定性问题。 2. 问题场景 在实际的工作中,往往会有部署持久化进程的需求,比如接口服务进程,又或者是消费者进程等。这类进程通常是作为后台进程持久化运行的。 一般的部署方法是通过 nohup cmd & 命令来部署。但是这种方式有个弊端是在某些情况下无法保证目标进程的稳定性运行,有的时候 nohup 运行的后台任务会因为未知原因中断,从而导致服务或者消费中断,进而影响项目的正常运行。 为了解决上述问题,通过引入 Supervisor 来部署持久化进程,提高系统运行的稳定性。 3. Supervisor 简介 Supervisor is a client/

By Ne0inhk
第一本给程序员看的AI Agent图书上市了!

第一本给程序员看的AI Agent图书上市了!

AI Agent火爆到什么程度? OpenAI创始人奥特曼预测,未来各行各业,每一个人都可以拥有一个AI Agent;比尔·盖茨在2023年层预言:AI Agent将彻底改变人机交互方式,并颠覆整个软件行业;吴恩达教授在AI Ascent 2024演讲中高赞:AI Agent是一个令人兴奋的趋势,所有从事AI开发的人都应该关注。而国内的各科技巨头也纷纷布局AI Agent平台,如:钉钉的AI PaaS、百度智能云千帆大模型平台等等。 Agent 是未来最重要的智能化工具。对于程序员来说,是时候将目光转向大模型的应用开发了,率先抢占AI的下一个风口AI Agent。 小异带来一本新书《大模型应用开发 动手做 AI Agent》,这本书由《GPT图解》的作者黄佳老师创作,从0到1手把手教你做AI Agent。现在下单享受5折特惠! ▼点击下方,即可5折起购书 有这样一本秘籍在手,程序员们这下放心了吧,让我们先来揭开 Agent 的神秘面纱。 AI Agent 面面观

By Ne0inhk