例外
MainViewModel中错误线程的领域访问
申请流程
SplashScreen> MainActivity(Exception)
[Activity(MainLauncher = true
, Icon = "@mipmap/ic_launcher"
, Theme = "@style/Theme.Splash"
, NoHistory = true
, ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashScreen : MvxSplashScreenActivity
{
public SplashScreen()
: base(Resource.Layout.SplashScreen)
{
}
}
MainActivity
public class MainActivity : MvxAppCompatActivity<MainViewModel>,ViewPager.IOnPageChangeListener,View.IOnTouchListener
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_tutorial);
if (ViewModel.IsCompletedOrNot)
ViewModel.OpenMainViewModel.Execute();
}
MainViewModel
[AddINotifyPropertyChangedInterface]
public class MainViewModel : MvxViewModel
{
private Realm _realm;
private bool isCompleted = false;
public TutorialViewModel(IMvxNavigationService navigationService)
{
_realm = Mvx.Resolve<Realm>();
}
public bool IsCompletedOrNot{
get
{
if (_realm.All<IsFirstTimeAppStartUpRealm>().Count() > 0)
{
isCompleted=true;
}else{
isCompleted = false;
}
return isCompleted;
}
}
}
App.CS
var key = ConfigManager.Settings?.DatabaseEcryption?.EncryptionKey;
if (key != null && key.Length > 0)
{
config.EncryptionKey = key;
}
Mvx.RegisterSingleton<Realm>(() => Realm.GetInstance(config));
Realm _realm = Mvx.Resolve<Realm>();
int count = _realm.All<IsFirstTimeAppStartUpRealm>().Count();
//RegisterCustomAppStart<CustomAppStart>();
// App start
if (count>0)
{
RegisterNavigationServiceAppStart<MainViewModel>();
}
else
{
RegisterNavigationServiceAppStart<OtherViewModel>();
}
下面的行引发异常。
_realm.All<IsFirstTimeAppStartUpRealm>().Count() > 0
通过SplashScreen进入应用程序时,它始终会崩溃,并且如果从MainActivity启动,则可以正常运行。
答案 0 :(得分:1)
MvvmCross不保证App启动在UI线程上运行。我很可能会在ThreadPool线程上运行。
为了将一段代码封送到主线程,您可以解析IMvxMainThreadAsyncDispatcher
(> = 6.1.x)或IMvxMainThreadDispatcher
并请求Action
在主线程上运行主线程:
var dispatcher = Mvx.Resolve<IMvxMainThreadAsyncDispatcher>();
int count;
await dispatcher.ExecuteOnMainThreadAsync(() =>
{
count = _realm.All<IsFirstTimeAppStartUpRealm>().Count();
});
答案 1 :(得分:0)
我有一种相当不错的方法,可以从应用程序中删除这些代码异味。我最近才开始使用Realm(到目前为止已喜欢它),但是我一直使用ReactiveProperty通知我的视图层VM更改-真的很好。
https://github.com/runceel/ReactiveProperty
ReactiveProperty是.NET的Rx框架,它将您的属性包装在一个实例中,该实例会根据需要生成INotifyPropertyChanged事件。您可以将所有这些属性链接在一起,因为它们彼此依赖,并且事件会在整个属性中传播。属性更改后,您将不再具有这些“通知此,通知该”的长列表。 相反,您在代码的单个部分(通常是构造函数)中声明所有成员如何相互依赖
因此,您可以将链的根放置在Realm线程上,所有相关的通知都将发布在该线程上。
所以,我的ViewModel看起来像这样(伪代码):
class VM
{
public ReactiveProperty<AppStartInfo> Entity { get; set; }
public ReactiveProperty<bool> IsFirstLaunch { get; set; }
public VM(){
var syncCtx = SynchronizationContext.Current;
Entity = new ReactiveProperty<AppStartInfo>();
// this property will fire its notifications on the syncCtx.
// remember to bind your view to "IsFirstLaunch.Value"
IsFirstLaunch = Entity.SubscribeOn(syncCtx).Select(x => x.IsFirstLaunch).ToReactiveProperty()
}
public async Task Init()
{
// let's get our realm instance on to the syncCtx.
syncCtx.Post(() => {
Entity.Value = Realm.Find(typeof(AppStartInfo), 0); // or whatever you need.
});
}
}