How to include instant dynamic feature module in instant app?

南楼画角 提交于 2021-01-23 01:56:41

问题


I have a project with these modules:

  • app
  • bookingfeature (instant enabled)
  • map (not instant)

app contains some common code and resources and a starting activity with some logic to route the app to the correct destination, based on whether it's running as instant or not.

bookingfeature contains an activity and some fragments that I want to deploy with the instant app.

map contains the rest of the app (work in progress to split this into more modules)

Everything works fine if I deploy it like this in android studio:

If I untick the box for bookingfeature obviously it won't work, because the feature is not present.

When I create an app bundle and upload it to play store, and click on "try now" in play store, it behaves like bookingfeature is not ticked.

Can I make it behave like bookingfeature is ticked, include it in the app module somehow? Or do I have to move all the code from bookingfeature into app?

Does the "try now" button only run the app module, is there no way to change it?


app manifest:

<manifest …>
<dist:module dist:instant="true" />

<application
   …
   android:name=“.App”>

    <activity
        android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>


bookingfeature manifest:

<manifest ...>

    <dist:module
        dist:instant="true"
        dist:title="@string/title_bookingfeature">
        <dist:delivery>
            <dist:install-time />
        </dist:delivery>
        <dist:fusing dist:include="false" />
    </dist:module>
    <application>
        <activity
            android:name=".booking.view.BookingActivity"/>
    </application>
</manifest>

MainActivity:

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = DataBindingUtil
            .setContentView(this, R.layout.activity_main)

        if (isInstantApp(this)) {
            findNavController(R.id.main_nav_host).navigate(R.id.booking_activity)
        } else {
            findNavController(R.id.main_nav_host).navigate(R.id.splash_activity)
        }
        finish()
    }
}

navigation:

...
<activity
   android:id="@+id/booking_activity"
   android:name="x.x.x.booking.view.BookingActivity"
   app:moduleName="bookingfeature" />

<activity
    android:id="@+id/splash_activity"
    android:name="x.x.map.splash.SplashActivity"
    app:moduleName="map" />

EDIT:

When I remove finish() from the activity, it will actually launch the BookingActivity and install the feature module. But it's not exactly what I want. I would like the module to be included when it downloads the instant app.


回答1:


I had exact same problem and this option "Deploy as Instant app" destroyed my several hours. anyway i got rid of it by adding CATEGORY_LAUNCHER in manifest of instant module(bookingfeature in your case).

you have to removed CATEGORY_LAUNCHER from base module manifest and only add it in instant module manifest otherwise it will show two app icons when app is installed using "Install" button on playstore.

Now when you use "Try Now" it will open your instant module activity which is set as Launcher and from this activity you can check whether it is running as an instant app or not and launch the base module activity.

Instant Module Activity will look like this -
    <activity
                android:name=".booking.view.BookingActivity">
    <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
    </activity>

When you install the app using "Install" button on playstore it also downloads the instant module along with base module. So now it will launch this BookingActivity of instant module and inside this activity you will check if it is running as an instant app or not -

val instantApp = InstantApps.getPackageManagerCompat(this).isInstantApp()
if(!instantApp) {
 // start base module activity
// finish() this activity
}

Hope this helps, do comment if you have any suggestion/any other way to fix it.



来源:https://stackoverflow.com/questions/62672943/how-to-include-instant-dynamic-feature-module-in-instant-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!