MvvmCross - Android: How to perform App initialization on Main Thread - xamarin.android

I have an Android application using MvvmCross. The App launches via an MvxSplashScreenActivity as the main launcher and I provided a setup class deriving from MvxAndroidSetup.
It seems however that my MvxAndroidSetup.CreateApp() override is called on a ThreadPool thread (see https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Droid/Views/MvxBaseSplashScreenActivity.cs#L79).
What is the best way to ensure certain parts of my App Initialization are performed on the MainThread?

Most of the modern platforms - WindowsStore, WindowsPhone and iOS - allow you to bundle a static Default.jpg (or similar) to entertain your users while your app starts.
Android doesn't do this - it simply launches your app using the Activity marked as the MainLauncher.
If your app needs to do some initialization work (as most MvvmCross apps do) then this leaves you with a choice - do you do that work on the UI thread (which then results in an unresponsive UI) or do you display a placeholder SplashScreen and then do the initialization work on the background thread.
This is what MvvmCross tries to allow you to do
it provides you with a splashscreen class
it overrides the OnCreate of the splashscreen to do the minimal work it can on the UI thread during the splashscreen OnCreate (during this time the UI is black which is horrible)
then it does the bulk of init on a threadpool thread - as #CheeseBaron has pointed out on MvxBaseSplashScreenActivity.cs#L79
The bulk of initialisation - loading types, starting services, recovering settings, loading language files, etc - shouldn't need to be done on the UI thread.
If there is some part of initialization that you need to do on the UI thread, then it's up to your app to work out how and when to marshal that work back to the UI - e.g.
by using MvxMainThreadDispatcher.cs
by deferring that task until a later time (e.g. using Lazy IoC which will be triggered by viewmodel creation)
by overriding the SplashScreen's OnInitialisationComplete method
However, obviously at no point should you try to marshal any long-lasting work onto the UI thread... the UI thread is for the UI, not for heavy calculation or for any blocking work.
You should aim to keep the UI responsive, even during startup.
Detailed note:
The above description covers the 'normal launch' of an app from e.g. the android Home page.
However, if you dive deeper, then this is not the only way an app can be started - it can also be started from push notifications, from recovering from being killed ("tombstoned" in WP speak) or from things like broadcast receivers.
In those situations, the MvvmCross app initialisation may occur in other ways than described above:
in the case of an MvxActivity being directly launched (e.g from push or after recovering from tombstoning), then the whole of Setup is currently run on the UI thread during the OnCreate of that activity - this isn't ideal and is something I would hope the framework can improve on in the future.
in the case of a background service starting, it's up to the app engineer to work out what to setup when - e.g. see Using MvvmCross from content providers and activities
One opportunity for an alternative startup route is to subclass the Android Application object - see http://developer.android.com/reference/android/app/Application.html

Related

Understanding when to use dispatch_get_main_queue and requiresMainQueueSetup by example

A while back I asked similar question here: Difference requiresMainQueueSetup and dispatch_get_main_queue?
I came back to it today and realised I did not grasp it completely yet. When we are writing react native modules for iOS there is dispatch_get_main_queue on ios side and requiresMainQueueSetup needed by react-native.
How and which one of these should be used for following packages and use cases?
asq-react-native-device - package that exports constants like bundle id
asq-react-native-sensors - package that allows to subscribe and receive data from device gyroscope and oher sensors
asq-react-native-google-sign-in - package tat exposes google sign in sdk
For all of these I receive warnings in my dev console i.e.
So I assume requiresMainQueueSetup needs to be used regardless for all packages? I struggle to grasp when it needs to be set to YES or NO however. None of the modules are ui components, google sign in one, however, opens up safari view controller to perform oAuth, does this mean value needs to be set to YES here?
Do I need to use dispatch_get_main_queue whenever I use any of react-native resolver / rejecter bridge methods?
While both methods are related to the way that RN interacts with your module, they are not the same.
+ (BOOL)requiresMainQueueSetup
This method determines if your module will be initialized on the main thread or not; in other words, if your module's constructor (init method) and the constantsToExport method will be called on the main thread.
- (dispatch_queue_t)methodQueue
This method is an override where you can tell RN which dispatch queue to use when calling your module's exported methods (exported using the RCT_EXPORT_METHOD macro). Returning dispatch_get_main_queue() here returns the main queue which belongs to the main thread, asking RN to invoke your exported methods on the main thread, but you can use any other custom dispatch queue if you have such requirement.
Main thread execution
If we're to simplify this, any operation that involves UI manipulation is required to be executed on the main thread or main dispatch queue. Even if your modules are not UI components there are other UI operations that can be executed from native modules, for example: presenting a view-controller (can be a system view-controller or a custom one)
As you see, all the warning that you get originate from the lack of requiresMainQueueSetup implementation, and it tells you the exact reason - a module is overriding the init or the constantsToExport method but doesn't specify if it wishes for it to be executed on the main thread. Up until now, modules that were overriding the init or the constantsToExport were initialized on the main thread by default, assuming that they might need access to UI elements or UIKit. In future RN versions this is going to change - these methods will get called on the main thread only if you explicitly say so.
The packages in question
It doesn't look like you're doing something in your init or constantsToExport that requires the main thread, but at the moment it's as if you are overriding requiresMainQueueSetup and returning YES. I recommend that you do override it and return NO, so you can test that everything works as expected and make sure that you won't have any surprises when RN defaults to this in your case in future RN versions.
Notice that even though these are not UI components, you sometimes do need the main thread when exported methods are called, like in asq-react-native-google-sign-in - the signIn methods are presenting and dismissing view-controllers. In this case you correctly override methodQueue and use the main queue for your exported methods.
Note that it's also possible to keep the method calls in RN background threads by not overriding methodQueue, and dispatch to the main queue yourself when necessary. For example:
dispatch_async(dispatch_get_main_queue(), ^{
[RCTPresentedViewController() dismissViewControllerAnimated:YES completion:nil];
});

SQLite.net exception on screen rotation on android 4.1+

I am currently working on a cross-platform application using Monodroid/Xamarin. It uses a SQLite.net database and at the moment I have only built the Android UI.
In the application there is a long running method on a background thread which does several database reads and writes.
I was testing this long running method on a Nexus 7 running android 4.2.2 and it seems as though after a second screen rotation, a SQLite exception is thrown and the application crashes.
The exception stack trace varies depending on when you rotate the screen but the exception is always object not set to an instance inside Prepare2.
The interesting part is when testing on Samsung Galaxy S2 running 4.1.2 an exception still occurs but it is a different exception.
Furthermore, testing on a Samsung Galaxy Tab 2 and emulators the error is not thrown at all and the method completes just fine.
Any ideas, hints, suggestions would be much appreciated.
As a side question - in all the cross platform applications i have seen using Xamarin - the database layer and or repository is always static - whats the reason for this?
Thanks everyone
It's hard to identify the problem from what you've written - would be easier if you'd included some code about how you are accessing the database from your app.
However, I suspect that the problem here will be due to some interaction between the lifecycle of your UI Activity and the way it interacts with the SQLite database.
By default, when you rotate an Activity, then the existing instance is destroyed and a new one is created - your old Activity will be called to store its state in SaveInstanceState and your new rotated Activity will get called with a bundle in OnCreate.
This is why the database layer is often static/singleton in the samples - it's an easy way to allow the same database instance to be shared by multiple Activities/Components.
I guess that your Activity is doing something with the database during OnCreate - and that this is being called after each rotation/creation? Alternatively maybe your long-running method is trying to do something after the Activity that's hosting it has been finished and disposed?
In the end, this turned out to be a issue with mulithreading and Linq not playing well together. Thanks to Stuart for his answer.

iOS lifecycle: what happens before UIApplication runs?

I have a question that I can't really answer, so I wonder if someone may shed some light here.
Basically I am interested in knowing what is going on in iOS before and while I run an app...but from the OS perspective.
I've seen a lot of posts regarding what happens when the user tap on an app in the main screen, but I am interested in knowing basically what happens behind the scenes, before that the app takes control and main runs the singleton for UIApplication. And also once that the app is running, is the whole OS blocked in the main run loop of the app or something else is going on?
In particular, I would like to understand who creates the process where UIApplication will run (so the whole app will run inside that process, I assume).
Also would like to know what is the OS doing when for example, I open a connection in an app...since I see that a new thread is created (looking at a crash report I see a bunch of threads running, not just the main one), but I don't get where and who creates them (UIApplication itself?, where they running already before launching the app?).
Hope that the question is clear; I've search all over to find info but all that I get is that when you tap an app, main() runs and calls UIApplication,which takes control, deal with the delegate and views and so on...but what is going in the OS is a mystery.
Is there any resource related to the iOS part? Thanks!
The operating system of the iPhone works really similar to any other modern operating system. There is a kernel which provides low level functions, an API that provides high level functions (either to applications either to the OS itself) and so on.
There are a lot of processes always alive in the OS itself, just think about the fact that the device is able to receive notifications, receive calls, manage connections and whatever it needs to run.
When you launch an application the only thing that changes is that a process is launched and the control of it is given to the application.
And also once that the app is running, is the whole OS blocked in the main run loop of the app or something else is going on?
The whole OS is not blocked, the process launched is just scheduled together with many other processes that constantly run. This is achieved by multi-tasking.
In particular, I would like to understand who creates the process where UIApplication will run (so the whole app will run inside that process, I assume).
The process is created by the OS itself, which istantiates a new process structure to manage the just launched application and schedule it (with a high priority since it will run in foreground).
(UIApplication itself?, where they running already before launching the app?).
Threads are similar to processes in the sense that they have their code and they actually do something but a thread is lightweight because many thread can be managed by just one process. This mean that your application (or an API call) can create a thread which will run together with the main thread of your application and manage their operations but all these thread will share the same CPU allocation time and the same memory space and whatever. Actually Cocoa hides many of the details from a developer point of view, so that you don't care exactly about which threads are automatically started by the application because you don't need to: they are used to dispatch messages between objects, to manage asyncronous events and whatever.
But this is just the tip of the iceberg, before understanding how iOS works you should learn how a lower level infrastructure works, eg BSD Unix which is actually one of the ancestors of Darwin, which is the kernel on which iOS is operating. After understanding how it works you will undersand also how the infrastructure over it works (which is iOS + its API).

Does Native Extension code in Adobe AIR for IOS run in a separate CPU Thread?

I am building an IOS application using Flex 4.6 and AIR 3.3. I do have some Objective-C Libs that we will be using for processing audio, images, and video to create a new "video" file.
Being that we are doing all this processing on the device through a native extensions I am wondering if the user is going to see the app lock up till the processing is complete. In other words am I going to need to show them a progress bar and not allow them to do anything else in the app till this is complete OR does native extension code run in a separate thread ?
A secondary question would be ... If Native Code does not run in a separate thread is it possible to use the new Actionscript Workers to offload the processing to a separate thread ?
Your ANE can invoke a new thread, so your app shouldn't lock up.
This is a very good reference for developing native extensions: http://help.adobe.com/en_US/air/extensions/air_extensions.pdf
To quote the relevant part:
"The native C code can dispatch asynchronous events back to the ActionScript side of your extension. For example, an extension method can start another thread to perform some task. When the task in the other thread completes, that thread calls FREDispatchStatusEventAsync() to inform the ActionScript side of the extension. The target of the event is an ActionScript ExtensionContext instance."
Regarding the worker threads, yes, that's exactly what worker threads are for and from what I've read from the AS3 implementation, it'll work just like that. However, my best bet is that using an ANE will be faster for such tasks than using AS3. If you have the libs ready to roll, I'd just use an ANE and maybe try the worker threads once released for fun, might be easier to maintain if you're mostly developing in AS3.

Using GCD or not?

I have an iPhone app which pretty much is a mobile app for a website. Pretty much everything it does is call API methods from our server. The app retrieves the user's information, and keeps updating the server using the API.
My colleague and I had a discussion whether to introduce GCD to the downloading aspect on the app. My colleague argues that since the UI needs to wait for the download to complete before it can display the pictures, text or whatever, there is absolutely no need for GCD. My argument is that we should keep the main thread busy with UI rendering (even if there is no data), and introduce GCD to the app to create other threads for download.
Which argument is right here? In my case, if the UI renders with no data, will there be some sort of lag? Which will yield a cleaner, sleeker and faster app?
One argument would be : what will happen when the download fails and times out because there is a problem at the server end ?
Without GCD the app will remain blocked and will crash after a time
out since the UI can not be blocked for longer than 20 seconds.
With GCD the application remains functional but there will be no data
being downloaded and the application will not crash.
Other aspects to take into account are :
the thread safety of the objects that you are using
how you handle downloads that are no longer necessary because the user navigates away from the page
I don't think doing time consuming operations in the main thread is a good idea.
Even if user have to wait for the data te be downloaded before he can do anything meaningful, still he will not hope UI is blocked.
Let's assume you have a navigator view, and after user tap some button, you push a new view to it and start download something. If user suddenly decides he don't want to wait anymore, he tap the "back" button. If your downloading operation blocks UI, user will have to wait it to end, it's really bad.
A more appropriate question would perhaps be if you should download asynchronously or on the main thread for your app, since there are several different methods to download asynchronously on iOS (e.g. using NSThread, NSOperation or indeed GCD). An easy approach to achieve your goals could be to use the AFNetworking library. It makes multithreaded networking / internet code very easy to implement and understand.
Personally I'm very fond of GCD and recommend you learn it someday soon, though in itself it is not as suitable for asynchronous downloading compared to a library like AFNetworking (that uses GCD under the hood, I believe).
Here is a good read on using NSOperationQueues (that uses GCD behind the scenes) to download images. There is also some Github code you can check out. They have an elegant solution to pause downloads and enqueue new downloads when the user moves to different parts of your app.
http://eng.alphonsolabs.com/concurrent-downloads-using-nsoperationqueues/?utm_medium=referral&utm_source=pulsenews
Use GCD / NSOperationQueues as opposed to using NSThreads. You will have a good learning on core fundamentals and at the same time create a well architectured app. :)

Resources