Supercharge Your Xamarin.Mac Application Startup Time

Startup performance matters, as it’s the first feature users come across when using your application. In this post, we’ll walk through some recent samples that improve Xamarin.Mac startup times, especially for large applications, featuring a few build options that change startup time drastically, including one that cuts startup time by 77ms or about 15%.

Let’s start with the SourceWriter, a simple but full Xamarin.Mac application sample that provides a text editor with code completion and syntax highlighting.

Launching a Debug build takes around a half a second, which isn’t bad, but is difficult to measure manually. By applying the technique from this sample and averaging five launches of the application, we can measure an average startup time of 574ms.

To determine how much overhead is related to Debug, switching to Release configuration can drop the time to 454ms, a 20% + improvement! A vast majority of this improvement is due to the Static Registrar, which you can see by adding registrar:static to the MMP arguments (Project Options → Mac Build), giving 477ms.

Registrar Settings

To understand what the registrar settings are doing, we have to dig a bit under the hood. During startup, the Objective-C runtime needs to be informed of the various managed classes that derive from NSObject and the selectors they support. The three options for the registrar setting are Partial Static, Static, and Dynamic.

  • The Partial Static registrar uses reflection on user assemblies during startup and is the default for Debug builds.
  • The Static registrar scans all assemblies and generates code at build time, which is a significant performance improvement (17% in this example). In contrast, it also increases build time, which is why it’s only on by default for Release configurations.
  • There’s also a Dynamic registrar which reflects overall assemblies at startup, not just users assemblies. Previous to Xamarin.Mac 3.2, when the “Partial Static” registrar was introduced, this was the default for Debug configurations.

Compilation

Another job done at startup is a compilation of managed code from IL to machine code. While JIT compilation is incredibly fast in most cases, for large applications it can take up a significant percentage of startup time. Ahead of Time (AOT) compilation compiles assemblies to machine code (dylibs) during the build and bundles them inside the final application bundle.

Enabling AOT requires passing a command line argument via the “Additional MMP arguments” field in Mac Build. Full AOT options will be added to the Mac Build panel in Xamarin.Mac 4.2. The current options are as follows:

aot[=VALUE]          Specify assemblies that should be AOT compiled
                           - none - No AOT (default)
                           - all - Every assembly in MonoBundle
                           - core - Xamarin.Mac, System, mscorlib
                           - sdk - Xamarin.Mac.dll and BCL assemblies
                           - |hybrid after option enables hybrid AOT which
                           allows IL stripping but is slower (only valid
                           for 'all')
                            - Individual files can be included for AOT via +
                           FileName.dll and excluded via -FileName.dll

                           Examples:
                             --aot:all,-MyAssembly.dll
                             --aot:core,+MyOtherAssembly.dll,-mscorlib.dll

In the SourceWriter example, aot:all reduces startup time to a quick 377ms. This is below the 400-500 ms goal that many users will consider “instant,” and a good place to be.

While AOT compilation is great and can provide that last push to get under the desired performance window, it does have some drawbacks to consider. In SourceWriter, it increases build time by 40% and doubles the final application bundle size (i.e. 12 megs to 24 megs).

More Build Settings

Other build settings to consider are Target Framework and Linking mode. Linking can dramatically reduce application size by removing unused code, but is only available in some Target Framework configurations. Applications optimized with Linking are great candidates for AOT compilation.

Even after configuring build settings, your application still might miss your desired performance benchmarks. Consider reviewing the performance documentation and profile your application.

If you’re interested in Xamarin.Mac, Hello, Mac is a great place to get started. There are a number of tutorials covering macOS specific user interface controls and a wealth of samples to look at. The Xamarin.Mac forum community is also open for discussions and questions as well.

The post Supercharge Your Xamarin.Mac Application Startup Time appeared first on Xamarin Blog.

Replacing Services With Jobs in Android Oreo 8.0

