如何创建高度模块化的 Android 应用

简介: 本文讲的是如何创建高度模块化的 Android 应用,Android 中构建 UI 的职责通常委派给一个类(比如 Activity、Fragment 或 View/Presenter)。这通常涉及到以下任务:
本文讲的是如何创建高度模块化的 Android 应用,

“单一职责原则规定,每个模块或类应该对软件提供的某单一功能负责。”(en.wikipedia.org/wiki/Single_responsibility_principle)

Android 中构建 UI 的职责通常委派给一个类(比如 Activity、Fragment 或 View/Presenter)。这通常涉及到以下任务:

  • 填充 View(xml 布局)
  • View 配置(运行时参数、布局管理、适配)
  • 数据源连接(DB 或者 数据存储的监听/订阅)
  • 加载缓存数据
  • 新数据的按需请求分派
  • 监听用户事件(tap、scroll)然后响应事件

除此之外,Activity 和 Fragment 通常还会委派一些额外的职责:

  • App 导航
  • Activity 结果处理
  • Google Play 服务连接和交互
  • 过渡动画配置

这不是单一职责,当前的处理方式包括了继承或组合,这太复杂了。

继承地狱

“当一个对象或类是基于另一个对象或类,这就是继承。它是为了代码重用,并允许原始软件通过公共类和接口单独扩展。这些对象或类的关系,通过继承形成一种层级。” (en.wikipedia.org/wiki/Inheritance_(object-oriented_programming))

对于这种复杂的结构,如 UI 构建,继承能让它很快变成一坨 x。看看下面的模拟案例:

据此继承树构建代码会很快变得难于管理 ("继承地狱")。要避免这种情况,开发人员应遵循"组合而非继承"的原则。

组合优于继承

“在面向对象编程中有个原则,组合替代继承(组合复用原则)。类应该通过组合实现行为多态和代码复用(通过包含其他类的实例来实现所需的功能)。”(en.wikipedia.org/wiki/Composition_over_inheritance)

组合优于继承原则是个很棒的想法,无疑可以帮助我们解决上面提出的问题。然而,几乎没有库、示例代码或者教程来教你如何在 Android 上实现这原则。一种实现它的简单方法就是使用运行时参数(又叫 intent extras)来组合功能,但是,仍会导致形成一个巨大的难以管理的怪物类。

很荣幸,这里要提及两个库, LightCycle 和 CompositeAndroid。两者都紧紧的绑定在 Activity 或 Fragment,抛开其他诸如 MVP 或 MVVM 的现代模式,都不是很灵活,因为它们仅仅依赖 Android 原生回调(无法添加额外回调),也不支持模块间通信。

修饰模式

开发者们每天都要面对这些提出的问题, EyeEm Android 团队开始开发一种模式,以一种更加灵活的方式来解决该问题,而不是直接附加到一个组件上如 Activity 或 Fragment 。该模式可以用来对任何开发者希望通过组合来模块化的类进行解耦。

该模式和 LightCycle/Composite 的方法非常相似,由三个类组成:

  • 基本类,称为 DecoratedObject(装饰对象),调度其继承和额外的方法给一个调度对象。
  • DecoratorsObject 实例化,保存所有组成对象的列表并分派方法给它们。
  • Decorator 抽象类,所有方法和额外接口都只声明未实现。由创建此类的开发人添加单一职责的具体实现。

使用这种方式开发人员获得的直接好处

  • 职责分离
  • 功能动态运行置换
  • 并行开发

为了让开发者能毫无障碍的实现上述模式,一个在编译时生成代码的工具被创造了出来,接下来我们会看到,将之前提交的那些职责分解成单一职责类是多么简单。

Decorator 库

如何三步创建你自己的模块化单一职责应用

