25

Google updated their documentation about instant apps recently: Prepare your app

Most of the points are clear except 3. Refactor your app, if necessary.

They suggest for retail modules like browse, search, item detail, and check out.

Question: How do I split up the app into modules which are fully functional & URL addressable?

I do see here several issues:

  • if we use libraries like dagger, butterknife, ... all modules would be dependent on other modules
  • if our modules contain (views) as required, how should a transition to another view (from another module) be implemented without importing this module?

Can somebody shed light into the dark? Thanks!

Prags
  • 2,457
  • 2
  • 21
  • 38
Fahim
  • 1,431
  • 1
  • 15
  • 28
  • `if we use libraries like dagger, butterknife, ... all modules would be dependant on other modules` - Not at all. Why should they? I've recently done such refactoring on a huge codebase with extensive usage of Dagger and ButterKnife, and can say - it was not an issue for me. Check my answer for more details and let me know if smth. is not clear for you. – Volo Apr 16 '17 at 22:27

5 Answers5

4

Proper modules separation required by Instant Apps can be easily done using the following steps:

  1. Create a shared module which will contain code and resources which should be shared across feature modules.
  2. Create several feature modules for each major feature (in the example provided by Google: browse, search, item detail, and checkout). These modules can depend on the shared module created in p.1, but they should know nothing about each other.
  3. To start an activity from different module make target activity URL-addressable, and start it via implicit intent. Google suggests to use App Links for that.
  4. To build your regular Android app, create an application module which depends on feature modules.
  5. Once Google releases its Android InstantApp SDK to the public, you can build your Instant Apps (one per feature).
Volo
  • 28,673
  • 12
  • 97
  • 125
4

Please refer to the official docs now that Instant Apps is generally available to developers.

To summarize, all Instant Apps will at least have what's called a base feature module that contains common code across the Instant App. On top of that, Instant Apps can optionally have 1 or more additional feature libraries that depend on the base feature module. Each feature module can have its own entry points that are URL-addressable, although feature modules themselves do not need to depend on each other. If one needs to call the other, that can be done via a URL-based Intent.

The diagram from the docs site helps a bit:

enter image description here

All feature modules use the new com.android.feature plugin, which is used in a similar way to the traditional com.android.library plugin in terms of how you can use it in your Android project and therefore the library docs can be used as a reference. In terms of how it differs, it will output a regular AAR file when used with your installable application module, and will output a feature APK when used with the new Instant App module.

AdamK
  • 21,199
  • 5
  • 42
  • 58
4

Consider this diagram. enter image description here

Q: How do I split up the app into modules which are fully functional & URL addressable?

Base module: contains all common resources required by your app. So in our case, all activities from feature1 and feature2 would be using shared res from base module.It may have libraries like dagger, butterknife.

Now it's time to break your whole app into a smaller unit called feature. A single feature may consist of multiple activities that may just gives a glimpse about your app or accomplish a goal which drives users to install that app. Now its completely depend upon you that what thing you want to deliver to the user which insist them to download your app.

Feature1: So we have split app into feature1 and feature2. In this feature1 we are giving users to search and browse for items. Whenever user click on item we need to load item detail from feature2 so on click of item from browse activity we will call like

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

Because:Activity1 from feature1 cannot directly call Activity2 in feature2. For doing so you must request URL address of activity2 from activity1.

Feature2: Now, Feature2 loaded into the instant app so we can now see item details activity.

NOTE: You should also consider your feature size while splitting app functionality because each feature must not exceed 4MB size otherwise validation occurs while uploading apk to play store.

Pinkesh Darji
  • 1,041
  • 10
  • 23
1

I'm not sure if I'm misunderstanding your question, but I'll try to take a crack at it. For my below explanation, I'll reference this code sample by Google several times. I HIGHLY suggest cloning that repo and playing around with it, since I think it will answer your question.

if we use libraries like dagger, butterknife, ... all modules would be dependent on other modules

As mentioned by others, any libraries that will be used by all of your Features will go into your Base Feature.

if our modules contain (views) as required, how should a transition to another view (from another module) be implemented without importing this module?

This answer covers the overview of it - but this part seems to be the root of your question so I'll try to dig in a little deeper.

Let's say Feature1 (BrowseActivity) wants to open up Feature2 (ItemDetailActivity). Instead of Feature1 calling startActivity(ItemDetailActivity.class) directly, it will have to use the method call below (this is because Feature1 doesn't have access to Feature2's ItemDetailActivity.class since they do NOT depend on each other). 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);

Now the missing part is that in Feature2's AndroidManifest you need to declare that ItemDetailActivity is listening for the https://example.com/itemdetail link. 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>

For any more info, read up on Digital Asset Links as well as general Deep Linking

Kyle Venn
  • 4,597
  • 27
  • 41
0

I think feature module come up with everything should modular concept. At the end every feature possible separate into feature module.

I start to understand new way of project structure from this talk. It make me clear for some point.

Like If we create feature module and want to link to feature base module, We probably need to remove unused androidTest test and res resources.

Also create simple project with new structure here

On this repos, try to start from scratch following document and above to change from application module to feature module and add instant app module into codebase.

anop72
  • 41
  • 3
  • Whenever you link to a blog post, library, or other external resource you're involved in (such as your repo), [you must clearly indicate this](https://stackoverflow.com/help/promotion). – Nathan Tuggy May 24 '17 at 04:43