25

谷歌最近更新了他们关于即时应用的文档:准备你的应用

除了3. 重构您的应用程序,如有必要,大部分要点都很清楚 。

他们建议零售模块,如浏览、搜索、商品详情和结账。

问题:如何将应用程序拆分为功能齐全且可通过 URL 寻址的模块?

我确实在这里看到了几个问题:

  • 如果我们使用 dagger、butterknife 之类的库......所有模块都将依赖于其他模块
  • 如果我们的模块根据需要包含(视图),如何在不导入此模块的情况下实现到另一个视图(从另一个模块)的转换?

有人可以照亮黑暗吗?谢谢!

4

5 回答 5

4

考虑这个图表。 在此处输入图像描述

问:如何将应用程序拆分为功能齐全且可通过 URL 寻址的模块?

基本模块:包含您的应用所需的所有常用资源。所以在我们的例子中,来自 feature1 和 feature2 的所有活动都将使用来自基本模块的共享资源。它可能有像 dagger、butterknife 这样的库。

现在是时候将您的整个应用程序分解为一个称为功能的较小单元了。单个功能可能包含多个活动,这些活动可能只是让您了解您的应用程序或完成一个促使用户安装该应用程序的目标。现在,它完全取决于您要向用户提供什么东西,从而坚持他们下载您的应用程序。

Feature1:所以我们将应用程序拆分为 feature1 和 feature2。在此功能中,我们让用户搜索和浏览项目。每当用户单击项目时,我们需要从 feature2 加载项目详细信息,因此从浏览活动中单击项目,我们将调用如下

Intent intent = new Intent(Intent.ACTION_VIEW,
                Uri.parse("https://yourdomain.com/itemdetail"));
        intent.setPackage(getPackageName());
        intent.addCategory(Intent.CATEGORY_BROWSABLE);
        startActivity(intent);

因为:feature1中的Activity1不能直接调用feature2中的Activity2。为此,您必须从活动 1 请求活动 2 的 URL 地址。

Feature2: 现在,Feature2 已加载到免安装应用中,因此我们现在可以查看项目详细信息活动。

注意:您还应该在拆分应用程序功能时考虑您的功能大小,因为每个功能不得超过 4MB 大小,否则在将 apk 上传到 Play 商店时会进行验证。

于 2017-05-30T12:32:41.677 回答
4

Instant Apps 所需的适当模块分离可以使用以下步骤轻松完成:

  1. 创建一个共享模块,其中包含应该跨功能模块共享的代码和资源。
  2. 为每个主要功能创建几个功能模块(在 Google 提供的示例中:浏览、搜索、项目详细信息和结帐)。这些模块可以依赖于 p.1 中创建的共享模块,但它们之间不应相互了解。
  3. 要从不同的模块启动一个活动,使目标活动 URL 可寻址,并通过隐式意图启动它。Google建议为此使用 App Links。
  4. 要构建您的常规 Android 应用程序,请创建一个依赖于功能模块的应用程序模块。
  5. 一旦 Google 向公众发布其 Android InstantApp SDK,您就可以构建您的 Instant Apps(每个功能一个)。
于 2017-04-16T22:23:07.220 回答
4

请参阅官方文档,因为即时应用程序已普遍提供给开发人员。

总而言之,所有即时应用程序都至少具有所谓的基本功能模块,其中包含整个即时应用程序的通用代码。最重要的是,Instant Apps 可以选择拥有 1 个或多个依赖于基本功能模块的附加功能库。每个功能模块都可以有自己的 URL 可寻址的入口点,尽管功能模块本身不需要相互依赖。如果一个需要调用另一个,可以通过基于 URL 的 Intent 来完成。

来自 docs 网站的图表有点帮助:

在此处输入图像描述

所有功能模块都使用新插件,就如何在 Android 项目中使用它而言com.android.feature,它的使用方式与传统插件类似,因此库文档可以用作参考。就其不同之处而言,它在与您的可安装应用程序模块一起使用时会输出一个常规的 AAR 文件,而在与新的 Instant App 模块一起使用时会输出一个功能 APK。com.android.library

于 2017-05-17T22:44:53.237 回答
1

我不确定我是否误解了你的问题,但我会尝试解决它。对于下面的解释,我将多次引用Google 的此代码示例。强烈建议克隆该回购并使用它,因为我认为它会回答您的问题。

如果我们使用 dagger、butterknife 之类的库......所有模块都将依赖于其他模块

正如其他人所提到的,您的所有功能都将使用的任何库都将进入您的基本功能。

如果我们的模块根据需要包含(视图),如何在不导入此模块的情况下实现到另一个视图(从另一个模块)的转换?

这个答案涵盖了它的概述 - 但这部分似乎是你问题的根源,所以我会尝试更深入地挖掘。

假设 Feature1 ( BrowseActivity) 想要打开 Feature2 ( ItemDetailActivity)。而不是直接调用 Feature1 startActivity(ItemDetailActivity.class),它必须使用下面的方法调用(这是因为 Feature1 无权访问 Feature2,ItemDetailActivity.class因为它们不相互依赖)。 这是谷歌提供的代码示例

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com/itemdetail"));
intent.setPackage(getPackageName());
intent.addCategory(Intent.CATEGORY_BROWSABLE);
startActivity(intent);

现在缺少的部分是在 Feature2 中,AndroidManifest您需要声明ItemDetailActivity正在侦听https://example.com/itemdetail链接。这是来自 Google 的相关代码示例

<activity android:name=".ItemDetailActivity">
    <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="http" />
      <data android:scheme="https" />
      <data android:host="example.com" />
      <!-- IMPORTANT -->
      <data android:pathPrefix="/itemdetail"/>
    </intent-filter>
    <meta-data
      android:name="default-url"
      android:value="https://www.example.com/itemdetail" />
</activity>

有关更多信息,请阅读数字资产链接以及一般深度链接

于 2017-06-07T17:54:46.877 回答
0

我认为功能模块提出了一切应该模块化的概念。最后,每个可能的功能都分离到功能模块中。

我从这次谈话中开始了解项目结构的新方式。这让我明白了一点。

就像如果我们创建功能模块并想要链接到功能基础模块,我们可能需要删除未使用androidTest testres资源。

还在这里创建具有新结构的简单项目

在这个 repos 上,尝试从头开始以下文档及以上内容,从应用程序模块更改为功能模块,并将即时应用程序模块添加到代码库中。

于 2017-05-24T04:14:11.800 回答