Before Android 8.0, Android apps would start a service that ran almost indefinitely, even when the app was in the background. This service can be handy for the app, and easy for the developer to implement, but can also have a disastrous impact on a user’s device experience.

As an example of this, imagine a scenario where many applications want to perform work when a device is plugged in to charge. When this happens, Android dispatches the android.intent.action.ACTION_POWER_CONNECTED intent. All apps that have registered to respond to that intent will start up, demanding RAM, CPU time, and bandwidth. When this happens, it’s possible these simultaneous demands may exceed the available space on the device, and cause it to slow down. At this point, all a user knows is that they plugged in their device and it started exhibiting sluggish, unresponsive behavior, and may think there is something wrong with their phone or that they need to purchase more memory.

Android 8.0 has introduced new background execution limits that dramatically change how services work. When applications move into the background, any services they start will be granted several minutes to complete their work before the operating system terminates them. The Android Framework JobScheduler is one possible way to address this change for Xamarin.Android apps targeting Android 5.0 (API level 21) or higher.

The Android Framework JobScheduler is an API designed to run jobs—discrete, distinct units of work—in the background of various apps. The JobScheduler schedules which jobs will run at appropriate times according to conditions that can be set by the application. Going back to our original example of charging a device, the JobScheduler may schedule the jobs so that they run one after another, instead of all at once.

The ability to schedule and queue jobs make the JobScheduler perfect for tasks that are traditionally handled by long-running services, such as:

  • Downloading a file, but only when the device is connected to an unmetered (free) network.
  • When charging a device, make a series of thumbnail images from a collection of larger images.
  • If connected to the network, call a method on a web service using an exponential backoff algorithm between unsuccessful web service calls.

There are three important classes in the JobScheduler API:

  • JobScheduler: A system service that will run jobs scheduled by apps.
  • JobService: A class extended by applications and contains the code that runs as part of a job. The code for each job is contained in a class that extends the JobService class and requests the android.permission.BIND_JOB_SERVICE permission.
  • JobInfo: Holds information about the job that the JobScheduler needs in order to run a JobService. The JobInfo will tell the JobScheduler which JobService type to use, and which conditions must be met before the job can run. It also contains any parameters that the app must pass to the JobService. A JobInfo object isn’t directly instantiated, instead it’s created by using a JobInfo.Builder.

A JobService sub-class must override two methods:

  • OnStartJob: The method that a system invokes when the job is starting and runs on the main thread of the app. If the work is a small, easy task (less than 16 milliseconds), it may run on the main thread. However, lengthy tasks such as disk access or network calls must run asynchronously. OnStartJob should return "true" if it’s running work on another thread, while "false" should be returned if the all the work was performed within OnStartJob itself.
  •  OnStopJob: This method is called when the system has to prematurely terminate the job and provides the JobService a chance to perform any necessary cleanup. If the job should be rescheduled, it will return "true".

The following code shows a sample JobService type:

[Service(Name = "JobScheduleSample.FibonacciJob", Permission = "android.permission.BIND_JOB_SERVICE")]
public class FibonacciJob : JobService
{
   public override bool OnStartJob(JobParameters jobParams)
   {
      // Called by the operating system when starting the service.
      // Start up a thread, do work on the thread.
      return true;
   }

   public override bool OnStopJob(JobParameters jobParams)
   {
      // Called by Android when it has to terminate a running service.
      return false; // Don't reschedule the job.
   }
}

In order to schedule a job, it’s necessary for an app to use a JobInfo.JobBuilder to create a JobInfo object. The JobInfo.JobBuilder has a fluent interface and is used to collect meta-data, such as the type of JobService to instantiate and any conditions that should be met before the job is run. This snippet shows how to create a JobInfo class to run the FibonacciJob (from the example above) but only when the device is connected to an “unmetered” (free) network. The job shouldn’t run sooner than one second from being scheduled but should run within five seconds:

