Xamarin.android MvvmCross-Realm从错误线程访问
例外情况 MainViewModel中不正确线程的领域访问 应用程序流程 SplashScreen>Main活动(例外) main活动Xamarin.android MvvmCross-Realm从错误线程访问,xamarin.android,realm,mvvmcross,viewmodel,Xamarin.android,Realm,Mvvmcross,Viewmodel,例外情况 MainViewModel中不正确线程的领域访问 应用程序流程 SplashScreen>Main活动(例外) main活动 public class MainActivity : MvxAppCompatActivity<MainViewModel>,ViewPager.IOnPageChangeListener,View.IOnTouchListener { protected override void OnCreate(Bundle save
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();
}
public类main活动:mvxappcompativity,ViewPager.IOnPageChangeListener,View.IOnTouchListener
{
创建时受保护的覆盖无效(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_教程);
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;
}
}
}
[AddNotifyPropertyChangedInterface]
公共类主视图模型:MvxViewModel
{
私人领域(u领域),;
private bool isCompleted=false;
公共教程视图模型(IMvxNavigationService navigationService)
{
_realm=Mvx.Resolve();
}
公共学校已完成{
得到
{
如果(_realm.All().Count()>0)
{
isCompleted=真;
}否则{
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>();
}
var key=ConfigManager.Settings?.DatabaseEcryption?.EncryptionKey;
if(key!=null&&key.Length>0)
{
config.EncryptionKey=密钥;
}
RegisterSingleton(()=>Realm.GetInstance(config));
Realm _Realm=Mvx.Resolve();
int count=_realm.All().count();
//RegisterCustomAppStart();
//应用程序启动
如果(计数>0)
{
RegisterNavigationServiceAppStart();
}
其他的
{
RegisterNavigationServiceAppStart();
}
下面的行抛出异常
_realm.All<IsFirstTimeAppStartUpRealm>().Count() > 0
\u realm.All().Count()>0
当通过SplashScreen时,应用程序总是崩溃,如果从MainActivity启动,它可以正常工作。
MvvmCross不保证应用程序启动在UI线程上运行。我很可能在线程池线程上运行
为了将一段代码封送到主线程,您可以解析IMvxMainThreadAsyncDispatcher
(>=6.1.x)或IMvxMainThreadDispatcher
,并请求在主线程上运行操作
:
var dispatcher=Mvx.Resolve();
整数计数;
等待dispatcher.ExecuteOnMainThreadAsync(()=>
{
count=_realm.All().count();
});
MvvmCross不保证应用程序启动在UI线程上运行。我很可能在线程池线程上运行
为了将一段代码封送到主线程,您可以解析IMvxMainThreadAsyncDispatcher
(>=6.1.x)或IMvxMainThreadDispatcher
,并请求在主线程上运行操作
:
var dispatcher=Mvx.Resolve();
整数计数;
等待dispatcher.ExecuteOnMainThreadAsync(()=>
{
count=_realm.All().count();
});
我有一个相当不错的方法可以从我的应用程序中去除这些代码气味。我最近刚刚开始使用Realm(到目前为止我很喜欢),但我一直使用ReactiveProperty来通知我的视图层VM更改,这真的很好
ReactiveProperty是.NET的一个Rx框架,它将您的属性包装在一个实例中,该实例根据需要生成您的INotifyPropertyChanged事件。您可以将所有这些属性链接在一起,因为它们相互依赖,事件会在其中传播。您不再有“notify of this,notify of this”的长列表财产变动后。
相反,您可以在代码的单个部分(通常是构造函数)中声明所有成员之间的相互依赖关系
因此,您可以将链的根放在领域线程上,并且所有相关通知都在该线程上发布
因此,我的ViewModels看起来像这样(伪代码):
类虚拟机
{
公共反应属性实体{get;set;}
公共ReactiveProperty是FirstLaunch{get;set;}
公共虚拟机(){
var syncCtx=SynchronizationContext.Current;
实体=新的反应属性();
//此属性将在syncCtx上触发其通知。
//记住将视图绑定到“IsFirstLaunch.Value”
IsFirstLaunch=Entity.SubscribeOn(syncCtx)。选择(x=>x.IsFirstLaunch)。ToReactiveProperty()
}
公共异步任务Init()
{
//让我们把领域实例放到syncCtx上。
syncCtx.Post(()=>{
Entity.Value=Realm.Find(typeof(AppStartInfo),0);//或任何您需要的内容。
});
}
}
我有一个相当不错的方法可以从我的应用程序中去除这些代码气味。我最近刚刚开始使用Realm(到目前为止我很喜欢),但我一直使用ReactiveProperty来通知我的视图层VM更改,这真的很好
ReactiveProperty是.NET的一个Rx框架,它将您的属性包装在一个实例中,该实例根据需要生成您的INotifyPropertyChanged事件。您可以将所有这些属性链接在一起,因为它们相互依赖,事件会在其中传播。您不再有“notify of this,notify of this”的长列表财产变动后。
相反,您可以在代码的单个部分(通常是构造函数)中声明所有成员之间的相互依赖关系
因此,您可以将链的根放在领域线程上,并且所有相关通知都在该线程上发布
因此,我的ViewModels看起来像这样(伪代码):
类虚拟机
{
公共反应属性实体{get;set;}
公共ReactiveProperty是FirstLaunch{get;set;}
公共虚拟机(){
var s
_realm.All<IsFirstTimeAppStartUpRealm>().Count() > 0
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.
});
}
}