From 8452f18bb188f7be1c2186f1f7d28e37c4886f64 Mon Sep 17 00:00:00 2001 From: Olivier Notteghem Date: Thu, 31 Oct 2024 11:41:08 -0700 Subject: [PATCH] Restore (limited) dynamic feature capability + introduce sample app --- examples/bundle/.DS_Store | Bin 0 -> 6148 bytes examples/bundle/.bazelrc | 10 +++ examples/bundle/.gitignore | 1 + examples/bundle/BUILD | 1 + examples/bundle/MODULE.bazel | 55 ++++++++++++++++ examples/bundle/README.md | 12 ++++ examples/bundle/WORKSPACE | 58 +++++++++++++++++ examples/bundle/WORKSPACE.bzlmod | 1 + examples/bundle/app/.DS_Store | Bin 0 -> 6148 bytes examples/bundle/app/AndroidManifest.xml | 22 +++++++ examples/bundle/app/BUILD | 31 +++++++++ examples/bundle/app/BasicActivity.java | 59 ++++++++++++++++++ .../app/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 1678 bytes .../app/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 1283 bytes .../app/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 1817 bytes .../app/res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 2137 bytes .../bundle/app/res/layout/basic_activity.xml | 23 +++++++ examples/bundle/app/res/menu/menu.xml | 8 +++ examples/bundle/app/res/values/dimens.xml | 5 ++ examples/bundle/app/res/values/strings.xml | 8 +++ examples/bundle/features/assets/BUILD | 18 ++++++ examples/bundle/features/assets/src/.DS_Store | Bin 0 -> 6148 bytes .../features/assets/src/AndroidManifest.xml | 13 ++++ .../bundle/features/assets/src/assets.txt | 1 + rules/android_application/BUILD | 7 --- .../android_feature_module_rule.bzl | 8 +-- rules/android_application/attrs.bzl | 6 +- .../feature_module_validation.sh | 0 .../gen_priority_android_feature_manifest.sh | 0 rules/rules.bzl | 5 ++ toolchains/android/BUILD | 16 +++++ toolchains/android/toolchain.bzl | 5 ++ 32 files changed, 359 insertions(+), 14 deletions(-) create mode 100644 examples/bundle/.DS_Store create mode 100644 examples/bundle/.bazelrc create mode 100644 examples/bundle/.gitignore create mode 100644 examples/bundle/BUILD create mode 100644 examples/bundle/MODULE.bazel create mode 100644 examples/bundle/README.md create mode 100644 examples/bundle/WORKSPACE create mode 100644 examples/bundle/WORKSPACE.bzlmod create mode 100644 examples/bundle/app/.DS_Store create mode 100644 examples/bundle/app/AndroidManifest.xml create mode 100644 examples/bundle/app/BUILD create mode 100644 examples/bundle/app/BasicActivity.java create mode 100644 examples/bundle/app/res/drawable-hdpi/ic_launcher.png create mode 100644 examples/bundle/app/res/drawable-mdpi/ic_launcher.png create mode 100644 examples/bundle/app/res/drawable-xhdpi/ic_launcher.png create mode 100644 examples/bundle/app/res/drawable-xxhdpi/ic_launcher.png create mode 100644 examples/bundle/app/res/layout/basic_activity.xml create mode 100644 examples/bundle/app/res/menu/menu.xml create mode 100644 examples/bundle/app/res/values/dimens.xml create mode 100644 examples/bundle/app/res/values/strings.xml create mode 100644 examples/bundle/features/assets/BUILD create mode 100644 examples/bundle/features/assets/src/.DS_Store create mode 100644 examples/bundle/features/assets/src/AndroidManifest.xml create mode 100644 examples/bundle/features/assets/src/assets.txt mode change 100644 => 100755 rules/android_application/feature_module_validation.sh mode change 100644 => 100755 rules/android_application/gen_priority_android_feature_manifest.sh diff --git a/examples/bundle/.DS_Store b/examples/bundle/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..82e28c3b8942788f7d43425a2196d58d551d2a3b GIT binary patch literal 6148 zcmeHKF-`+P475p#NHi%a_Y3@B6@?e@fdm3oq(p@DSMe^M#*A$wP6t&)6OASB?0P-B z+9}RwGxODXcW<^dvjv=J9~`E}efq?1DnfLg@w|UJ9QKUr{Z>hXyD1!XYs}9T=ho z0L~E(!#sKkU}FH-3x`BRV4hT9QoULRPdehQ@_ONrm~`{F8Ryi^ULA+W?TEKXH}8oW zrGOL|D=^FDlJ)-q{zv~mCTS%Fq`*}v;Pdt4dW9!dZJj)hwYI@GaOQl%X_yBELzH7+ ilw&Mdj_)EV^BU*a?}bBR&=C(hP(K6IMJ5IQTY)d`7#U*# literal 0 HcmV?d00001 diff --git a/examples/bundle/.bazelrc b/examples/bundle/.bazelrc new file mode 100644 index 000000000..a28203e1e --- /dev/null +++ b/examples/bundle/.bazelrc @@ -0,0 +1,10 @@ +# Flags needed while the Android rules are being migrated to Starlark. +common --experimental_google_legacy_api +common --experimental_enable_android_migration_apis +common --android_sdk=@androidsdk//:sdk +common:core_library_desugaring --desugar_java8_libs + +# Flags to enable mobile-install v3 +mobile-install --mode=skylark --mobile_install_aspect=@rules_android//mobile_install:mi.bzl --mobile_install_supported_rules=android_binary +# Required to invoke the Studio deployer jar +mobile-install --tool_java_runtime_version=17 diff --git a/examples/bundle/.gitignore b/examples/bundle/.gitignore new file mode 100644 index 000000000..63f1fef0e --- /dev/null +++ b/examples/bundle/.gitignore @@ -0,0 +1 @@ +*.lock diff --git a/examples/bundle/BUILD b/examples/bundle/BUILD new file mode 100644 index 000000000..a09fce916 --- /dev/null +++ b/examples/bundle/BUILD @@ -0,0 +1 @@ +# Empty build file to satisfy gazelle for rules_go. \ No newline at end of file diff --git a/examples/bundle/MODULE.bazel b/examples/bundle/MODULE.bazel new file mode 100644 index 000000000..ef2860cd8 --- /dev/null +++ b/examples/bundle/MODULE.bazel @@ -0,0 +1,55 @@ +module( + name = "bundle", +) + +bazel_dep(name = "rules_java", version = "7.4.0") +bazel_dep(name = "bazel_skylib", version = "1.3.0") + +bazel_dep( + name = "rules_android", + version = "0.5.1", +) + +local_path_override( + module_name = "rules_android", + path = "../../", +) + +remote_android_extensions = use_extension( + "@rules_android//bzlmod_extensions:android_extensions.bzl", + "remote_android_tools_extensions") +use_repo(remote_android_extensions, "android_gmaven_r8", "android_tools") + +register_toolchains( + "@rules_android//toolchains/android:android_default_toolchain", + "@rules_android//toolchains/android_sdk:android_sdk_tools", +) + +android_sdk_repository_extension = use_extension("@rules_android//rules/android_sdk_repository:rule.bzl", "android_sdk_repository_extension") +use_repo(android_sdk_repository_extension, "androidsdk") + +register_toolchains("@androidsdk//:sdk-toolchain", "@androidsdk//:all") + +bazel_dep(name = "rules_jvm_external", version = "5.3") + +# Load the maven extension from rules_jvm_external +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") + +maven.install( + name = "maven", + aar_import_bzl_label = "@rules_android//rules:rules.bzl", + artifacts = [ + "com.google.guava:guava:32.1.2-android", + "com.arthenica:ffmpeg-kit-https:4.4.LTS", + ], + repositories = [ + "https://maven.google.com", + "https://repo1.maven.org/maven2", + ], + use_starlark_android_rules = True, +) +use_repo(maven, "maven") + + + + diff --git a/examples/bundle/README.md b/examples/bundle/README.md new file mode 100644 index 000000000..0d923e32d --- /dev/null +++ b/examples/bundle/README.md @@ -0,0 +1,12 @@ +To build, ensure that the `ANDROID_HOME` environment variable is set to the path +to an Android SDK, and run: + +``` +bazel build app:assets +``` + +This will build application bundle containing a dynamic feature containing assets (named assets.txt). Verify with : + +``` +jar -tf bazel-bin/app/assets_unsigned.aab | grep assets.txt +``` diff --git a/examples/bundle/WORKSPACE b/examples/bundle/WORKSPACE new file mode 100644 index 000000000..a23815374 --- /dev/null +++ b/examples/bundle/WORKSPACE @@ -0,0 +1,58 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") + +maybe( + http_archive, + name = "rules_jvm_external", + strip_prefix = "rules_jvm_external-fa73b1a8e4846cee88240d0019b8f80d39feb1c3", + sha256 = "7e13e48b50f9505e8a99cc5a16c557cbe826e9b68d733050cd1e318d69f94bb5", + url = "https://github.com/bazelbuild/rules_jvm_external/archive/fa73b1a8e4846cee88240d0019b8f80d39feb1c3.zip", +) + +maybe( + http_archive, + name = "bazel_skylib", + urls = [ + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", + ], + sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c", +) +load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") +bazel_skylib_workspace() + +local_repository( + name = "rules_android", + path = "../..", # rules_android's WORKSPACE relative to this inner workspace +) + +load("@rules_android//:prereqs.bzl", "rules_android_prereqs") +rules_android_prereqs() +load("@rules_android//:defs.bzl", "rules_android_workspace") +rules_android_workspace() + +load("@rules_android//rules:rules.bzl", "android_sdk_repository") +android_sdk_repository( + name = "androidsdk", +) + +register_toolchains( + "@rules_android//toolchains/android:android_default_toolchain", + "@rules_android//toolchains/android_sdk:android_sdk_tools", +) + +load("@rules_jvm_external//:defs.bzl", "maven_install") + +maven_install( + name = "maven", + aar_import_bzl_label = "@rules_android//rules:rules.bzl", + artifacts = [ + "com.google.guava:guava:32.1.2-android", + "com.arthenica:ffmpeg-kit-https:4.4.LTS", + ], + repositories = [ + "https://maven.google.com", + "https://repo1.maven.org/maven2", + ], + use_starlark_android_rules = True, +) diff --git a/examples/bundle/WORKSPACE.bzlmod b/examples/bundle/WORKSPACE.bzlmod new file mode 100644 index 000000000..df9ed0ec9 --- /dev/null +++ b/examples/bundle/WORKSPACE.bzlmod @@ -0,0 +1 @@ +workspace(name = "bundle") diff --git a/examples/bundle/app/.DS_Store b/examples/bundle/app/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b15ab6319cee930304605401d4344651924f5b94 GIT binary patch literal 6148 zcmeH~JqiLr422W55Nx)zoW=uqgF*BJUO;s11VOQ%qx41vI)z6#m+=T zbo1!fBAtlL;ij^(Ffzq{DmOXHy}zF>$LsYnR7`SZHSkVG&xb-TNPq-LfCNZ@1b&8q zo!hYaB9xH?NPq+e0``9>aMPOFLjBi);3EKZhO`^jK1)E0C7?C6g(3sfXoW_r`WRw) zZ-~K`M-mIn*T>F+>!tZ{22kA zZTH&^J}S@Fx6iZuA+xq_aHy9fyj%jXv7>kicf<2y3usMkp~%2^5pWC)B=A)NPp>u+ AbpQYW literal 0 HcmV?d00001 diff --git a/examples/bundle/app/AndroidManifest.xml b/examples/bundle/app/AndroidManifest.xml new file mode 100644 index 000000000..1a4a7a99d --- /dev/null +++ b/examples/bundle/app/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + diff --git a/examples/bundle/app/BUILD b/examples/bundle/app/BUILD new file mode 100644 index 000000000..aff62ba6a --- /dev/null +++ b/examples/bundle/app/BUILD @@ -0,0 +1,31 @@ +load("@rules_android//android:rules.bzl", "android_application", "android_library") + +android_application( + name = "assets", + manifest_values = { + "applicationId" : "com.examples.bundle.app", + "versionCode": "0", + }, + feature_modules = ["//features/assets:feature_module"], + manifest = "AndroidManifest.xml", + deps = [":lib"], +) + +android_application( + name = "native", + manifest_values = { + "applicationId" : "com.examples.bundle.app", + "versionCode": "0", + }, + feature_modules = ["//features/native:feature_module"], + manifest = "AndroidManifest.xml", + deps = [":lib"], +) + +android_library( + name = "lib", + srcs = ["BasicActivity.java"], + manifest = "AndroidManifest.xml", + resource_files = glob(["res/**"]), + deps = ["@maven//:com_google_guava_guava",] +) diff --git a/examples/bundle/app/BasicActivity.java b/examples/bundle/app/BasicActivity.java new file mode 100644 index 000000000..f051263ba --- /dev/null +++ b/examples/bundle/app/BasicActivity.java @@ -0,0 +1,59 @@ +// Copyright 2022 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.examples.bundle.app; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +/** + * The main activity of the Basic Sample App. + */ +public class BasicActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.basic_activity); + + final Button buttons[] = { + findViewById(R.id.button_id_fizz), findViewById(R.id.button_id_buzz), + }; + + for (Button b : buttons) { + b.setOnClickListener( + new View.OnClickListener() { + public void onClick(View v) { + TextView tv = findViewById(R.id.text_hello); + if (v.getId() == R.id.button_id_fizz) { + tv.setText("fizz"); + } else if (v.getId() == R.id.button_id_buzz) { + tv.setText("buzz "); + } + } + }); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu, menu); + return true; + } +} diff --git a/examples/bundle/app/res/drawable-hdpi/ic_launcher.png b/examples/bundle/app/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..6ab2adde210fde3d980a0d3d9c551dcf61a96a86 GIT binary patch literal 1678 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 Q1ysb~>FVdQ&MBb@0DAuQWB>pF literal 0 HcmV?d00001 diff --git a/examples/bundle/app/res/drawable-xhdpi/ic_launcher.png b/examples/bundle/app/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..014b0f1064d5d3a51451970d0bb39b954e805264 GIT binary patch literal 1817 zcmZ`&3se(l7XBj)nUGe3&>|=#C>U8Eq#%m~2zfuM;Ss=7dC5Bkwj_mtNF-rQWvi>Z zu+b_D%46NG-Lkt#6)9B_wOVRn6~q!(d5INufj})x+7Rp?XnW4?IXmb6|NZYb-@W&n zJ2Qu3qb098dpQFDUX@9O3h2}A3w40|J@NbY8;(kzoCiQ_6?Gv4fiWXXs*nSq-2ec7 z0DvDLgg*tKgayF!bO6{j0C=cReij!20BIn0XMzY4O8ZJm`>@h}EccpHd0i>{tNhI~ za(;tY&?pf!NcfG=#IEK3u1Twa$_wxTNLdMXQGd#^=l+zwbXW@e?bYmIKbC$ev&3G! z1iMoV4IW^aaXC|b`pvY@_CO^0)6}$!dwBIC*eJt^F%{Z+(q?#~2BvvVk=4Ek>aVMpF6 z5nbg=iE&;gkknp`_X8Q~btC}^A|#=Gw-2FF!mj1<8pP~l96^&r(Hs~2L4*_LL$BQG zw38fsI5h6UE>FWIp!NbPPf*|iqz?8e2}z#0YwQzSHi-OUkeUCwownBpo!C`CIH@ucdE}@g}(dj8DZn5kqP(){W&p_yrwWh`IO!SfOZG?^ZeuO?YMz?tn&(GUz z!`_IFu))K;&7w!p3P^y4qc#FEZ4{z{uvu`lf*=SSg>G??z$wr}j6zr}lyV&fK|GF9 z-Jl9m<_?Jv97MdOFrcWVyNdx>dELH9U#LFHh9DV}$wlNRD?Hq`AafH#@T+yu$b`Iv zw}+?hD3jfI?#O6c{AB9cOaV=lfWAFBWV+#VV>qrgvt^CJ@R6_cm9Kj@TnsNZpZZf> z_KT~MZ{N5bHZjz3JmgzzRmJJtp0(bkiu~T%Nab{m`lzBHEpcuEIq4G>P?4B8=TUce zoXIO_np)_I)UWFN_l2-uoKf4>@kLC3%dh7wvU|;Qk$QzKKeei1;BwN?ICHLL7liLN zKl6#o(}&y}XNI-hjMN*6eA76ygZSgV1;3Y^%&LZ-2@VhLW=@*QH9WvM%Omh_GIjo; z+7G`v9(;7uu0OokKik%<{f#&4F4_2`{^H1kuV_JEX74EO0K%Tjllq`9<>Krv(~J3D{#FV}5NMj%;MzEK$lBxQ zv@No%;e;Q^ahX16bZ>k*ri(T@cKfv5miB|b(?qWf!L=XjvJ?njuN^s-utE{ju9ALC zYC1DA$PB?pf~N|OvKfQH=KmOz7!R^03ykYx`@EX8?;O#E-WU6?|Ho^b*p9s5zQcw0 zZ<#d42Y-%xwBv%gW;F=cOx?T@xsUJ<3zSYrscA30!?Eq)@3+=VT4&}=vu?Rfp=F=g z20|}Y{BY!K3{_`S-u6V4FBdA!4m0NMCT3;lB3=4xG8u1hsBzRpePH0e zqKgXH-qo1aJ$=TP#w1#+N$2^6^c4d-=~ZN#q1^?qd1P&^MvfV-1UkIi%b^wFe01KQ ztD|q;3j$E-*aJ-f@}j{f!0VF?XXyUlb`XUyYNZ(6tW-Y5s`@w@bxPs_gv1wq#mFEvEl zI!Yt2m^GDaLRGvj*TVMGHthMohW3@2lfV9p^^}WKpLuNk`G#rjLUz%j^?1lP&(2Mt ztG&csho?`(Q}3TaUcp|w6yuCOeXdWO;rMeKXRI3?fqOAMse1pTX@T>q*h$?+p5yPX zxcH*n)x=dkI8aRYvvA)c_8Z6tG<3#eoMm25-OYGtl^UoAbo97xFg7Bgt!;ECW-A8; z*FWs2Vq%?T$)7-t8go?n=CRHkx%Im;Z2%$BzkF;CwCG3j(k6S#;9u#FiQdApGq44h6N|-WvD$`bW&f4%jw(AZx9tBXeEyzn4kmco rJH)GUF-=BM4$x>cTk{GFinB7*Ia^gl%DU+YFGvD1QMB-%{B*;QT66hG literal 0 HcmV?d00001 diff --git a/examples/bundle/app/res/drawable-xxhdpi/ic_launcher.png b/examples/bundle/app/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..20703a15c6809f4919a823ff4b5f571b02c5e88f GIT binary patch literal 2137 zcmZ`(c~p~E7JmUk5)czKmHi_S6qEvy%?Jr5A(*g85;j}v0z{y|AX`WRC=d_<#Q>us zRSra9O6-gas68%N9Y7GODBD4yDvN9~f)<}m`RyI}_^2gO{jzFOo&)mTTpsC#Ok7zVJlZ4!m9ROr+03iPm09pv; z&j64~0pL{>0AAGqn55R+6wm-bUFHXc`9TM9Z>G3UBz`Ow_dz8?{7541OaFPcN!TTf zxxeqy+>c>RJ0qIE@l|kGb=!UGI4r0rwu2ONzye@59z+3IDQ36~1Q%)uZ%v3a-rXTw znZRd)bASZ()K8SS4sdmW1OahG5Qqj|07MZ$C=QNyWq=9}yguyT_bdmNvnh75NhQOI zHYF6W-xM%_O&S^20`OH~HeUc>Hjd6pewY)0y+H;mkD4V42@Zwwe=QUa<qB?rTMt@{k>O?al4fZb8CzCskZ}!S`TUJq^TG;!P@__-RhnFVT&_l=R_Eie z8ns4~3t2ucPXiZ3av{S(Yzdch5Qj#aI!|tfl~FN)95yIHTXEq5m&*M%1Ax_SD;w3B zqTB~TjL3h7A7)C&WUZ6_-{#BU7pphz&t`^6hhGoGODw_(`cY5YJqLql^jM^`<~p9E z{F;1R1q;*f&srb^uqum^?=mbc-fxND8F^v;xwo67J8@@C{qj$XJy}!F20hK&%z9D} zFW#xHwAkO0aP?;?^;FsXFUwU{LXUfGX4cO#k}?*Oy*DJ5`eHU1o|z38tn8qsM}^+* zGv(k1F1mMg6`elWA*GV%Th#%*FNRFZEvtK8pCcc8J0t5OA4}_yHJkj~6d!LH`D9<- zcv;$%><@^lWxt*5xIW5w9w6Lxo$^Z`bU3uf^!y1NALNTUkNXAG?P1}3de;TLzgc< zt*Q0Aw{YvvO?daLQ5nX_Fg`Bc+O^#}_vPIN%<0qKOUm5I2g1O>a*OdRn7ZoUEl!^q zx)emaP_@x#+ZMBe$iQNe<4A4Q#?^%z4X|B_;dv!u0qmTwKW zl|Hh5J}VQ`mx;UIxArIU)@*A|Jyf=B@jrt;GdJoxtIpqlyEdDbG`Vb|tUI;$z-+Ab zz!O#XKTmwGDj(W2l(X)|(xOZE;?#FCd*j};icm{g>kU^0#Iy#kEgx>#ftQ6=)S zWv~Q8g|czvYP~bpuA5FN>BWCUCP^~oG>RF7?-StL*KI|x?drR>n0Dd~1lYaF=RHI> zvC%y2nkwynnt0$w$a7^Aw` zC+yKDrxPUa5LDt(E>9=>4x6{hE9(eYf3CkFUihI9|LZ%ubLBoCU+S#azH{ro@^;x| zZ`G>=_lwJ~=29Gbr}Dl#F+H+y(P`*-Nl(SOhp#Ur(wpQC{5)Ev9Lv8$6LF}@JfxXS z9N^&xjrCt$Dkj({a&z7^>KAGknBF?faOq_^iSL0lkU`i<%)EnM_%zDffDxXpkRRY* zLlk6u*fo3NSIohjg2o6iIQG^%ovD(x$SwK1YhyTc{=r%nXR9)}d_-UpcBymLL3i-= zY~}!JaG}dD`7ud)ljnpsI&44ZfHFGL_^elRW~6Y!-&;G@S*L#=c3k^@`4sARck`hS z+7VTz#bLLau~m&VH?aF1t}iWmT@QkP!Sy1)Z$$f|MX_GO^jIi>E5+5-iQ?+y>K3+n ztCzcn7sb<&Lh+(d4tdTE{3RecWnV&E*8dMsC53(u1I$(`gr>xaB+==yKq8SiC+ttk b5JsoQI;W(^pP8qbLnq+x7tFrMiYoXov?hQf literal 0 HcmV?d00001 diff --git a/examples/bundle/app/res/layout/basic_activity.xml b/examples/bundle/app/res/layout/basic_activity.xml new file mode 100644 index 000000000..f84199cb5 --- /dev/null +++ b/examples/bundle/app/res/layout/basic_activity.xml @@ -0,0 +1,23 @@ + + + + +