基于Sunflower演示项目学习下目前的Android Jetpack架构最佳实践

透过sunflower看看Google最近在Android上有什么花活(一)--- Hilt sunflower sunflower是什么?太阳花?Google没出这个框架吧。 其实,sunflower是Google基于Google开发框架,加入大量Android JetPack组件的示例项目,涉及到kotlin,kotlin协程,新fragment,hilt,DataSource,paging3等等等等。 话不多说,先clone一下吧,地址如下:https://github.com/android/sunflower.git 开始 clone完成之后,打开项目,项目本身并不复杂,也没有使用插件化, 阅读详情

Sunflower项目是google发布的Android kotlin Demo项目,展示了使用Jetpack架构开发App的最佳实践),这个项目是持续更新的,第一次提交是2017.8,2021年6月还在更新,我的代码是7月下载的。 里面主要介绍google 最新的一些工具和理念,使用databinding,viewModel,liveData实现MVVM架构, 使开发者可以快速构建自己的APP项目,具体源码:https://github.com/googlesamples/android-sunflower

项目的就是个简单的花园demo, 包括我的花园,植物目录,植物详情,分享等页面,基于kotlin MVVP架构实现,

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

一、主要技术

1、MVVM 利用databinding,viewModel,liveData实现MVVM架构,

2、利用navigation框架做导航,APP只有一个Activity,其余的都是Fragment

二、具体说明

1、界面实现

首先看看manifest文件

    <application
        android:name=".MainApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Sunflower">
        <activity
            android:name=".GardenActivity"
            android:theme="@style/Theme.Sunflower.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <provider
            android:name="androidx.work.impl.WorkManagerInitializer"
            android:authorities="${applicationId}.workmanager-init"
            tools:node="remove" />
    </application>

主Activity:GardenActivity 加载了一个布局

<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_garden" />

</layout>

有个来封装其实没啥用,因为没有使用Binding的内容,可以去掉

这里用到Navigation,我们来看看nav_garden

//使用navigation来包装,加载两个fragment app:startDestination设置主界面
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    app:startDestination="@+id/view_pager_fragment">

//主fragment
    <fragment
        android:id="@+id/view_pager_fragment"
        android:name="com.gl.samples.apps.sunflower.HomeViewPagerFragment"
        tools:layout="@layout/fragment_view_pager">

        <action
                android:id="@+id/action_view_pager_fragment_to_plant_detail_fragment"
                app:destination="@id/plant_detail_fragment"
                app:enterAnim="@anim/slide_in_right"
                app:exitAnim="@anim/slide_out_left"
                app:popEnterAnim="@anim/slide_in_left"
                app:popExitAnim="@anim/slide_out_right" />

    </fragment>
//详情页
    <fragment
        android:id="@+id/plant_detail_fragment"
        android:name="com.gl.samples.apps.sunflower.PlantDetailFragment"
        android:label="@string/plant_details_title"
        tools:layout="@layout/fragment_plant_detail">
        <argument
            android:name="plantId"
            app:argType="string" />
    </fragment>

</navigation>

这个也不难,HomeViewPagerFragment主界面,PlantDetailFragment植物详情页,具体内容可以去了解下Navigation
HomeViewPagerFragment 主要是一个viewPager,包含两个Fragment :GardenFragment和 PlantListFragment

class SunflowerPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {

    /**
     * Mapping of the ViewPager page indexes to their respective Fragments
     */
    private val tabFragmentsCreators: Map<Int, () -> Fragment> = mapOf(
        MY_GARDEN_PAGE_INDEX to { GardenFragment() },
        PLANT_LIST_PAGE_INDEX to { PlantListFragment() }
    )

    override fun getItemCount() = tabFragmentsCreators.size

    override fun createFragment(position: Int): Fragment {
        return tabFragmentsCreators[position]?.invoke() ?: throw IndexOutOfBoundsException()
    }
}

viewPager适配器SunflowerPagerAdapter中定义一个map,在创建Fragment的时候通过反射来执行构建Fragment的方法。