要实现装饰模式首先创建应生成的代码蓝图,在这里我们将使用一个带 RecyclerView 的 Activity 作为例子,但同样能用在 Fragment、Presenter 甚至 View 。这这个例子中,我们将使用 activity 生命周期中的 onCreate/onStart/onStop/onDestroy ,但是也会额外创建几个适合 RecyclerView 案例的回调。

    @Decorate
    public class ActivityBlueprint extends AppCompatActivity {

        @Override protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);}
        @Override protected void onStart() {super.onStart();}
        @Override protected void onStop() {super.onStop();}
        @Override protected void onDestroy() {super.onDestroy();}

        public int getLayoutId() {return R.layout.recycler_view;}
        public RecyclerView.LayoutManager getLayoutManager() {return new LinearLayoutManager(this);}
        public RecyclerView.Adapter getAdapter() {return null;}
        public void setupRecyclerView(RecyclerView recyclerView, WrapAdapter wrapAdapter, RecyclerView.Adapter adapter) { /**/ }

        public interface DataInstigator {
            RealmList getList();
            RealmObject getData();
        }

        public interface RequestInstigator {
            void reload();
            void loadMore();
        }
    }

这个简单的蓝图使用 @Decorate 注解,将会生成完整的修饰模式实现,Serializable builder 类可以作为参数传递。为了完成 Activity 的实现,我们扩展了生成类,并将 received builder 绑定上去。

    public classRecyclerViewActivityextendsDecoratedAppCompatActivity{

        @Overrideprotected void onCreate(Bundle savedInstanceState) {
            bind(getBuilder(getIntent().getSerializableExtra(KEY.BUILDER)));
            super.onCreate(savedInstanceState);
            setContentView(getLayoutId());
            RecyclerView rv = (RecyclerView) findViewById(R.id.recycler);
            rv.setLayoutManager(getLayoutManager());
            RecyclerView.Adapter adapter = getAdapter();
            WrapAdapter wrapAdapter = newWrapAdapter(adapter);
            rv.setAdapter(wrapAdapter);
            setupRecyclerView(rv, wrapAdapter, adapter);
        }

        @Overrideprotected void onDestroy() {
            super.onDestroy();
            unbind();
        }
    }

现在可以方便的将职责分发到可绑定的修饰类上。每个修饰器包含所有生命周期的回调,可以实现任何可选接口。最后,可以组合得到一个简单的建造者模式:

      Intent i = new Intent(context, RecyclerViewActivity.class);
            i.putExtra(KEY.BUILDER, new DecoratedActivity.Builder()
                    .addDecorator(GridInstigator.class)
                    .addDecorator(LoadMoreDecorator.class)
                    .addDecorator(PhotoGridAdapter.class)
                    .addDecorator(PhotoListInstigator.class)
                    .addDecorator(PhotoRequestInstigator.class));
            i.putExtra(KEY.URL, url);

完整示例应用

请查看我们 Github 上的相关库和完整的示例应用 https://github.com/eyeem/decorator 。该示例应用在开始下一步之前从当前 activity 通过简单的添加/移除修饰器来模拟每个用户在 Activity 执行 tap。

上面展示的代码大部分都是出自示例。你会发现一个用 Realm 和 Retrofit 真正实现的修饰器列表,就是这篇文章开始提到的 UI 构建任务。

  • CoordinatorLayoutInstigator,重写了 CoordinatorLayout 的默认布局,可选实例化一个 header
  • ToolbarInstigator,接管 toolbar,并且应用一个标题
  • ToolbarUp 和 ToolbarBack 修饰器,导航工具栏上图标的行为
  • 加载更多的修饰器,添加一个无限滚动的功能到 RecyclerView
  • PhotoList 和 PhotoRequest 修饰器,本地数据存储和 API 请求图片列表 API 调用

现实世界应用

EyeEm 已经在使用修饰器——并且体验非常好。来 Play Store 看看吧。我们目前为所有 UI 元素使用 装饰 view presenters(使用 Square Mortar 库),为过渡动画使用了装饰 activities,处理不同 API 级别,A/B 测试,导航,跟踪和新摄影师入职时的少数特殊情况,

最后说明

上面所示的代码和实现纯粹只是示例,仅作为指导。

当我们为 Android 创建这个库时,该模式是开放给任何用例的。这个库是一个纯 Java 实现,它在编译时生成代码,可用于任何 Java 类,我们鼓励开发人员在他们任何 Java 项目中编写模块化的单一职责的代码!来

说的够多了-将添加到你的 build.gradle 中,然后开始构建模块化应用吧。

在 EyeEm,我们正在探索摄影和技术的交叉点。除了建立尖端的计算机视觉技术,我们的 iOS,Android 和 web 应用程序被 1800 万世界各地的摄影师用于获得灵感、 学习、 分享他们的工作,发现惊人的天赋,获得出版和展出,甚至通过我们的市场赚钱。






