这里需要强调的一点是,我将由Retrofit生成的函数类型返回至另一新函数: Call。
我利用 以面向Open Weather Map实际执行调用。这里我并没有使用由Retrofit提供的任何调用适配工具,这是为了保证自己能够将Call对象打包在suspendable函数当中。
02实用工具
从这里,我们正式迈入了全新的coroutines世界:我们希望创建一条打包有Call对象的suspendable函数。
要完成这部分内容,您需要掌握coroutines的一部分基础知识。如果您尚不了解,请参阅《Coroutines指南》的第一章内容(由Roman Elizarov撰写)。
这将是一条扩展函数:suspend funCall.await(),其负责调用Call.enqueue(…)(以实际执行网络调用),而后调用suspends,再然后是resumes(当响应返回时)。
要将任意异步计算转化为suspendable函数,我们需要使用The Kotlin标准库当中的函数。其能够为我们提供一个对象,这属于一类通用回调。我们只需要在对新的suspendable函数进行恢复时(通常是在出现异常的情况下),调用其方法(或者方法)即可。
下一步是使用我们的新suspend funCall.await()函数,其负责将由Retrofit生成的异步函数转换为便捷的suspendable函数。
03 Repository
Repository对象属于我们在应用中需要显示的数据(图表)的实际来源。
在这里,我们会使用一些由suspend funCall.await()扩展生成的专用suspendable函数,用以实现天气服务功能。如此一来,其返回的将全部为可立即使用的Forecast预报等数据,而非Call。接下来,我们在一条公共suspendable函数中使用这些数据:suspendfun getCityCharts(city:String):List。其能够将来自API的数据转化为可随时显示的图表清单。这里我使用List上的部分定制化扩展属性以将数据实际转换至List。需要强调的是,只有suspendable函数能够调用其它suspendable函数。
为了简单起见,我们这里对此appid进行硬编码。如果大家希望对应用进行测试,请点击此处生成新的appid——这是因为如果此硬编码appid被多人频繁使用,则会自动被屏蔽24小时。
在下一步中,我们将创建主应用模型(采用Android ViewModel架构组件),其利用一个actor(coroutine builder)以实现应用逻辑。
04 模型
在这款应用中,我们只使用一套简单的模型: MainModel : ViewModel,且仅供一种活动使用: MainActivity。
这个类代表着应用本身。其将由我们的活动(实际上是由Android系统的ViewModelProvider)进行实例化,但能够在配置变更(例如屏幕旋转)后继续存在,且保证新的活动实例仍拥有相同的模型实例。我们完全不必担心活动生命周期问题。相较于实现与各方法(onCreate、onDestroy等)相关的活动生命周期,这里我们只拥有一项onCleared()方法,其会在用户退出此应用时进行调用。
更确切地讲,当活动finished时,onCleared方法将得到调用。