In order to reduce app size and deliver sceneform dependencies to limited set of devices and users who want to use it. This is an attempt to bundle sceneform as a seperate on demand dynamic module using Android feature delivery which is delivered through App Bundles.
The application consists of primary app module and sceneform_dynamic_module. When the user clicks on Start Sceneform Activity, app attempts to download the sceneform dependency and launch an AR fragment.
Steps to load app bundle and test apk locally:
- Step1: Download bundletool from here. Rename the jar to
bundletool-all.jar
- Step2: Open terminal and change current working directory to the one containing the above jar. Run the below command:
alias bundletool='java -jar bundletool-all.jar'
- Step 3: Generate App Bundle
./gradlew :app:bundleDebug
- Step 4: Run bundletool to generate apks
bundletool build-apks --local-testing --bundle app-debug.aab --output app-debug.apks
- Step 5: Connect device and install apks
bundletool install-apks --apks app-debug.apks
Currently, getting below error when trying to launch the Sceneform Activity:
Invalid ID 0x00000000.2023-04-11 15:56:02.798 9148-9148 AndroidRuntime
com.acedev.dynamicfeature.debug
D Shutting down VM2023-04-11 E FATAL EXCEPTION: main
Process: com.acedev.dynamicfeature.debug, PID: 9148
android.view.InflateException: Binary XML file line #6 in
com.acedev.dynamicfeature.debug.sceneform_dynamic_module:layout/sceneform_ux_fragment_layout:
Binary XML file line #6 in com.acedev.dynamicfeature.debug.sceneform_dynamic_module:layout/sceneform_ux_fragment_layout:
Error inflating class
com.google.ar.sceneform.ArSceneView
Caused by: android.view.InflateException: Binary XML file line #6 in
com.acedev.dynamicfeature.debug.sceneform_dynamic_module:layout/sceneform_ux_fragment_layout:
Error inflating class com.google.ar.sceneform.ArSceneView
Caused by:
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343 undefined)
at android.view.LayoutInflater.createView(LayoutInflater.java:858 undefined)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1010 undefined)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:965 undefined)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1127 undefined)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088 undefined)
at android.view.LayoutInflater.inflate(LayoutInflater.java:686 undefined)
at android.view.LayoutInflater.inflate(LayoutInflater.java:538 undefined)
at com.google.ar.sceneform.ux.BaseArFragment.onCreateView(BaseArFragment.java:184 undefined)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963 undefined)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518 undefined)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282 undefined)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112 undefined)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647 undefined)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128 undefined)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072 undefined)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251 undefined)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502 undefined)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:251 undefined)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1543 undefined)
at android.app.Activity.performStart(Activity.java:8366 undefined)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3666 undefined)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:224 undefined)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:204 undefined)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176 undefined)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97 undefined)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2303 undefined)
at android.os.Handler.dispatchMessage(Handler.java:106 undefined)
at android.os.Looper.loopOnce(Looper.java:201 undefined)
at android.os.Looper.loop(Looper.java:288 undefined)
at android.app.ActivityThread.main(ActivityThread.java:7884 undefined)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548 undefined)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936 undefined)
Caused by: android.content.res.Resources$NotFoundException: Unable to find resource ID #0x0
at android.content.res.ResourcesImpl.getResourceTypeName(ResourcesImpl.java:281 undefined)
at android.content.res.Resources.getResourceTypeName(Resources.java:2319 undefined)
at com.google.ar.sceneform.utilities.LoadHelper.fromResource(LoadHelper.java:90 undefined)
at com.google.ar.sceneform.rendering.Texture$Builder.setSource(Texture.java:153 undefined)
at com.google.ar.sceneform.rendering.PlaneRenderer.loadPlaneMaterial(PlaneRenderer.java:339 undefined)
at com.google.ar.sceneform.rendering.PlaneRenderer.<init>(PlaneRenderer.java:84 undefined)
at com.google.ar.sceneform.ArSceneView.initializeAr(ArSceneView.java:561 undefined)