Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4114845
  • 博文数量: 855
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8236
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
  • 认证徽章:
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(855)

文章存档

2019年(12)

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(272)

2010年(1)

2009年(53)

2008年(65)

2007年(47)

2006年(81)

2005年(12)

分类: Android平台

2017-09-26 22:30:50

在谷歌开发者大会上,Xamarin组的几个团队成员出席了生命周期的架构组件座谈 (推荐你看看)。虽然提出的解决方案很有趣,但在某些情况下,映射到我们在.NET中已经拥有的模式,它的共鸣与我们这些人因为这些Android生命周期细节让一个特定的C #特征使用较为繁琐: async/await。

对于 async/await,Android开发者有两个主要的挑剔点:

  • 因为Android资源系统的工作方式,配置的更改(如屏幕旋转)将在默认情况下重新创建Activity实例。
  • 因为在Activity生命周期中,await是不确定的, 它可以执行的延续得到不希望的状态,会造成一个IllegalStateException。.

注意,我们已经介绍了部分解决这些疑虑的ActivityController形式,为基于StartActivityForResult的工作流提供方便的异步包装方法提供了额外的好处。 

根据以往的经验在C # 7最新定制的异步状态机驱动(看到更多的宣传,例如这个新的C #特征valuetask),我认为有可能利用这一点来帮助减轻这两个问题,而不需要太多的代码更改。

进入ActivityTask (在  NuGet 上已经可用了)

这人库包含两个主要的类:

  • ActivityScope允许你跟踪你的一个Activity的子类的最近的一个例子,潜在的娱乐是透明的,对你而言。
  • ActivityTask acts as a standard 作为一个异步方法返回值标准的任务, 在一个异步方法返回值, 但自定义状态机的驱动程序(在合作ActivityScope)进行连续调度意识活动的生命周期。

在那个罩之下,ActivityScope 在应用级别注册一个监听器,监听全局的activity生命周期事件。当它监测到一个activity将要被销毁时,它标记它,以便当它重新创建时,它可以与它重新关联。因为它实现了对Activity的隐式转换运算符,您可以在需要Activity实例的地方传递该范围,以确保始终使用有效值。

至于ActivityTask,实现是很无奈的(它几乎是定义到TaskCompletionSource)。 ActivityScopeMethodBuilder的有趣部分是,它驱动了机器的async状态。对于所有intents和目的,它将表现为任务的默认驱动程序。然而,扩展ActivityScope方法参数,它还将确保当范围跟踪的活动处于可用状态时才执行任何继续。如果不是,它会简单地把继续排队直到Activity被resume(onResume方法)。

看看这一切是如何结合在一起的,这里是测试应用的activity的代码,在 GitHub 仓库:


点击(此处)折叠或打开

  1. [Activity(Label = "ActivityTaskTest", MainLauncher = true, Icon = "@mipmap/icon")]
  2. public class MainActivity : Activity
  3. {
  4.     static bool launched = false;
  5.     protected override async void OnCreate(Bundle savedInstanceState)
  6.     {
  7.         base.OnCreate(savedInstanceState);
  8.         // Set our view from the "main" layout resource
  9.         SetContentView(Resource.Layout.Main);
  10.         if (!launched)
  11.         {
  12.             launched = true;
  13.             using (var scope = ActivityScope.Of(this))
  14.                 await DoAsyncStuff(scope);
  15.         }
  16.     }
  17.     TextView MyLabel(Activity activity) => activity.FindViewById(Resource.Id.myLabel);
  18.     async ActivityTask DoAsyncStuff(ActivityScope scope)
  19.     {
  20.         await Task.Delay(3000); // Medium network call
  21.         MyLabel(scope).Text = "Step 1";
  22.         await Task.Delay(5000); // Big network call
  23.         MyLabel(scope).Text = "Step 2";
  24.     }
  25. }

这个示例模拟在创建Activity的第一次时启动一系列异步操作。以前虽然,它创建了一个ActivityScope跟踪当前活动的寿命及传下去。在每个异步子步骤之间,Activity实例用于获取屏幕上的标签并更新其文本。

这个想法是在这些Task中触发一个破坏性的事件。延迟调用,您可以通过旋转设备来测试(从而杀死和重新创建活动),或者按下Home按钮暂停活动,并在延迟到期后重新打开它。

F例如,如果在“步骤1”之后旋转屏幕显示,您应该看到标签的原始文本再次出现(因为布局是从零开始膨胀的),不久后,你会看到“步骤2”设置,这意味着异步方法正确使用新的活动实例来定位标签。

如果在“步骤1”之后暂停活动,则显示,在第二次延迟过期后恢复活动将导致立即显示“步骤2”,由于回调是在恢复过程中执行的,而不是在活动处于后台时运行。

阅读(2193) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册