这里要注意viewPager和我们以前使用的viewPager并不是一个东西,而是在androidx.viewpager2.widget里面的新的类,主要通过RecyclerView来实现,适配器当然

也是继承RecyclerView.Adapter实现的,具体实现请查看源码,具体不细说。

GardenFragment和 PlantListFragment里面就比较简单,运用DataBinding来把数据绑定到View上,实现数据变化view改变,ViewModel来处理和管理数据,并进行数据通信。

这个里面涉及到的内容比较复杂,可以查看我另一个源码,比较简单的介绍DataBinding和ViewModel的用法,传送门

2、数据加载

这个应用可以说是一个离线应用(数据离线,图片加载不是),主要的数据都是存储在plants.json,于是需要把内容都加载出来:

package com.google.samples.apps.sunflower.workers

import android.content.Context
import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import com.google.samples.apps.sunflower.data.AppDatabase
import com.google.samples.apps.sunflower.data.Plant
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class SeedDatabaseWorker(
        context: Context,
        workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {
    override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
        try {
            val filename = inputData.getString(KEY_FILENAME)
            if (filename != null) {
                applicationContext.assets.open(filename).use { inputStream ->
                    JsonReader(inputStream.reader()).use { jsonReader ->
                        val plantType = object : TypeToken<List<Plant>>() {}.type
                        val plantList: List<Plant> = Gson().fromJson(jsonReader, plantType)

                        val database = AppDatabase.getInstance(applicationContext)
                        database.plantDao().insertAll(plantList)

                        Result.success()
                    }
                }
            } else {
                Log.e(TAG, "Error seeding database - no valid filename")
                Result.failure()
            }
        } catch (ex: Exception) {
            Log.e(TAG, "Error seeding database", ex)
            Result.failure()
        }
    }

    companion object {
        private const val TAG = "SeedDatabaseWorker"
        const val KEY_FILENAME = "PLANT_DATA_FILENAME"
    }
}

主要在SeedDatabaseWorker类中,主要使用的是WorkManager这个框架来实现异步加载,加载后把数据存入room数据库,便于后续使用。

CoroutineWorker是Worker的子类,一般在使用Kotlin开发的时候使用来和协程配合开发,

看这部分代码可以先去学习下WorkManager,

3、网络请求

主要是获取植物的图片url, 基于okhttp3和retrofit2框架实现
图片的加载使用glide, 这几个框架都是安卓开发的主流框架

package com.google.samples.apps.sunflower.api

import com.google.samples.apps.sunflower.BuildConfig
import com.google.samples.apps.sunflower.data.UnsplashSearchResponse
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.HttpLoggingInterceptor.Level
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Query

/**
 * Used to connect to the Unsplash API to fetch photos
 */
interface UnsplashService {

    @GET("search/photos")
    suspend fun searchPhotos(
        @Query("query") query: String,
        @Query("page") page: Int,
        @Query("per_page") perPage: Int,
        @Query("client_id") clientId: String = BuildConfig.UNSPLASH_ACCESS_KEY
    ): UnsplashSearchResponse

    companion object {
        private const val BASE_URL = "https://api.unsplash.com/"

        fun create(): UnsplashService {
            val logger = HttpLoggingInterceptor().apply { level = Level.BASIC }

            val client = OkHttpClient.Builder()
                .addInterceptor(logger)
                .build()

            return Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(UnsplashService::class.java)
        }
    }
}

总结:

Sunflower这个应用主要的技术包括:DataBinding、ViewModel、LiveData、Navigation、WorkManager和Room,

当然还有一些简单的Android的知识和协程的内容,把这个应用过一遍,对自己也很有帮助。

探索Android Sunflower:打造完美园艺体验的Jetpack应用 Android Sunflower项目是一个开源的园艺应用程序,旨在帮助用户管理和记录自己的花园。无论是花匠还是园艺爱好者,都可以通过Android Sunflower来探索、学习和享受园艺的乐趣。Android Sunflower的主要目的是展示如何使用Android Jetpack的各种组件和库来构建一个高质量的应用程序。该项目旨在演示最佳的开发实践和技术选型,使开发者能够了解如何正确地利用Jetpack提供的工具和功能,以提高应用程序的性能、稳定性和可维护性。 阅读详情

