Androidã¢ããªã®APKãµã€ãºãå§çž®ããããšè©Šã¿ãŠæãã話
åçš¿:
æŽæ°:

æ¬èšäºã®æŠèŠ
Xamarin.Formsã§éçºããAndroidã¢ããªã®ããã±ãŒãžãµã€ãºãå§çž®ããããšãLinkerããd8/r8ãã³ã³ãã€ã©ãé§äœ¿ããããæåããäžé£ã®é¡æ«ãããŸãšããã
ã¢ããªã®ããã±ãŒãžãµã€ãºãæ°ã«ãªã
ãããã ãã®åºŠãçŽ äººãªããã¹ããã¢ããªéçºã«ææŠããŠã¿ããä»åã®èšäºã§ã¯æŠèŠãšçµç·¯ã«ã€ããŠæžãç¶Žã£ãŠã¿ãããå®éã«è¡ã£ãäœæ¥ã®è©³çްã¯ãå š7åã«åããèšäºãå¥éäœæ
ã€ã³ã¹ããŒã«ã¯ãã¡ãããã

è²ã ãšäžå ·ååé¡ã§è©±é¡ãšãªã£ãŠãããCOCOA - æ°åã³ãããŠã€ã«ã¹æ¥è§Šç¢ºèªã¢ããªãã®åœ±é¿ãããããã£ããæªãã€ã¡ãŒãžãã€ãããXamarin.Formsãã§éçºããã
Xamarin.Formsã¯çŽæ¥AndroidãiOSã®APIãå©ããŠå®è¡ããã¢ããªãäœããããã£ãŠããã€ãã£ãéçºãšæ¯ã¹ãŠç¹å¥ã«å£ããšããããšããªããšã¯æãã
æãããmonoã©ã³ã¿ã€ã ãæ±ããŠããããšããããããã±ãŒãžãµã€ãºã倧ãããªããã¡ã
Xamarinã®åºç€ãMonoãã®monoã©ã³ã¿ã€ã ãšã¯ã©ã¹ã©ã€ãã©ãª
ã€ã³ãµã€ãXamarinïŒ3ïŒãXamarinã«ããããœãããŠã§ã¢ã®åºç€ã§ããMonoãæ·±ãçè§£ããã°ãXamarin補åã®çè§£ã¯ãã£ãšæ·±ãŸããä»åã¯monoã©ã³ã¿ã€ã ãšãMonoã®ã¯ã©ã¹ã©ã€ãã©ãªã«ã€ããŠè§£èª¬ããã
çŸåšãªãªãŒã¹ããŠããããŒãžã§ã³1.0.4ã®æç¹ã§ãããŠã³ããŒããµã€ãºã¯34MBãã€ã³ã¹ããŒã«ããã¢ããªãµã€ãºã¯49.45MBãã¢ããªã®å 容ãèãããšå€§ããã
ãããã©ãã«ãã§ããªãããšæªæŠèŠéããæããïŒã€ãŸãæªè§£æ±ºïŒãšãããæ®å¿µãªå 容ãªèšäºãšã£ãŠããã
æ å ±äŸ¡å€ã¯ãŒããšã¯æãããæã€ã¶ãã«ãä»ãåãããã ãããããããã
Xamarin.Forms ã ã£ãŠãã€ãšããããã
åèã«ãããµã€ãã¯ãã¡ãã
- Xamarin.Forms - Android App Performance and Package Size Reduction
- Reducing iOS and Android App Size in Xamarin
ãµã€ãºãå°ããããæ¹æ³ã¯ããã€ãããã
- R8 Shrinkerã䜿çšãã
Android's D8 dexer and R8 shrinker - Xamarin Blog
Learn more about Xamarin.Androidâs D8 and R8 integration and deep dive on how R8 is being developed for Android and D8 as the next-generation DEX compiler.
- Linkerã䜿çšãã
Android ã§ã®ãªã³ã¯ - Xamarin
Xamarin.Android ã¢ããªã±ãŒã·ã§ã³ã䜿çšããŠããµããŒãæ å ±ãå«ãã¢ããªã±ãŒã·ã§ã³ã®ãµã€ãºããªã³ã«ãŒã䜿ã£ãŠå°ããããæ¹æ³ã«ã€ããŠèª¬æããŸãã
- AOTïŒLLVMã³ã³ãã€ã©ã䜿çšãã
ãªãªãŒã¹ã«åããŠã¢ããªã±ãŒã·ã§ã³ãæºåãã - Xamarin
ã¢ããªã±ãŒã·ã§ã³ã®ã³ãŒããèšè¿°ãããã¹ããããããé åžçšã«ããã±ãŒãžãçšæããå¿ èŠããããŸãã ãªãªãŒã¹çšã«ã¢ããªããã«ãããæé ã«ã€ããŠç¢ºèªããŸãã
ãã®äžã§ã3çªç®ã®AOTïŒLLVMã¯ãVisual Studioã®Enterpriseãšãã£ã·ã§ã³ã©ã€ã»ã³ã¹ãå¿ èŠããã£ãŠãããã¯æ®å¿µãªããå©çšã§ããªãã
ã§ã¯ãæåã®2ã€ã䜿çšããã°ãããããªãããšãªãããããã¯ç°¡åã«ã¯ãããªãã
ãŸãã¯ãR8 ShrinkerããšãLinkerãã«ã€ããŠã調ã¹ãŠã¿ãããšãç°¡åã«ãŸãšãããã
R8 Shrinker
ããã¯ãJavaãã€ãã³ãŒãã察象ã«ãæªäœ¿çšã³ãŒããåé€ããŠããããã®ã
ãã ãããã€ãã£ãéçºãšç°ãªããXamarin.Formsã§ã¯é£èªåã®æ©æµã¯åŸãããšãã§ããªãã

