I am extending the Messenger plugin with functionality, which will make it possible to pass messages on the main thread instead of everything happening on a background thread.
I have extended BaseSubscription
with a bool
for knowing that this subscription needs to be messaged on the main thread. Now I need to be able to use InvokeOnMainThread
from the TypedInvoke
methods in the actual implementations of the subscriptions.
When I look in the referenced MvvmCross assembly I see that Cirrious.MvvmCross.ViewModels.MvxMainThreadDispatchingObject
contains the InvokeOnMainThread
method, so the question is how do I get hold of that object so I can invoke the method?
The easiest way to get hold of the UI thread is to inherit from MvxMainThreadDispatchingObject
If the hierarchy won't let you, then the next easiest way is to add the IMvxServiceConsumer
marker interface and to then use the GetService<T>
extension method:
public class MyClass
: MyBaseClass
, IMvxServiceConsumer
{
// ...
private bool DoStuff(Action stuff)
{
var dispatcherProvider = this.GetService<IMvxMainThreadDispatcherProvider>();
var dispatcher = dispatcherProvider.Dispatcher;
if (dispatcher == null) {
return false;
}
return dispatcher.RequestMainThreadAction(action);
}
}
The GetService<T>()
static method could also be invoked as a static method if preferred (if you don't want to use IMvxServiceConsumer
).
Notes:
if you are sharing code between 'Apps' and 'Services'/'BackgroundAgents' you need to be very careful to check for error conditions - there isn't always a UI thread available.
Android is particularly special - the UI thread can only really be accessed via the current foreground activity - currently MvvmCross tracks this (via Activity OnStart and OnResume hooks) in the IMvxAndroidCurrentTopActivity
service - but there's no guarantee that you will always have a foreground activity running - e.g. if your code ever loads non-MvvmCross activities then obviously MvvmCross won't know about these.
You should not hold on to references to the Dispatcher - if you do, then you may be holding Android Activity's in memory beyond their natural lifetimes
I guess DoStuff
could be put into an extension method too - perhaps I'll add that in v3 (https://github.com/slodge/MvvmCross/issues/150)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With