Android Instant App:如何创建URL可寻址模块?

时间:2017-02-07 13:37:49

标签: android android-studio android-gradle android-build android-instant-apps

Google最近更新了有关即时应用的文档:Prepare your app

3. Refactor your app, if necessary外,大多数要点都很清楚。

他们建议零售模块,如浏览,搜索,项目详细信息和结账。

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

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

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

有人可以将光照进黑暗中吗?谢谢!

5 个答案:

答案 0 :(得分:4)

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

  1. 创建一个共享模块,其中包含应在功能模块之间共享的代码和资源。
  2. 为每个主要功能创建多个功能模块(在Google提供的示例中:浏览,搜索,项目详细信息和结帐)。这些模块可以依赖于第1页中创建的共享模块,但它们应该对彼此一无所知。
  3. 要从不同模块启动活动,请使目标活动URL可寻址,并通过隐式意图启动它。 Google suggests可以使用App链接。
  4. 要构建常规Android应用,请创建一个依赖于功能模块的应用模块。
  5. Google向公众发布Android InstantApp SDK后,您可以构建Instant Apps(每个功能一个)。

答案 1 :(得分:4)

现在请参阅official docs,即开发人员通常可以使用即时应用。

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

docs网站上的图表有点帮助:

enter image description here

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

答案 2 :(得分:4)

考虑这个图。 enter image description here

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

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

现在是时候将整个应用程序分解为一个名为feature的较小单元。单个功能可能包含多个活动,这些活动可能只是让您对应用程序有一瞥,或者实现促使用户安装该应用程序的目标。现在它完全依赖于你想要提供给用户的东西,这些东西迫使他们下载你的应用程序。

Feature1:因此我们将应用分为feature1和feature2。在此功能1中,我们为用户提供搜索和浏览项目的功能。 每当用户点击项目时,我们需要从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。为此,您必须从activity1请求activity2的URL地址。

<强>特征2: 现在,Feature2已加载到即时应用程序中,因此我们现在可以查看项目详细信息活动。

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

答案 3 :(得分:1)

我不确定我是否误解了你的问题,但我会尽力解决它。对于我的以下解释,我会多次提到this code sample by Google。我 HIGHLY 建议克隆那个回购并玩弄它,因为我认为它会回答你的问题。

  

如果我们使用像dagger,butterknife这样的库,......所有模块都依赖于其他模块

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

  

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

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

假设Feature1(BrowseActivity)想要打开Feature2(ItemDetailActivity)。而不是Feature1直接调用startActivity(ItemDetailActivity.class),它必须使用下面的方法调用(这是因为Feature1无法访问Feature2的ItemDetailActivity.class,因为它们不相互依赖)。 Here is the code sample provided by Google

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链接。 Here is the relevant code sample from 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>

如需更多信息,请阅读Digital Asset Links以及一般Deep Linking

答案 4 :(得分:0)

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

我开始从这个talk了解项目结构的新方式。  这让我明白了一点。

喜欢如果我们创建功能模块并希望链接到功能基础模块,我们可能需要删除未使用的androidTest testres资源。

同时使用新结构here

创建简单项目

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