軜éåã«åœ¹ç«ã€ãªã䜿ãã°ãããããªããããæãããšã ããã
ãªãã®åãããªãããã€ãéžã¶ãšã¢ããªã¯èŠäºã¯ã©ãã·ã¥ããã
ãããããšå¯ŸåŠãããªããšäœ¿ããªãããšãããã£ãããã®çç±ãšå¯ŸåŠã«ã€ããŠã¯åŸè¿°ããã
Linker
ããã¯ãéçè§£æã«ããäžèŠãšå€æããã³ãŒããã°ã£ããåãæšãŠãããšã§è»œéåãå³ãæ©èœã
ãªãã·ã§ã³ãšããŠããäžå䜿çšããªãïŒãªãïŒããSDKã®ã¿å¯Ÿè±¡ãšããïŒSDKã¢ã»ã³ããªã®ã¿ïŒãããã¹ãŠå¯Ÿè±¡ïŒSDKããã³ãŠãŒã¶ã¢ã»ã³ããªïŒãã®3ã€ãããã

çŸåšã¯ãSDKã®ã¿ã察象ãšããŠãããããããæžããã³ãŒãããã³è¿œå ããNuget Packageã«ã€ããŠã¯å¯Ÿè±¡å€ãšãªã£ãŠããã
ã§ããSDKãšãŠãŒã¶ã¢ã»ã³ããªãã¹ãŠãã宿ã«éžã¶ãšã¢ããªã¯èŠäºã¯ã©ãã·ã¥ããã
R8 ShrinkerãLinkerãã©ã¡ããäœãããã«äœ¿ããããã§ã¯ãªããå°å ¥ããã«ã¯ãããªãã®æºåãå¿ èŠãªã®ã ã
R8 Shrinker ã䜿ãããã«è¡ã£ãäœæ¥
ãŸãã¯ãVisual Studioã®ããŒã«âAndroidâAndroid Device Monitorã§ãã¯ã©ãã·ã¥åå ãèŠãŠã¿ãã

