标签(空格分隔): 翻译计划 Android开发
在Google I/O之间,Google推出了包含LiveData和ViewModel的组件架构,这有助于开发者们使用MVVM开发Android应用程序。这篇文章旨在讲述该组件如何融汇在使用MVVM模式开发Android应用程序。
如果你很熟悉MVVM架构,那么你可以快速跳过本小节知识点。
MVVM是增强关注点分离的体系结构模式之一,它允许将用户界面逻辑从业务(或者后端)逻辑中分离开来,他的目标(和MVC等其他目标)是为了实现”保持UI代码简单化,不涉及更多的业务逻辑,以便于开发者更好的控制和管理”。
如上所述,LiveData是新引入的组件架构之一,LiveData是一个可以被观察的数据持有者.这也就意味着应用中的组件能够观察LiveData对象的更改,而无需在它们之间创建明确的和严格的依赖关系。这将完全分离LiveData对象使用者和LiveData对象生产者。
除此之外,LiveData还有一个很大的好处,LiveData遵守应用程序组件(活动,片段,服务)的生命周期状态,并进组件的生命周期管理,确保LiveData对象的内存泄漏.
根据Google文档,如果您已经在使用Rx或Agera等开源库,那么你可以继续使用它们而不是替换成LiveData.但在这种情况下,您有责任处理每个Android组件生命周期的对象分配和解除分配.
由于LiveData遵从Android的生命周期机制,这意味着除非LiveData主体(activity或fragment)处于活动状态(接收onStart()但未收到onStop()),否则它将不会调用其观察者回调.除此之外,当主体收到onDestroy()时,LiveData也会自动删除观察者防止内存泄漏.
LiveData也会将在下面的MVVM事例中进行说明.
ViewModel也是新引入的体系架构组件之一.架构组件提供了一个名为ViewModel的新类,它负责为UI / View准备数据.
ViewModel为您的MVVM模式中的ViewModel提供了一个很好的基类,因为ViewModel(及其子类AndroidViewModel)的扩展类会在配置更改期间自动保留其数据.这意味着,在配置更改后,此ViewModel所有数据可立即用于下一个活动(activity)或片段(fragment)实例.
ViewModel也将会在下面的MVVM事例中进行说明。
现在,让我们来看看最有趣的部分,让我们把上述的所有知识(组件)放在一个程序中.
此MVVM事例应用主要包含两个界面.
下面显示的第一个界面显示了Google GitHub上的项目列表.其中包含一些简要信息,例如标题,编程语言和watcher数量。
一旦用户点击了首页的item,GitHub项目的详细信息屏幕将会显示项目描述,编程语言,watcher数量,公开问题,创建和上次更新日期,最后显示克隆URL.
以下交互图显示了检索Google GitHub项目的应用场景之一的示例交互图。
如上图所示,每个图层都从其后续图层(Fragment(View) - > ViewModel - > Repository)观察LiveData,最后一旦检索到项目列表(或者有所变化),就会使用RecyclerView(ListView)适配器绑定显示项目列表.
Respository模块负责处理数据操作,通过这一点,Respository可以为程序的其余部分提供干净的API,并简化ViewModel的工作.
如果需要更新数据,Respository模块应该知道从哪里获取数据以及进行哪些API调用.它们可以被视为不同数据源(REST服务,数据库,XML文件等)之间的中介.
现在,让我们从下往上解释这些图层,从Model、ViewModel开始,最后用View来检索GitHub项目场景。
让我们从业务逻辑层开始,我们有两个模型对象
interface GitHubService {
String HTTPS_API_GITHUB_URL = "https://api.github.com/";
@GET("users/{user}/repos")
Call> getProjectList(@Path("user") String user);
@GET("/repos/{user}/{reponame}")
Call getProjectDetails(@Path("user") String user, @Path("reponame") String projectName);
}
为了便于ViewModel的工作,创建一个ProjectRespository来与GitHub服务交互,并最终为ViewModel提供一个LiveData对象.以下代码片段显示了getProjectList()API实现.
public class ProjectRepository {
private GitHubService gitHubService;
//…
public LiveData> getProjectList(String userId) {
final MutableLiveData> data = new MutableLiveData<>();
gitHubService.getProjectList(userId).enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
data.setValue(response.body());
}
// Error handling will be explained in the next article …
});
return data;
}
// …
}
ProjectRepository是ViewModel的数据提供者,它有getProjectList(),它简单地将响应包装到LiveData对象中.
为了简化本文的目的,错误处理被省略,并且将在下一篇文章中进行说明
为了处理(接收)getProjectList()API,创建了ViewModel类(调用Repository API并可以为LiveData执行任何所需的数据转换).
以下代码片段显示了ProjectListViewModel类
public class ProjectListViewModel extends AndroidViewModel {
private final LiveData> projectListObservable;
public ProjectListViewModel(Application application) {
super(application);
// If any transformation is needed, this can be simply done by Transformations class ...
projectListObservable = ProjectRepository.getInstance().getProjectList("Google");
}
/**
* Expose the LiveData Projects query so the UI can observe it.
*/
public LiveData> getProjectListObservable() {
return projectListObservable;
}
}
如上所示,我们的ProjectListViewModel类继承了AndroidViewModel,并在构造函数中调用getProjectList(“Google”)来检索Google GitHub项目.
在现实世界的情况下,在将结果数据传递到观察视图之前可能需要进行转换,为了进行转换,可以使用Transformation类,如以下文档中所示https://developer.android.com/topic/libraries/architecture/livedata.html#transformations_of_livedata
最后,让我们快速浏览一下这个应用程序的视图层,我们主要有一个名为MainActivity的Activity(活动),它负责处理代表应用程序视图的两个片段的导航.
由于活动和片段被视为生命周期所有者,activity需要扩展LifecycleActivity,fragment需要扩展LifecycleFragment.但是,请务必记住LifecycleActivity和LifecycleFragment类都是临时实现,直到Lifecycle与支持库支持为止:https://developer.android.com/reference/android/arch/lifecycle/LifecycleActivity.html
现在,让我们继续我们的项目检索方案,查看ProjectListFragment这个界面,下面的代码片段显示了最重要的集成部分.
public class ProjectListFragment extends LifecycleFragment {
private ProjectAdapter projectAdapter;
//…
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final ProjectListViewModel viewModel =
ViewModelProviders.of(this).get(ProjectListViewModel.class);
observeViewModel(viewModel);
}
private void observeViewModel(ProjectListViewModel viewModel) {
// Update the list when the data changes
viewModel.getProjectListObservable().observe(this, new Observer>() {
@Override
public void onChanged(@Nullable List projects) {
if (projects != null) {
//…
projectAdapter.setProjectList(projects);
}
}
});
}
//…
}
如上代码所示,ProjectListFragment获取ProjectListViewModel数据对象,然后监听其getProjectListObservable()方法,以便获取Github项目列表。
最后,一旦检索到项目列表(有数据变化),它将被传递给projectAdapter(RecyclerView适配器),以显示RecyclerView组件中(更新UI).
这是对项目的一个端到端场景的解释,您可以在这里找到GitHub中提供的完整项目:
现在,重点介绍MVVM实现的一些重要指导原则:
故事尚未完成,因为有些事情需要处理,比如:
这将在MVVM的下一系列文章中进行说明,敬请关注.