相关推荐

Android代码-android-sunflower

Android Sunflower (alpha) A gardening app illustrating Android development best practices with Android Jetpack. Android Sunflower is currently released as an alpha and is under heavy development. To view the latest changes, please visit the Releases page. Note that some changes (such as database schema modifications) are not backwards compatible during this alpha period and may cause the app to crash. In this case, please uninstall and re-install the app. Introduction Android Jetpack is a set o

【Android-JetpackCompose】9、将 SunFlower 项目从 View 迁移到 Compose

有鉴于此,以及为了实现可重用性,最好将 LiveData 的使用和监听拆分到不同的可组合项中。如需从可组合项观察 LiveData,请使用 LiveData.observeAsState() 函数,该函数开始观察 LiveData,并通过 State 对象表示它的值。组合必须遵循 fragment 的视图生命周期,Compose 界面 View 类型才能保存状态,并且在发生过渡或窗口过渡时让 Compose 界面元素保留在界面上。在过渡期间,ComposeView 本身仍然可见,即使其与窗口分离也是如此。

呆呆的猫的博客 1006

Java版本的Sunflower官方学习项目

Google官方只给出了Kotlin版本的SunFlower项目,这里我将其改造成Java语言,供大家参考学习,多交流。

2024年Android最全Android Sunflower 带您玩转 Jetpack,阿里面试官必问

我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了7、8年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。不断奔跑,你就知道学习的意义所在!

2401_84545804的博客 1047

Android Qcom Display学习(十一)

该系列文章总目录链接与各部分简介:本章主要是基于MIPI Payload传输接口的学习,包括Generic和DCS的接口不同。底层都是基于去封装的,下面第一部分调用原生接口,第二部分分析高通是如何进行读写操作的。

Android驱动开发 3179

超详细Tokenizer——文本训练数据预处理

Tokenizer是Keras库中的一个文本处理工具,它用于将文本分词并构建词汇表,同时将文本映射到整数序列。这对于自然语言处理任务非常有用,例如文本分类、情感分析、机器翻译等。

halo的博客 3700

Android架构演进:Sunflower项目从XML到Jetpack Compose的现代化重构

Android开发领域正在经历从传统的XML布局到声明式UI架构Jetpack Compose的重大技术迁移。GitHub加速计划中的Sunflower项目作为Android官方示例,完整展示了如何将基于View的应用渐进式迁移到Jetpack Compose架构,为中级开发者提供了从传统架构向现代架构演进的最佳实践指南。 ## 技术挑战:传统Android开发的架构瓶颈 在Jetpack C

gitblog_01104的博客 1072

银河麒麟V11 + KVM/QEMU + GT 710 GPU直通 Win10 完整操作流程文档

宿主机:RTX 5080专门运行ollama大模型服务,通过SSH/VNC远程管理Win10虚拟机:GT 710直通,物理键盘专属,通过物理显示器处理视频应用硬件隔离:两个系统完全隔离,互不干扰,性能最大化两种不同的直通方式直通方式 配置方法 设备在宿主机的状态 典型应用场景PCIe设备直通 vfio-pci.ids=10de:128b,10de:0e0f 设备完全从宿主机消失,被vfio-pci驱动接管 GPU、网卡、NVMe硬盘。

weixin_45285654的博客 1151

android-sunflower-java:演示Android Jetpack的最佳实践园艺应用

android-sunflower-java:演示Android Jetpack的最佳实践园艺应用 项目介绍 android-sunflower-java 是一个开源项目,旨在演示如何使用 Android Jetpack 开发 Android 应用。这个项目是 Kotlin 版本的 Android Sunflower 的 Java 实现,包含了两个 app 模块:一个是 Kotlin 实现,另一个...

gitblog_00744的博客 990

Labview项目01:标准可配置序列测试框架