原文发布时间为:2016年08月13日

本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。
目录
相关文章
|
11天前
|
IDE Java 开发工具
深入探索安卓应用开发:从环境搭建到第一个"Hello, World!"应用
本文将引导读者完成安卓应用开发的初步入门,包括安装必要的开发工具、配置开发环境、创建第一个简单的安卓项目,以及解释其背后的一些基本概念。通过一步步的指导和解释,本文旨在为安卓开发新手提供一个清晰、易懂的起点,帮助读者顺利地迈出安卓开发的第一步。
190 65
|
11天前
|
存储 Java Android开发
探索安卓应用开发:构建你的第一个"Hello World"应用
【9月更文挑战第24天】在本文中,我们将踏上一段激动人心的旅程,深入安卓应用开发的奥秘。通过一个简单而经典的“Hello World”项目,我们将解锁安卓应用开发的基础概念和步骤。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供一次实操体验。从搭建开发环境到运行你的应用,每一步都清晰易懂,确保你能顺利地迈出安卓开发的第一步。让我们开始吧,探索如何将一行简单的代码转变为一个功能齐全的安卓应用!
|
15天前
|
开发框架 搜索推荐 开发工具
打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第51天】本文是一篇面向初学者的Flutter入门教程,旨在通过简单易懂的语言和实际代码示例,引导读者步入跨平台移动应用开发的世界。文章首先介绍了Flutter的基本概念和优势,然后逐步展示了如何搭建开发环境、创建第一个Flutter应用,并实现了一个简单的待办事项列表。最后,文章探讨了Flutter在实现高性能和美观界面方面的潜力,鼓励读者发挥创意,探索更多可能。
66 15
|
6天前
|
监控 安全 Java
Kotlin 在公司上网监控中的安卓开发应用
在数字化办公环境中,公司对员工上网行为的监控日益重要。Kotlin 作为一种基于 JVM 的编程语言,具备简洁、安全、高效的特性,已成为安卓开发的首选语言之一。通过网络请求拦截,Kotlin 可实现网址监控、访问时间记录等功能,满足公司上网监控需求。其简洁性有助于快速构建强大的监控应用,并便于后续维护与扩展。因此,Kotlin 在安卓上网监控应用开发中展现出广阔前景。
9 1
|
20天前
|
搜索推荐 Java Android开发
打造个性化安卓应用:从设计到发布的全程指南
【9月更文挑战第15天】本篇文章将带领读者踏上一段激动人心的旅程,从构思一个独特的安卓应用想法开始,直至将其变为现实并成功发布。我们将一起探索如何捕捉灵感、设计界面、编写代码以及最终将应用推向市场。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供宝贵的洞见和实用的技巧,让你的应用在竞争激烈的市场中脱颖而出。
56 17
|
16天前
|
Java Android开发 UED
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
在Android开发中,为应对复杂应用场景和繁重计算任务,多线程与异步编程成为保证UI流畅性的关键。本文将介绍Android中的多线程基础,包括Thread、Handler、Looper、AsyncTask及ExecutorService等,并通过示例代码展示其实用性。AsyncTask适用于简单后台操作,而ExecutorService则能更好地管理复杂并发任务。合理运用这些技术,可显著提升应用性能和用户体验,避免内存泄漏和线程安全问题,确保UI更新顺畅。
38 5
|
17天前
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
86 3
|
17天前
|
存储 API Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
随着Android系统的更新,权限管理成为应用开发的关键。尤其在Android 6.0(API 级别 23)后,动态权限请求机制的引入提升了用户隐私保护,要求开发者进行更精细的权限管理。
43 2
|
25天前
|
开发框架 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的指南
在移动应用开发的广阔天地中,安卓与iOS两大平台各占半壁江山。本文将深入浅出地对比这两大操作系统的开发环境、工具和用户体验设计,揭示它们在编程语言、开发工具以及市场定位上的根本差异。我们将从开发者的视角出发,逐步剖析如何根据项目需求和目标受众选择适合的平台,同时探讨跨平台开发框架的利与弊,为那些立志于打造下一个热门应用的开发者提供一份实用的指南。
51 5
|
23天前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
46 1
下一篇
无影云桌面