-->
Jun 22, 2020 Visual Studio 2019 or Visual Studio 2017, any Windows edition. (Cloud Tools for Visual Studio does not support Visual Studio 2017 for Mac.) Cloud SDK; Create a new Windows VM to host your app: Navigate to the ASP.NET Framework image on the Google Cloud Marketplace. Go to the ASP.NET Framework image; Select Launch on Compute Engine. Download Visual Studio Community, Professional, and Enterprise. Try Visual Studio IDE, Code or Mac for free today.
Xamarin.Android has a few places to look when tracking down various bugs.These include:
Diagnostic MSBuild can contain additional information relating to packagebuilding and may contain some package deployment information.
To enable diagnostic MSBuild output within Visual Studio:
To enable diagnostic MSBuild output within Visual Studio for Mac/OS X:
To enable device deployment logging within Visual Studio:
Visual Studio for Mac always writes device deployment logs. FInding them isslightly more difficult; a AndroidUtils log file is created for everyday + time that a deployment occurs, for example: AndroidTools-2012-10-24_12-35-45.log.
%LOCALAPPDATA%XamarinStudio-{VERSION}Logs
.$HOME/Library/Logs/XamarinStudio-{VERSION}
.Android will write many messages to theAndroid Debug Log.Xamarin.Android uses Android system properties to control thegeneration of additional messages to the Android Debug Log. Androidsystem properties can be set through the setprop command within theAndroid Debug Bridge (adb):
System properties are read during process startup, and thus must beeither set before the application is launched or the application mustbe restarted after the system properties are changed.
Xamarin.Android supports the following system properties:
debug.mono.debug: If a non-empty string, this is equivalent to*mono-debug*
.
debug.mono.env: A pipe-separated ('|') list of environmentvariables to export during application startup, before mono hasbeen initialized. This allows setting environment variables thatcontrol mono logging.
Note
Since the value is '|'-separated, the value must havean extra level of quoting, as the `adb shell` command willremove a set of quotes.
Note
Android system property values can be no longer than 92characters in length.
Example:
debug.mono.log: A comma-separated (',') list of components thatshould print additional messages to the Android Debug Log. Bydefault, nothing is set. Components include:
Note
These are extremely verbose. Do not enable unless you really need to.
debug.mono.trace: Allows setting the mono --trace=PROPERTY_VALUE
setting.
bin
and obj
Xamarin.Android has suffered in the past from a situation such as:
Clean
, Rebuild
, or manually delete your bin
and obj
directories.We are heavily invested into fixing problems such as these due to their impact on developer productivity.
If a problem such as this happens to you:
Before deleting your bin
and obj
directories, zip them up and save them for later diagnosis if needed. You can probably merely Clean
your Xamarin.Android application project to get things working again.
This error occurs due to an incompatibility with Visual Studio.
Visual Studio 2017 Update 1 (version 15.1 or older) is only compatible with the System.ValueTuple NuGet 4.3.0 (or older).
Visual Studio 2017 Update 2 (version 15.2 or newer) is only compatible with the System.ValueTuple NuGet 4.3.1 (or newer).
Please choose the correct System.ValueTuple NuGet that corresponds with your Visual Studio 2017 installation.
GC component messages can be viewed by setting the debug.mono.log systemproperty to a value that contains gc.
GC messages are generated whenever the GC executes and provides informationabout how much work the GC did:
Additional GC information such as timing information can be generated bysetting the MONO_LOG_LEVEL
environment variable to debug
:
This will result in (lots of) additional Mono messages, including thesethree of consequence:
In the GC_BRIDGE
message, num-objects
is thenumber of bridge objects this pass is considering, and num_hash_entries
is the number of objects processed during thisinvocation of the bridge code.
In the GC_MINOR
and GC_MAJOR
messages, total
is the amount of time while the world is paused (no threadsare executing), while bridge
is the amount of time taken in thebridge processing code (which deals with the Java VM). The world is not paused while bridge processing occurs.
In general, the larger the value of num_hash_entries
,the more time that the bridge
collections will take, and thelarger the total
time spent collecting will be.
To enable Global Reference loggig (GREF) logging, the debug.mono.logsystem property must contain gref, e.g.:
Xamarin.Android uses Android global references to provide mappings betweenJava instances and the associated managed instances, as when invoking a Javamethod a Java instance needs to be provided to Java.
Unfortunately, Android emulators only allow 2000 global references to existat a time. Hardware has a much higher limit of 52000 global references. Thelower limit can be problematic when running applications on the emulator, soknowing where the instance came from can be very useful.
Note
The global reference count is internal to Xamarin.Android,and does not (and cannot) include global references taken out by other nativelibraries loaded into the process. Use the global reference count as anestimate.
There are four messages of consequence:
In all messages, The grefc value is the count of global referencesthat Xamarin.Android has created, while the grefwc value is the countof weak global references that Xamarin.Android has created. The handleor obj-handle value is the JNI handle value, and the character afterthe ' /' is the type of handle value: /L for local reference, /G for global references, and /W for weak globalreferences.
As part of the GC process, global references (+g+) are converted into weakglobal references (causing a +w+ and -g-), a Java-side GC is kicked, and thenthe weak global reference is checked to see if it was collected. If it's stillalive, a new gref is created around the weak ref (+g+, -w-), otherwise the weakref is destroyed (-w).
There is one 'interesting' wrinkle here: on targets running Android prior to4.0, the gref value is equal to the address of the Java object in the Android runtime'smemory. (That is, the GC is a non-moving, conservative, collector, and it'shanding out direct references to those objects.) Thus after a +g+, +w+, -g-,+g+, -w- sequence, the resulting gref will have the same value as the originalgref value. This makes grepping through logs fairly straightforward.
Android 4.0, however, has a moving collector and no longer hands out directreferences to Android runtime VM objects. Consequently, after a +g+, +w+, -g-, +g+, -w-sequence, the gref value will be different. If the object survivesmultiple GCs, it will go by several gref values, making it harder to determinewhere an instance was actually allocated from.
You can query both the GREF and WREF counts by querying the JniRuntime
object.
Java.Interop.JniRuntime.CurrentRuntime.GlobalReferenceCount
- Global Reference Count
Java.Interop.JniRuntime.CurrentRuntime.WeakGlobalReferenceCount
- Weak Reference Count
The Android Debug Logs may provide additional context regarding any runtime errors you'reseeing.
Alternatively, 'My app runs 10x faster with the Debug build than with theRelease build!'
Xamarin.Android supports multiple device ABIs: armeabi,armeabi-v7a, and x86. Device ABIs can be specified within ProjectProperties > Application tab > Supported architectures.
Debug builds use an Android package which provides all ABIs, and thus willuse the fastest ABI for the target device.
Release builds will only include the ABIs selected in the Project Propertiestab. More than one can be selected.
armeabi is the default ABI, and has the broadest device support. However, armeabi doesn't support multi-CPU devices and hardwarefloating-point, amont other things. Consequently, apps using the armeabi Releaseruntime will be tied to a single core and will be using a soft-floatimplementation. Both of these can contribute to significantly slower performancefor your app.
If your app requires decent floating-point performance (e.g. games), youshould enable the armeabi-v7a ABI. You may want to only support the armeabi-v7a runtime, though this means that older devices which onlysupport armeabi will be unable to run your app.
There are 2 downloads available from Google for the Android SDK for Windows.If you choose the .exe installer, it will write registry keys that tellXamarin.Android where it was installed. If you choose the .zip file and unzip ityourself, Xamarin.Android does not know where to look for the SDK. You can tellXamarin.Android where the SDK is in Visual Studio by going toTools > Options > Xamarin > Android Settings:
Sometimes you will attempt to deploy your application to a device, butthe device you want to deploy to isn't shown in the Select Devicedialog. This can happen when the Android Debug Bridge decides to go onvacation.
To diagnose this issue, find theadb program,then run:
If your device isn't present, then you need to restart the Android Debug Bridge server so that your device can be found:
HTC Sync software may prevent adb start-server from workingproperly. If the adb start-server command doesn't print out whichport it's starting on, please exit the HTC Sync software and tryrestarting the adb server.
This means that your PATH does not contain the directory where the JavaSDK's bin directory is located. Check that you followed those stepsfrom theInstallation guide.
To help you debug this problem, go into Visual Studio and change theMSBuild verbosity level, to do this, select: Tools > Options >Project and Solutions > Build and Run > MSBuild Project BuildOutput Verbosity and set this value to Normal.
Rebuild, and check Visual Studio's Output pane, which should contain the full error.
This occurs when you don't start the emulator from within VisualStudio. When starting the emulator outside of Visual Studio, you needto pass the -partition-size 512
options, e.g.
Ensure you use the correct simulator name, i.e.the name you used when configuring the simulator.
Android package names must contain a period ('.'). Edit your package name so that it contains a period.
A 'shared library' in this context is not a native sharedlibrary (libfoo.so) file; it is instead a library that must beseparately installed on the target device, such as Google Maps.
The Android package specifies which shared libraries are required withthe <uses-library/>
element. If a required library is not presenton the target device (e.g. //uses-library/@android:required
istrue, which is the default), then package installation will fail withINSTALL_FAILED_MISSING_SHARED_LIBRARY.
To determine which shared libraries are required, view the generatedAndroidManifest.xml file (e.g.objDebugandroidAndroidManifest.xml) and look for the<uses-library/>
elements. <uses-library/>
elements can be addedmanually in your project's PropertiesAndroidManifest.xml file and via theUsesLibraryAttribute custom attribute.
For example, adding an assembly reference toMono.Android.GoogleMaps.dll will implicitly add a <uses-library/>
for the Google Maps shared library.
Android packages have three requirements:
Thus, imagine this scenario:
When this happens, package installation will fail with aINSTALL_FAILED_UPDATE_INCOMPATIBLE error, because the package namedidn't change while the signing key did. TheAndroid Debug Logwill also contain a message similar to:
To fix this error, completely remove the application from your devicebefore re-installing.
When an Android package is installed, it is assigned a user id (UID).Sometimes, for currently unknown reasons, when installing over an alreadyinstalled app, the installation will fail with INSTALL_FAILED_UID_CHANGED
:
To work around this issue, fully uninstall the Android package, either byinstalling the app from the Android target's GUI, or using adb
:
DO NOT USEadb uninstall -k
, as this will preserve application data,and thus preserve the conflicting UID on the target device.
Does the Android Debug Log output will contain a message similar to:
If so, there are two possible causes for this:
The .apk doesn't provide an ABI that the target device supports.For example, the .apk only contains armeabi-v7a binaries, and thetarget device only supports armeabi.
An Android bug. Ifthis is the case, uninstall the app, cross your fingers, andreinstall the app.
To fix (1), edit the Project Options/Properties andadd support for the required ABI to the list of Supported ABIs. Todetermine which ABI you need to add, run the following adb commandagainst your target device:
The output will contain the primary (and optional secondary) ABIs.
This generally means you have an HP computer and the environmentvariable “Platform” has been set to something like MCD orHPD. This conflicts with the MSBuild Platform property that isgenerally set to “Any CPU” or “x86”. You willneed to remove this environment variable from your machine beforeMSBuild can function:
Restart Visual Studio or Visual Studio for Mac and try to rebuild. Thingsshould now work as expected.
Xamarin.Android 4.x doesn't properly marshal nested generic typesproperly. For example, consider the following C# code usingSimpleExpandableListAdapter:
The problem is that Xamarin.Android incorrectly marshals nested generictypes. The List<IDictionary<string, object>>
is being marshaled to ajava.lang.ArrrayList,but the ArrayList
is containing mono.android.runtime.JavaObject
instances (which reference the Dictionary<string, object>
instances)instead of something that implementsjava.util.Map,resulting in the following exception:
The workaround is to use the providedJava Collection types insteadof the System.Collections.Generic
types for the “inner”types. This will result in appropriate Java types when marshaling theinstances. (The following code is more complicated than necessary inorder to reduce gref lifetimes. It can be simplified to altering theoriginal code via s/List/JavaList/g
ands/Dictionary/JavaDictionary/g
if gref lifetimes aren't a worry.)
This will be fixed in a future release.
Occasionally theAndroid Debug Logwill mention NullReferenceExceptions that “cannot happen,”or come from Mono for Android runtime code shortly before the app dies:
or
This can happen when the Android runtime decides to abort the process,which can happen for any number of reasons, including hitting thetarget's GREF limit or doing something “wrong” with JNI.
To see if this is the case, check the Android Debug Log for a messagefrom your process similar to:
The Android runtime's JNI layer only supports a limited number of JNIobject references to be valid at any given point in time. When thislimit is exceeded, things break.
The GREF (global reference) limit is 2000 references in the emulator, and ~52000 references on hardware.
You know you're starting to create too many GREFs when you see messages such as this in the Android Debug Log:
When you reach the GREF limit, a message such as the following is printed:
In the above example (which, incidentally, comes frombug 685215) theproblem is that too many Android.Graphics.Point instances are beingcreated; seecomment #2for a list of fixes for this particular bug.
Typically, a useful solution is to find which type has too manyinstances allocated – Android.Graphics.Point in the above dump– then find where they're created in your source code and disposeof them appropriately (so that their Java-object lifetime isshortened). This is not always appropriate (#685215 is multithreaded,so the trivial solution avoids the Dispose call), but it's the firstthing to consider.
You can enableGREF Loggingto see when GREFs are created and how many exist.
If you hand-roll JNI code, it's possible that the types won't matchcorrectly, e.g. if you try to invoke java.lang.Runnable.run
on a typethat doesn't implement java.lang.Runnable
. When this occurs, therewill be a message similar to this in the Android Debug Log:
To use C# dynamic in your application or library, you have to addSystem.Core.dll, Microsoft.CSharp.dll and Mono.CSharp.dll to yourproject.
It is likely that your application project does not have referencesto System.Core.dll, Microsoft.CSharp.dll or Mono.CSharp.dll. Makesure those assemblies are referenced.
In the first preview, those assemblies were excluded unless typesin each assembly are explicitly used by the application code. Seethe following for a workaround:http://lists.ximian.com/pipermail/mo...il/009798.html
When deploying an app built withAOT+LLVMon x86-based devices, you may see an exception error message similar tothe following:
This is a known issue – the workaround is to disable LLVM.
-->Although there are many app markets for distributing an application, GooglePlay is arguably the largest and most visited store in the world for Androidapps. Google Play provides a single platform for distributing, advertising,selling, and analyzing the sales of an Android application.
This section will cover topics that are specific to Google Play, such asregistering to become a publisher, gathering assets to help Google Play promoteand advertise your application, guidelines for rating your application on GooglePlay, and using filters to restrict the deployment of an application to certaindevices.
To distribute an application through Google Play, a developer account must becreated. This only needs to be performed once, and does involve a one time feeof $25 USD.
All applications need to be signed with a cryptographic key that expiresafter October 22, 2033.
The maximum size for an APK published on Google Play is 100MB. If anapplication exceeds that size, Google Play will allow extra assets to bedelivered through APK Expansion Files. Android Expansion files permitthe APK to have 2 additional files, each of them up to 2GB in size. Google Playwill host and distribute these files at no cost. Expansion files will bediscussed in another section.
Google Play is not globally available. Some locations may not be supportedfor the distribution of applications.
To publish applications on Google play, it is necessary to have apublisher account. To sign up for a publisher account follow these steps:
Google Play does not support all countries in the world. The most up-to-datelists of countries can be found in the following links:
Supported Locations for Developer & Merchant Registration – This is a list of all countries where developers may register as merchants and sell paid applications.
Supported Locations for distribution to Google Play users – This is a list of all countries where applications may be distributed.
To effectively promote and advertise an application on Google Play,Google allows developers to submit promotional assets such as screenshots,graphics, and video to be submitted. Google Play will then use those assets toadvertise and promote the application.
A launcher icon is a graphic that represents an application. Each launcher iconshould be a 32-bit PNG with an alpha channel for transparency. An applicationshould have icons for all of the generalized screen densities as outlined in thelist below:
Launcher icons are the first things that a user will see of applicationson Google Play, so care should be taken to make the launcher icons visuallyappealing and meaningful.
Tips for Launcher Icons:
Simple and uncluttered– Launcher icons should be keptsimple and uncluttered. This means excluding the name of theapplication from the icon. Simpler icons will be more memorable,and will be easier to distinguish at the smaller sizes.
Icons should not be thin– Overly thin icons will notstand out well on all backgrounds.
Use the alpha channel– Icons should make use of thealpha channel, and should not be full-framed images.
Applications on Google Play require a high fidelity version of theapplication icon. It is only used by Google Play, and does not replace theapplication launcher icon. The specifications for the high-resolution iconare:
The Android Asset Studiois a helpful tool for creating suitable launcher icons and thehigh-resolution application icon.
Google play requires a minimum of two and a maximum of eight screenshots foran application. They will be displayed on an application's details page inGoogle Play.
The specs for screenshots are:
This is an optional image used by Google Play:
Used by the featured section of Google Play. This graphic may be displayedalone without an application icon.
This is a URL to a YouTube video showcasing the application. The video shouldbe 30 seconds to 2 minutes in length and showcase the best parts of yourapplication.
Xamarin Android 7.0 introduces an integrated workflow for publishingapps to Google Play from Visual Studio. If you are using a version ofXamarin Android earlier than 7.0, you must manually upload your APK viathe Google Play Developer Console. Also, you must have at least one APKalready uploaded before you can use the integrated workflow. If youhave not yet uploaded your first APK, you must upload it manually. Formore information, seeManually Uploading the APK.
Creating a New Certificate,explained how to create a new certificate for signing Android apps. Thenext step is to publish a signed app to Google Play:
InArchive for Publishing,the Distribution Channel dialog presented two choices fordistribution: Ad Hoc and Google Play. If the SigningIdentity dialog is displayed instead, click Back to return to theDistribution Channel dialog. Select Google Play:
In the Signing Identity dialog, select the identity created inCreating a New Certificateand click Continue:
In the Google Play Accounts dialog, click the + button to add a new Google Play Account:
In the Register Google API Access dialog, you must provide theClient ID and Client secret that provides API access to your GooglePlay Developer account:
The next section explains how to create a new Google API project and generate theneeded Client ID and Client secret.
Visual Studio for Mac has an integrated workflow for publishingapps to Google Play.
Creating a New Certificate,discussed creating a new certificate for signing Android apps. Thefollowing steps outline how to publish a Xamarin.Android app to GooglePlay:
In Archive for Publishing,the Sign and Distribute... dialog presented two choices fordistribution. Select Google Play and click Next:
In the Google Play API Account dialog, you must provide the ClientID and Client secret that provides API access to your Google PlayDeveloper account:
The next section explains how to create a new Google API project and generatethe needed Client ID and Client secret.
First, sign into yourGoogle Play Developer account.If you do not already have aGoogle Play Developer account, see Get Started withPublishing.Also, the Google Play Developer API Getting Startedexplains how to use the Google Play Developer API. After you sign intothe Google Play Developer Console, click CREATE APPLICATION:
After creating the new project, it will belinked to your Google Play Developer Console account.
The next step is to create an OAuth Client for the app (if one has notalready been created). When users request access to their privatedata using your app, your OAuth Client ID is used to authenticate your app.
Go to the Settings page.
In the Settings page, select API access and click CREATE OAUTH CLIENT to create a new OAuth client:
After a few seconds, a new Client ID is generated. Click View inGoogle Developers Console to see your new Client ID in the GoogleDeveloper's Console:
The Client ID is displayed along its name and creation date. Click theEdit OAuth Client icon to view the Client secret for your app:
The default name of the OAuth client is Google Play AndroidDeveloper. This can be changed to the name of Xamarin.Android app, or any suitable name. In this example, theOAuth Client name is changed to the name of the app, MyApp:
Click Save to save changes. This returns to the Credentials page where to download the credentials by clicking on the Download JSON icon:
This JSON file contains the Client ID and Client secret that you can cutand paste into the Sign and Distribute dialog in the next step.
Use the Client ID and Client secret to complete the Google Play API Account dialog inVisual Studio for Mac. It is possible to give the account a description – this makesit possible to register more than one Google Play account and upload future APK's todifferent Google Play accounts. Copy the Client ID and Client secret to this dialogand click Register:
A web browser will open and prompt you to sign into your Google Play AndroidDeveloper account (if you are not already signed in). After you sign in, thefollowing prompt is displayed in the web browser.Click Allow to authorize the app:
After clicking Allow, the browser reports Received verificationcode. Closing... and the app is added to the list of Google PlayAccounts in Visual Studio. In the Google Play Accounts dialog,click Continue:
Next, the Google Play Track dialog is presented. Google Play offersfive possible tracks for uploading your app:
Choose which Google Play track will be used for uploading the app and click Upload.
For more information about Google Play testing, seeSet up open/closed/internal tests.
Next, a dialog is presented to enter the password for the signing certificate.Enter the password and click OK:
The Archive Manager displays the progress of the upload:
When the upload finishes, completion status is shown in the lowerleft hand corner of Visual Studio:
If you do not see your custom track when selecting a Google Play track, make sure you have created a release for that track on the Google Play Developer Console. For instructions on how to create a release, see Prepare & roll out releases.
Note that one APK must have already been submitted to the Google Playstore before the Publish to Google Play will work. If an APK is notalready uploaded the Publishing Wizard will display the following errorin the Errors pane:
When this error occurs, manually upload an APK (such as an Ad Hoc build) viathe Google Play Developer Console and use the Distribution Channeldialog for subsequent APK updates. For more information, seeManually Uploading the APK. The version code of the APK must change with each upload, otherwise the following error will occur:
To resolve this error, rebuild the app with a different version numberand resubmit it to Google Play via the Distribution Channel dialog.
Use the Client ID and Client secret to complete the Google Play API Account dialog inVisual Studio for Mac. It is possible to give the account a description – this makesit possible to register more than one Google Play account and upload future APK's todifferent Google Play accounts. Copy the Client ID and Client secret to this dialogand click Register:
If the Client ID and Client secret are accepted, a RegistrationSuccessful message is displayed. Click Next:
In the Google Play Account dialog, select a Google account and a trackfor uploading the application:
Google Play offers five possible tracks for uploading your app:
For more information about Google Play testing, see Set upalpha/beta tests.
Next, choose a signing identity to that will be used to sign the app.Select Use Existing Key to use an existing signingidentity, otherwise consult the guideCreating a New Certificatefor information about creating a new key. After you have selected acertificate to sign the application, click Next:
At this point the app can be uploaded to Google Play. The Publish to Google Play dialog summarizes information about your app – click Publish to publish your app to Google Play:
If you do not see your custom track when selecting a Google Play track to upload your app to, make sure you have created a release for that track on the Google Play Developer Console. For instructions on how to create a release, see Prepare & roll out releases.
Note that one APK must have already been submitted to the Google Playstore before the Publish to Google Play will work. If an APK is not uploaded the following error may occur:
Google Play requires you to manually upload your first APK for this app. You can use an ad-hoc APK for this.
or
No application was found for the given package name. [404]
To resolve this error, manually upload an APK (such as an Ad Hoc build) via the GooglePlay Developer Console and use the Publish to Google Play dialog forsubsequent APK updates. For information about how to manually upload an APK, seeManually Uploading the APK.