摘要:本文介绍了一个基于LabVIEW2020开发的通用测试框架系统。该系统采用模块化设计,包含主界面、调试界面、设置界面和登录界面。主功能包括:1)可配置测试序列,支持延时、预定值输出、随机值输出等操作;2)单步测试功能自主添加;3)界面支持测试序列编辑和权限管理。系统采用队列机制处理事件和测试流程,通过CSV文件存储测试序列,支持参数化配置。用户可自定义测试VI(A_.vi和N_.vi格式),并通过调试界面验证测试序列。最终测试结果在主界面显示,提供整体判断功能。该系统既可作为学习参考,也可用于实际测试

weixin_38637405的博客 1552

【Power Compiler手册】13.UPF多电压设计实现(2)

在这个场景中,在约束传播期间,工具会比较BLOCK中的原子电源域与TOP设计中的原子电源域,并且确认所有属性都匹配。因此,域合并成功,工具会丢弃来自BLOCK的域。在这个场景中,在约束传播期间,工具会比较BLOCK中的原子电源域与TOP设计中的非原子电源域,发现电源域不匹配。在这个场景中,在约束传播期间,工具会比较BLOCK中的非原子电源域与TOP设计中的原子电源域,发现电源域不匹配。在这个场景中,在约束传播期间,工具会比较BLOCK中的原子电源域与TOP设计中的原子电源域,发现它们的一些属性不匹配。

QRBQ 750

解密Sunflower项目:从传统View到Jetpack Compose的平滑迁移实战手册

当Android开发者面对遗留的View-based应用时,技术债务和架构僵化常常成为创新的绊脚石。Sunflower项目作为Google官方的园艺管理应用,为我们展示了一条从传统View架构平滑过渡到Jetpack Compose的清晰路径。这个看似简单的植物管理应用背后,隐藏着Android现代化开发的最佳实践和架构演进智慧。 ## 从技术债务到架构新生:为什么迁移是必然选择 每个Andr

gitblog_00872的博客 913

建行报专版报道建设银行金融科技发展历程

经过十多年的建设,总行前中后台部门都有了自己的业务系统,但系统“部门”特征显著,渠道、客户、产品的横向整合不足,产品系统层次化、结构化、参数化程度不高,渠道支持产品快速部署以及跨渠道服务能力不足,管理分析类系统建设相对滞后,系统较弱的可扩展能力在应对高速增长的交易量时已疲态尽显,同时安全稳定运行的压力和风险日益积聚。站在新的历史起点上,科技条线将聚焦主责主业,完善信息科技管理体系,紧紧围绕安全生产中心任务,持续推动技术能力复用共享和自主可控,为全行做好金融五篇大文章,推动业务高质量发展提供技术支撑。

银行信息系统应用架构详解 384

Android Sunflower完整指南:掌握Jetpack Compose迁移的最佳实践

**一句话介绍**:Sunflower是一个展示Android开发最佳实践的园艺应用,通过将传统View-based应用迁移到Jetpack Compose,为你提供现代Android开发的完整学习路径!🌻 ## 核心关键词 - Jetpack Compose迁移 - Android开发最佳实践 - 现代Android架构 - 园艺应用开发 - Material Design 3 ## 项目

gitblog_00301的博客 434

YOLOv5源码逐行超详细注释与解读(1)——项目目录结构解析

全网最全YOLOv5项目目录结构超详细分析。逐个文件注释,小白上手必备

路人贾的博客 9万+

电源防反接保护电路全攻略实战A04

本文深入剖析了硬件设计中电源保护电路的关键技术与实战经验。文章指出,保护电路虽小但至关重要,通过对比分析二极管与MOSFET防反接方案,揭示了MOSFET在效率、温控方面的优势。针对过压保护,重点讲解了TVS二极管选型要点,强调钳位电压而非击穿电压才是保护核心。文章结合工业案例(如48V通信模块烧毁、5V系统MOSFET过热等),详细阐述了PCB布局规范、热设计路径等工程细节,并提供了USB接口ESD防护的完整选型方案。最后强调硬件设计必须考虑最坏工况,在成本与性能间找到平衡点,避免因小失大。

