MvvmCross + Android notifcation点击将viewmodel视为null

时间:2014-10-17 07:30:47

标签: c# xamarin xamarin.android android-notifications mvvmcross

我正在使用Xamarin和MvvmCross来创建跨平台应用程序。

在Android平台上,我需要显示通知。

在通知时,单击用户应登陆MainView屏幕。一切都按要求运作。

当应用程序从后台移除然后通知到达并且用户单击通知然后MainViewModel为空时,会出现问题。

以下是我显示通知的方式。

private void NotifyNotification(string title, string message)
        {


    var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;            
    int unique = 1;
    //uiIntent
    Intent uiIntent;

    uiIntent = new Intent(this, typeof(MainView));

    uiIntent.PutExtra("AppNotification", true);
    uiIntent.AddFlags(ActivityFlags.SingleTop | ActivityFlags.ClearTop);
    //pendingIntent
    var pendingIntent = PendingIntent.GetActivity(this, 0, uiIntent, PendingIntentFlags.OneShot);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(
                this);
    Notification notification = builder.SetContentIntent(pendingIntent)
                              .SetSmallIcon(Resource.Drawable.notificationIcon).SetTicker(message)
                              .SetAutoCancel(true).SetContentTitle(title).SetNumber(DroidConstants.NotifyCounter)
                              .SetDefaults((int)NotificationDefaults.All)
                              .SetContentText(message).Build();
        notificationManager.Notify(unique, notification);            
}

下面是我的MainView类代码

 public abstract class BaseMainView : BaseView<MainViewModel>
    {

    }

        [Activity(Label = "New Tasks",
              NoHistory = false,
              Icon = "@drawable/icon",
              Theme = "@style/Theme.AppCompat.Light",
              LaunchMode = Android.Content.PM.LaunchMode.SingleTask,//setted to single task to handle stack issue
            //ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait,
              UiOptions = Android.Content.PM.UiOptions.SplitActionBarWhenNarrow)]
        /*,
              ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize*/
    public class MainView : BaseMainView
    {      

        public new MainViewModel ViewModel
        {
          get { return base.ViewModel; }
          set { base.ViewModel = value; }
        }

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);            
            // Set up View to be shown
            SetContentView(Resource.Layout.MainView);
            var set = this.CreateBindingSet<MainView, MainViewModel>();
            //Code to map binding with controls
            set.Apply();

        }
        protected override void OnNewIntent(Android.Content.Intent intent)
        {
            //When is in background or running then this get called and I simple perform the action required.
        }
    }

注意: - 我已将此活动的LaunchMode设置为SingleTask。

  

LaunchMode = Android.Content.PM.LaunchMode.SingleTask

因为当应用程序在通知中处于前台或后台时,单击OnNewIntent将被调用并且能够在那里执行逻辑。但是,当应用程序从后台删除并且通知到达然后通知时,单击OnCreate方法被调用,并且我将MainViewModel视为空。

请帮我解决这个问题。

谢谢, Aaman

1 个答案:

答案 0 :(得分:0)

MvvmCross中的默认视图模型加载机制使用Extra中的特殊Intent来帮助识别ViewModel请求。

您可以在此处查看正常请求的执行方式 - https://github.com/MvvmCross/MvvmCross/blob/3.2/Cirrious/Cirrious.MvvmCross.Droid/Views/MvxAndroidViewsContainer.cs#L134

    public virtual Intent GetIntentFor(MvxViewModelRequest request)
    {
        var viewType = GetViewType(request.ViewModelType);
        if (viewType == null)
        {
            throw new MvxException("View Type not found for " + request.ViewModelType);
        }

        var converter = Mvx.Resolve<IMvxNavigationSerializer>();
        var requestText = converter.Serializer.SerializeObject(request);

        var intent = new Intent(_applicationContext, viewType);
        intent.PutExtra(ExtrasKey, requestText);

        AdjustIntentForPresentation(intent, request);

        return intent;
    }

如果您想使用此代码作为Intent的基础,您可以使用(例如)代码执行此操作:

  var request = MvxViewModelRequest<MyViewModel>.GetDefaultRequest();
  var intent = Mvx.Resolve<IMvxAndroidViewModelRequestTranslator>().GetIntentFor(request);

显然,它只是一个Intent,因此如果您愿意,可以为其添加额外的字段。


或者,您不必使用默认的ViewModel加载机制 - 如果您愿意,可以使用自己的机制替换它。