ãFATALããããããããèŠãŠã¿ããšããããªã¡ãã»ãŒãžãããã
java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.ads.MobileAdsInitProvider"
ãããã®ã¢ããªã«ã¯ãGoogle AdMobããšããåºå衚瀺çšã®ãã©ã°ã€ã³ãããããèµ·åæã«ãããªããç¡ããšèšãããŠããã
ã€ãŸãããR8 Shrinkerãã¯ãç§ã远å ããnugetããã±ãŒãžãäžèŠã³ãŒããšã¿ãªãããããµãªåã£ãã®ã ã
R8 Shrinkerã䜿çšããŠãããšãAndroidãããžã§ã¯ããã©ã«ãé äžã®ãobj\Release\XXX\proguardãã«ã.cfgãæ¡åŒµåã®ãã¡ã€ã«ãäœããããïŒXXXã¯ãã䜿ãã®ãšãã¥ã¬ãŒã¿ã®ããŒãžã§ã³ãå ¥ãïŒ
ãããã®ãã¡ã€ã«ãèŠãŠã¿ããšãã-keep class XXXXããšããèšè¿°ãããããšäžŠãã§ããã
ããã¯ãã³ã³ãã€ã«æã«åãæšãŠãããŒã察象ãšãªãã©ã€ãã©ãªåãããããšæžãããŠããã®ã ã
objé äžã«ãããã¡ã€ã«ã¯èªåçæããããã®ã
ãããšã¯å¥ã«ãèªåã远å ããããã±ãŒãžçãkeepãããããèšå®ãã¡ã€ã«ãçšæããå¿ èŠãããã
ããšãã°ãmy_proguard_xamarin.cfgããšãããã¡ã€ã«ãAndroidãããžã§ã¯ãã«è¿œå ããããã«ãã¢ã¯ã·ã§ã³ãããProguardConfigurationãã«ããŠããã
ããããããšã§ããã«ãæã«ãã®èšå®ãã¡ã€ã«ãèªãã§ãããããã«ãªãã
Xamarin.Android ProGuard ã¯ãJava ã¯ã©ã¹ ãã¡ã€ã«ã®ã·ã¥ãªã³ã«ãŒããªããã£ãã€ã¶ãŒãããã³äºåæ€èšŒæ©èœã§ãã ããã¯ãæªäœ¿çšã®ã³ãŒããæ€åºããŠåé€ãããã€ãã³ãŒãã®åæãšæé©åãè¡ããŸãã ãã®ã¬ã€ãã§ã¯ãProGuard ãã©ã®ããã«æ©èœãããããããžã§ã¯ãã§æå¹ã«ããæ¹æ³ãããã³èšå®æ¹æ³ã«ã€ããŠèª¬æããŸãã ãŸããProGuard ã®èšå®äŸãããã€ã瀺ããŸãã
ããšã¯ã²ãããããã©ã€ïŒãšã©ãŒã
ãšã©ãŒåå ãšãªã£ãã©ã€ãã©ãªãèšå®ãã¡ã€ã«ã«è¿œèšããAndroid Device Monitorã§ç¢ºèªããŸãå¥ã®ãšã©ãŒãåºããããã远èšããããŠãŸãâŠâŠã
ãããã®å Žåãæåã®AdMobã«ç¶ããŠAdMobã«é¢é£ãããcom.google.unity.ads.UnityAdListenerãããããŠãandroidx.workããåå ã§ã¯ãããããã®éœåºŠãã¡ã€ã«ã«Keepã远å ããã
äžçªåä»ã ã£ãã®ããSplash screenã®ãã¡ã€ã«ã«åé¡ããããšãšã©ãŒãåºãŠããããã調ã¹ãçµæãCalligraphyããã¢ããããŒããããšããæ å ±ãèŠã€ã察å¿ããããšã
R8ã䜿çšããŠããªããã°ãšãã«åé¡ã¯èµ·ããŠããªãã£ããããR8ã«é¢é£ããŠCalligraphyã®ããŒãžã§ã³ãåé¡ãšãªãã®ãããŸãã¡åå ã¯ã¯ã£ããããªãã£ãã
Crash on Android 10 (InflateException in layout/abc_screen_simple line #17)
My application works fine from Android 4.3 until Android 9 Pie, but my application doesn't work on Android 10 (Q API 29) and crashes. This is my logcat - why this is happening?java.lang.
Use custom fonts in Android! Port of https://github.com/InflationX/Calligraphy - nwestfall/Calligraphy.Xamarin
çµæãšããŠä»¥äžã®ãã㪠.cfgãã¡ã€ã«ãäœæããäœãšãã¢ããªãèµ·åãããšãããŸã§æŒãã€ããã
-keep class com.google.unity.** {
*;
}
-keep public class com.google.android.gms.ads.**{
public *;
}
-keep public class com.google.ads.**{
public *;
}
-keep class androidx.work.** { *; }
-keepattributes Annotation
R8ã«ã€ããŠã¯ä»¥äžãšãªãã
Linkerã§ãŠãŒã¶ã¢ã»ã³ããªã察象ã«ãã
ç¶ããŠãLinkerã
ãã£ãšãããã±ãŒãžå§çž®ã®æ©æµã倧ããã®ã¯ãSDKããã³ãŠãŒã¶ã¢ã»ã³ããªããéžæããããšã
ããããã¡ããR8 Shrinkeråæ§ãå¿ èŠãªèšå®ãæœããªããšããããã®å Žåã¯ã¢ããªãèŠäºã¯ã©ãã·ã¥ããã
è¡ãäœæ¥ãåæ§ã§ãLinkerã§åãæšãŠãŠã»ãããªãã©ã€ãã©ãªçãèšå®ãã¡ã€ã«ã«è¿œå ããã
ã«ã¹ã¿ã ãªã³ã«ãŒã®æ§æ - Xamarin
ãã®ããã¥ã¡ã³ãã§ã¯ãå¿ èŠãªã³ãŒãããªã³ã¯ãããŠããã¢ããªã±ãŒã·ã§ã³ããåé€ãããªãããšãæç€ºçã«ç¢ºèªãããªã³ã«ãŒãæ§æããããã«äœ¿çšã§ãã XML ãã¡ã€ã«ã«ã€ããŠèª¬æããŸãã
Linkerã®èšå®ã¯XMLãã¡ã€ã«ã«èšè¿°ããã
ãšãããããLinkerSettings.xmlããšããååã®ãã¡ã€ã«ãAndroidãããžã§ã¯ãã«è¿œå ãããã¡ã€ã«ããããã£ã®ãã«ãã¢ã¯ã·ã§ã³ããLinkDescriptionãã«ããŠããã
ãããã®å Žåã¯ãããªæãã«ãªã£ãã
䜿çšããŠããNuget Packageãšãäœæãããããžã§ã¯ãã¢ã»ã³ããªã察象ãšãªã£ãŠããã
<?xml version="1.0" encoding="utf-8" ?>
<linker>
<!--
For more information see the docs on creating custom Linker Settings
https://docs.microsoft.com/en-us/xamarin/cross-platform/deploy-test/linker
-->
<assembly fullname="Essential.Interfaces">
<type fullname="Xamarin.Essentials.Implementation.AppInfoImplementation">
<method name=".ctor" />
</type>
</assembly>
<assembly fullname="Prism.Forms">
<type fullname="Prism.Common.ApplicationProvider" preserve="all" />
<type fullname="Prism.Services.PageDialogService" preserve="all" />
<type fullname="Prism.Services.DeviceService" preserve="all" />
<type fullname="Prism.Ioc*" preserve="all" />
<type fullname="Prism.Modularity*" preserve="all" />
<type fullname="Prism.Navigation*" preserve="all" />
<type fullname="Prism.Behaviors.PageBehaviorFactory" preserve="all">
<method name=".ctor" />
</type>
<type fullname="Prism.Services.DependencyService" preserve="all">
<method name=".ctor" />
</type>
</assembly>
<assembly fullname="Prism">
<type fullname="Prism.Navigation*" preserve="all" />
<type fullname="Prism.Logging.EmptyLogger" preserve="all">
<method name=".ctor" />
</type>
</assembly>
<assembly fullname="Unity.Abstractions">
<type fullname="*" />
</assembly>
<assembly fullname="Unity.Container">
<type fullname="*" />
</assembly>
<assembly fullname="Prism.Unity.Forms">
<type fullname="*" />
</assembly>
<assembly fullname="System">
<type fullname="*" />
</assembly>
<assembly fullname="mscorlib">
<type fullname="*" />
</assembly>
<assembly fullname="OneThird.Core">
<type fullname="*" />
</assembly>
<assembly fullname="OneThird.Application">
<type fullname="*" />
</assembly>
<assembly fullname="OneThird.Domain">
<type fullname="*" />
</assembly>
<assembly fullname="OneThird.Infrastructure">
<type fullname="*" />
</assembly>
<assembly fullname="Microsoft.Identity.Client">
<type fullname="*" />
</assembly>
<assembly fullname="Realm">
<type fullname="*" />
</assembly>
<assembly fullname="System.IdentityModel.Tokens.Jwt">
<type fullname="*" />
</assembly>
<assembly fullname="Xamarin.CommunityToolkit">
<type fullname="*" />
</assembly>
<assembly fullname="Xamarin.GooglePlayServices.Ads" >
<type fullname="*" />
</assembly>
</linker>
ãããããã§ããŸãããšæãããâŠâŠã
èŠäºã«ã¯ã©ãã·ã¥ããã
ã§ãè²ã ãšèª¿ã¹ãŠãããšãLinkerã®å¯Ÿè±¡ããå€ãããã«ãPreserve屿§ã远å ããããšããæ å ±ãèŠã€ããã
ãããžãé¢åã§ã¯ãããã以äžã®ããã«å±æ§ãä»ããŠåãããšã«ããã
- Androidãããžã§ã¯ãã®ãã¹ãŠã®ã¯ã©ã¹
- [Android.Runtime.Preserve(AllMembers = true)]
- å
±éãããžã§ã¯ãã®ãã¹ãŠã®ã¯ã©ã¹
- [Xamarin.Forms.Internals.Preserve(AllMembers = true)]
ãããŸã§ãã£ãŠããããããããããã¢ããªãèµ·åããã
ã ããããã§ã¯çµãããªãâŠâŠ
ç¡äºèµ·åããã
ãããç©èªã¯åžžã«ããããŒãšã³ããšã¯éããªãã
åäœç¢ºèªããããšãCosmosDBã®æ¥ç¶ã§ãšã©ãŒãåºããåºåã衚瀺ãããªãããªã©ããã€ãã®äžå ·åãèŠã€ãã£ãã
ãã³ããŒãŒãŒãŒãŒãŒã£ããšå«ã³ããæ°æã¡ãæãããŸãã²ãšã€ã²ãšã€æœ°ããŠããããšé ãåãæ¿ããããšæã£ãã
ã ãå·éã«ãªãããã®æç¹ã§ã©ãã»ã©ããã±ãŒãžãµã€ãºã¯å°ãããªã£ãŠããã®ã ãããšç¢ºèªãããšããããã3MBãâŠâŠã
ããã ããã£ãŠããããªçšåºŠãããšãŸãè±åã
ãããŠãããšã©ãŒã朰ã = åé€ãããã³ãŒããæ®ãããã«ãããããã ã
ããããããã«ããã±ãŒãžãµã€ãºã¯å€§ãããªãã
ãŸãå°æ¥çãªããšãèããŠã¿ãã
ãã®å ããã£ãšæ©èœè¿œå çã§ã³ãŒããNuGetã远å ãããããã ããã
ãã®ãã³ã«ãä»åã®äœæ¥ãå¿ããè¡ãå¿ èŠãããã
ã¢ããªãµã€ãºãå°ãã§ãå°ããã»ãããŠãŒã¶ã«ãšã£ãŠè¯ãããšã
ã ããã³ã¹ãããªã¹ã¯ã«å¯Ÿããã¡ãªããå°ãªãããããªããã
æ¶ã®çµè«
ãšããããšã§ããR8 Shrinkerãããã³ããã«Linkerãã¯ããã£ã¡ãé 匵ãããããæãããããããããããšãšããã
ããŠã³ããŒãããŠããããŠãŒã¶ã®çããŸã®ã®ã¬ã奪ã£ãŠç³ããããªãã
wi-fiãããå Žæã§ããŠã³ããŒããããã¢ããããŒãããŠãããããšãç¥ã£ãŠããã
æè¡ã®è©±ãªã®ã«æåŸã¯ç¥ãã ã
Visual Studioã®ãšã³ã¿ãŒãã©ã€ãºãšãã£ã·ã§ã³ã²ããããŠãAOTïŒLLVMã䜿ãã°æ¥œã«ã¡ã£ãããªã£ããããã®ã ãããã
ã§ã$250/æãšãå人éçºã«ã¯å³ããã
ã»ãã«äœãè¯ãæ¹æ³ã¯ç¡ãã ãããã
ãããåããªæ¹ãããã£ããã£ããæããŠããã ãããšãææ©ãã¡ãã«åãã£ãŠæ¯æ¥ããããæè¬ã®ç¥ããæ§ããããšããçŽæããã
以äžãããã°ã©ãã³ã°ã¯ç¥ããã®å·»ãã