启芯硬件的博客 776

ModularizationExample与Plaid、Sunflower对比:哪个更适合你的Android项目?

Android模块化开发已成为大型应用架构的首选方案,但面对众多开源示例项目,开发者往往难以选择最适合自己的学习和实践对象。本文将深入对比ModularizationExample、Plaid和Sunflower三个主流Android模块化项目,从架构设计、功能实现和学习曲线三个维度为你提供清晰的选择指南,助你快速找到匹配项目需求的最佳实践方案。 ## 📱 项目架构深度解析 ### Modu

gitblog_00354的博客 836

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android Sunflower 项目教程

Android Sunflower 是一个展示 Android 开发最佳实践的应用程序,特别关注于从基于 View 的应用程序迁移到 Jetpack Compose。该项目由 Google 维护,旨在帮助开发者理解和实践 Jetpack Compose 的使用。 ### 主要特点 - **迁移示例**:展示了如何将一个基于 View 的应用程序迁移到 Jetpack Compose。 - **最...

gitblog_00312的博客 991

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Jetpack 练手项目 —— Sunflower

Sunflower 是 Google 官方提供的 Jetpack 练手项目,起初是用 Java 实现的,并逐步演进为现在的完全由 Kotlin 实现。它的页面如下: 图一展示在“我的花园”中已经种植了哪些植物,点击左上角的菜单按钮会弹出图二的抽屉布局,菜单中有“我的花园”和“植物目录”两个选项,点击植物目录会进入图三展示所有植物种类的页面,点击某一种植物后会进入图四的植物详情页面,在该页面点击右下角按钮后会将其添加到图一“我的花园”页面中。本篇文章会介绍 Java 实现该 Demo 的过程。按照 Googl

tmacfrank 1088

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Android Sunflower 带您玩转 Jetpack

作者:宋立心 (Tiem Song), Android 软件工程师△ 插图作者:Virginia Poltrack在 Google I/O 2018 开发者大会上,我们推...

谷歌开发者 2731

如何让2008-2017年老款Mac重获新生:OpenCore Legacy Patcher完全指南

你是否还在为手中的老款Mac无法升级到最新macOS系统而烦恼?看着那些依然性能强劲的2015年前MacBook Pro、iMac 2012等经典设备被苹果官方抛弃,却无法享受现代操作系统的流畅体验?OpenCore Legacy Patcher(OCLP)正是为解决这一痛点而生的开源工具,它能让你的老Mac重获新生,安装并运行macOS Big Sur、Monterey、Ventura、Sono

gitblog_00737的博客 932

Android Sunflower项目重构指南:Jetpack Compose园艺应用创新开发方案

Android Sunflower作为Google官方技术示范项目,为开发者呈现了从传统View系统到Jetpack Compose的完整技术演进路径。这个园艺管理应用不仅具备实用功能,更重要的是展示了现代Android开发的最佳实践模式。 ## 架构设计创新特色 ### 用户界面技术革新 - **声明式编程范式**:彻底告别XML布局的繁琐 - **Material Design 3标准**

gitblog_00362的博客 826

Android架构迁移实战:从传统View到Jetpack Compose的完整升级指南

Sunflower项目是Google官方推出的Android园艺应用示例,它不仅仅是一个简单的植物管理应用,更是一个展示Android开发最佳实践的完整教学案例。这个项目最初基于传统View系统构建,随后经历了从Material 2到Material 3、从Fragment到Jetpack Compose的完整迁移过程,为开发者提供了从传统Android开发到现代声明式UI的完整迁移路线图。 #

gitblog_00641的博客 708
上一篇: gRPC详细入门教程,Golang/Python/PHP多语言讲解
下一篇: What‘s New in Dubbo3
offbye
offbye 领域专家: 操作系统技术领域 领域专家: 操作系统技术领域
博客等级 码龄24年 1309粉丝 252原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

offbye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值