Java.Lang.Class javaClass = Java.Lang.Class.FromType(typeof(FibonacciJob);
ComponentName component = new ComponentName(context, javaClass);

JobInfo.Builder builder = new JobInfo.Builder(context, component)
                                     .SetMinimumLatency(1000)   // Wait at least 1 second
                                     .SetOverrideDeadline(5000) // But no longer than 5 seconds
                                     .SetRequiredNetworkType(NetworkType.Unmetered);
JobInfo jobInfo = builder.Build();

In the previous example, the context is any Android Context, such as an Activity. The parameter is a unique integer that identifies the job service to the JobScheduler.

The following C# extension method should help with creating a ComponentName for a given JobService subclass:

public static ComponentName GetComponentNameForJob<T>(this Context context) where T : JobService, new()
{
   Class javaClass = Class.FromType(typeof(T));
   return new ComponentName(context, javaClass);
}

Once a JobInfo created is created, the app can schedule a job. This code snippet will get a reference to the JobScheduler service and ask it to schedule the job identified in the jobInfo object:

JobScheduler jobScheduler = (JobScheduler)GetSystemService(JobSchedulerService);
int result = jobScheduler.Schedule(jobInfo);
if (result == JobScheduler.ResultSuccess)
{
   // The job was scheduled.
}
else
{
   // Couldn't schedule the job.
}

It’s also possible for the app to pass parameters to a service by packaging them up in a Bundle and then calling the JobInfo.SetExtras method. The Bundle is included with the JobParameters object passed to the JobService when OnStartJob is invoked. For example, this snippet will pass a value to a job:

// Bundle up parameters
var jobParameters = new PersistableBundle();
extras.PutLong("some_long_value", 10L);

// Put the Bundle with the parameters into the jobInfo.
JobInfo.Builder builder = new JobInfo.Builder(context, component)
                                     .SetExtras(extras);
JobInfo jobInfo = builder.Build();

To access this value, the JobService should read the .Extras property on the JobParameter object:

public override bool OnStartJob(JobParameters jobParams)
{
   long theValue = jobParams.Extras.GetLong("some_long_value", -1);

   // Job does something with the value.
}

Finally, when a JobService has finished its work (regardless of which thread the work is running on), it should call its own JobFinished() method. It’s important to call this method, because it tells the JobScheduler that the work is done and it’s safe to release any wake locks that were acquired for the JobService in the first place. This diagram illustrates how the JobService methods relate to each other and how they would be used:

The relationship of JobService method calls.

Now that you’ve seen the basics of the JobScheduler API, try using it in your Xamarin.Android application to replace a task done in a background service. This is a great opportunity to enhance the experience your user has with your applications and update to Android Oreo 8.0 all at once!

You can find a small sample on GitHub that shows the JobScheduler API in action. The sample calculates a Fibonacci number in a job and then passes that number back to an Activity.

Discuss this post in the forums.

The post Replacing Services With Jobs in Android Oreo 8.0 appeared first on Xamarin Blog.

Give the Visual Studio 2017 Version 15.5 Preview a Try!

With Visual Studio 2017 version 15.4 now stable and sporting some awesome new features, such as Xamarin Live integration, Android Oreo / iOS 11 support, and a smarter, smaller installation, it’s time to turn our attention to the next version of Visual Studio 2017, version 15.5! This upcoming release is now available as a preview which, like all Visual Studio previews, is a separate and sandboxed installation than your stable one. This means it’s completely safe to try without risking your production development environment.

In this blog post we will take a look at some of our favorite new features landing in the Visual Studio 2017 version 15.5 previews. Be sure to give the release a try and let us know how it works for you and your team!

Xamarin Live

Xamarin Live enables developers to continuously deploy, test, and debug their apps directly on iOS and Android devices. After downloading the Xamarin Live Player app from the App Store or Google Play, you can pair your device with Visual Studio and revolutionize the way you build your next app. And with the “Live Run” functionality, you also get a real-time preview of your XAML as you type! In this release we’re adding more integration for Xamarin Live with Visual Studio and enhancements to the Live Run functionality to make building XAML UIs natural and productive.

Live XAML Previewing

We know that developers are looking for easy ways to preview XAML and cut down on long debug-deploy-test cycles. The “Live Run” functionality allows you to preview changes to your XAML in real-time on a device as you type. Once you have entered a live run mode, Visual Studio will automatically re-deploy your XAML whenever the active document changes and render the entire context of the page, including the binding context and the codebehind! There is also a new context menu option (Tools > Xamarin Live Player > Live Run Current View ) and keyboard shortcut to make live running XAML fast and easy.

Check out the improved workflow for Debug and Live Run in Visual Studio 2017 version 15.5 below:

 

Deeper Integration with Visual Studio

Live Player devices act and feel just like regular emulator and device debug targets. Xamarin Live already supports breakpoints when debugging, and in this release we improved how the overall functionality integrates into Visual Studio. For example, it will now warn you when you attempt to perform an unsupported operation, such as live running an iOS app on an Android device, and suggest actions to resolve the issue. We’ve added a visual indication of the deployment status operation in the status bar as well so you know exactly where the deployment operation stands.

Finally, we’ve integrated Xamarin Live with the Console and Error windows in Visual Studio. If you log any output in your app (such as Console.WriteLine), it will now show in the console output while deployment errors will be surfaced in the Visual Studio Error window.

New Mac Connection Workflow

If you have ever built an iOS app with Xamarin on Windows then you know you must connect to a Mac in order to perform builds. So in this release we have added new functionality that improves the connection workflow so you can start building iOS apps in Visual Studio even faster.

Connection Status Indicator

You should always know the exact status of a connection attempt to the Mac, however previously the only way to know the status was to check for a “lock” icon in the Xamarin Mac Agent or a green icon in the Visual Studio toolbar. This didn’t provide any granularity to the status of a connection attempt so we’ve added a new UI for viewing the connection progress that provides more detail:

New connection workflow for the Xamarin Mac Agent.

Much, much, more!

These are only a few of the new features in Visual Studio 2017 version 15.5. This release contains so much more, including updated Xamarin SDKs for iOS and Android, lots of bug fixes, the integration of the Xamarin Android SDK Manager into the install, and improvements to our extension for accessibility and localization.

To get started with the previews today, download the Visual Studio Preview installer and select the Mobile .NET (Xamarin) workload just as you did for your stable installation. Remember, Visual Studio previews are installed side-by-side your current installation and are sandboxed from your production development environment.

If you decide you no longer want to use the preview, simply use the Visual Studio Installer to uninstall any preview instance. While your stable installation should not be affected by doing this, we do recommend running a “Repair” on your other installation afterwards as a precaution.

There’s so many reasons to try Visual Studio 2017 version 15.5, so give it a try and let us know what you think via Help -> Report a Problem in Visual Studio, on Developer Community, or reach out to me directly on Twitter.

The post Give the Visual Studio 2017 Version 15.5 Preview a Try! appeared first on Xamarin Blog.

CastleSoft adds Bitcoin support

CastleSoft is proud to announce support for Bitcoin payments.

Bitcoin is a worldwide cryptocurrency and digital payment system, and is the first decentralised digital currency.
Our integration allows simple access to the Bitcoin Digital Wallet, avoiding the hassle and costs of Bitcoin exchanges.

With Bitcoin, Alipay, WeChat and all major credit cards.
CastleSoft can provide a payment solution for your business.

 

CastleSoft adds Alipay and WeChat Pay support

CastleSoft is proud to announce support for Alipay and WeChat Pay.

Digital wallets are the payment method of choice in mobile-first markets like China.
Alipay, counts over 500 million users, while WeChat Pay — claims more than 600 million users.

Both parties dominate the mobile wallet ecosystem in China, with 92% market share between them.

By offering global support for Alipay and WeChat pay, we can help connect businesses in 25-plus countries to the hundreds of millions of Chinese consumers that actively use these payment methods.