Android AGP8.1.0组件化初探

Android AGP8.1.0组件化初探

在这里插入图片描述

前言:

前面两篇完成了从AGP4.2到 AGP8.1.0的升级,本文是由于有哥们留言说在AGP8.0中使用ARouter组件化有问题,于是趁休息时间尝试了一下,写了几个demo,发现都没有问题,跳转和传值都是正常的,这里我也是直接从groovy转换成version-catalogs的依赖方式,由于之前升级过,所以这次很顺利,几分钟就完成了,直接上代码:

1.添加统一依赖:

[versions]
agp = "8.1.0"
androidx-espresso-core = "3.4.0"
androidx-junit = "1.1.3"
org-jetbrains-kotlin-android = "1.8.0"
core-ktx = "1.10.1"
junit = "4.13.2"
androidx-test-ext-junit = "1.1.5"
espresso-core = "3.5.1"
appcompat = "1.6.1"
material = "1.9.0"
constraintlayout = "2.1.4"
mmkv = "1.3.1"
utilcodex = "1.31.1"
arouter = "1.5.2"
arouter-compiler = "1.5.2"
org-jetbrains-kotlin-kapt = "1.8.0"[libraries]
androidx-espresso-core-3_4_0 = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso-core" }
androidx-junit-1_1_3 = { module = "androidx.test.ext:junit", version.ref = "androidx-junit" }
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" }
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
mmkv = { group = "com.tencent", name = "mmkv", version.ref = "mmkv" }
utilcodex = {group = "com.blankj",name = "utilcodex",version.ref = "utilcodex"}
arouter = {group = "com.alibaba",name = "arouter-api",version.ref = "arouter"}
arouter-compiler = {group = "com.alibaba",name = "arouter-compiler",version.ref = "arouter-compiler"}[plugins]
com-android-library = { id = "com.android.library", version.ref = "agp" }
com-android-application = { id = "com.android.application", version.ref = "agp" }
org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "org-jetbrains-kotlin-android" }
org-jetbrains-kotlin-kapt = {id = "org.jetbrains.kotlin.kapt",version.ref = "org-jetbrains-kotlin-kapt"}[bundles]

2.添加lib-common组件配置:

@Suppress("DSL_SCOPE_VIOLATION")
plugins {alias(libs.plugins.com.android.library)alias(libs.plugins.org.jetbrains.kotlin.android)alias(libs.plugins.org.jetbrains.kotlin.kapt)
}
dependencies {implementation(libs.core.ktx)implementation(libs.appcompat)implementation(libs.material)implementation(libs.arouter)kapt(libs.arouter.compiler)testImplementation(libs.junit)androidTestImplementation(libs.androidx.test.ext.junit)androidTestImplementation(libs.espresso.core)
}kapt {arguments {arg("AROUTER_MODULE_NAME", project.name)}
}

完整配置:

@Suppress("DSL_SCOPE_VIOLATION")
plugins {alias(libs.plugins.com.android.library)alias(libs.plugins.org.jetbrains.kotlin.android)alias(libs.plugins.org.jetbrains.kotlin.kapt)
}android {namespace = "com.example.lib_cmmon"compileSdk = 33defaultConfig {//applicationId = "com.example.lib_cmmon"minSdk = 23targetSdk = 33// versionCode = 1// versionName = "1.0"testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {isMinifyEnabled = falseproguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),"proguard-rules.pro")}}compileOptions {sourceCompatibility = JavaVersion.VERSION_17targetCompatibility = JavaVersion.VERSION_17}kotlinOptions {jvmTarget = "17"}
}dependencies {implementation(libs.core.ktx)implementation(libs.appcompat)implementation(libs.material)implementation(libs.arouter)kapt(libs.arouter.compiler)testImplementation(libs.junit)androidTestImplementation(libs.androidx.test.ext.junit)androidTestImplementation(libs.espresso.core)
}kapt {arguments {arg("AROUTER_MODULE_NAME", project.name)}
}

3.lib-common添加ARouter初始化:

/*** @author: njb* @date: 2023/8/26 22:21* @desc:*/
public class BaseApp extends Application {@Overridepublic void onCreate() {super.onCreate();initARouter();}private void initARouter() {ARouter.openDebug();ARouter.openLog();ARouter.init(this);}
}

4.添加lib-arouter组件配置:

@Suppress("DSL_SCOPE_VIOLATION")
plugins {alias(libs.plugins.com.android.library)alias(libs.plugins.org.jetbrains.kotlin.android)alias(libs.plugins.org.jetbrains.kotlin.kapt)
}android {namespace = "com.example.lib_arouter"compileSdk = 33defaultConfig {// applicationId = "com.example.lib_arouter"minSdk = 23targetSdk = 33//versionCode = 1// versionName = "1.0"testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {isMinifyEnabled = falseproguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),"proguard-rules.pro")}}compileOptions {sourceCompatibility = JavaVersion.VERSION_17targetCompatibility = JavaVersion.VERSION_17}
}dependencies {implementation(libs.appcompat)implementation(libs.material)implementation(libs.constraintlayout)testImplementation(libs.junit)androidTestImplementation(libs.androidx.test.ext.junit)androidTestImplementation(libs.espresso.core)implementation(libs.arouter)kapt(libs.arouter.compiler)implementation(project(":lib-common"))
}kapt {arguments {arg("AROUTER_MODULE_NAME", project.name)}
}

5.调用ARouter初始化:

/*** @author: njb* @date: 2023/8/26 22:21* @desc:*/
public class ARouterApp  extends BaseApp {@Overridepublic void onCreate() {super.onCreate();}
}

6.主模块依赖配置:

@Suppress("DSL_SCOPE_VIOLATION")
plugins {alias(libs.plugins.com.android.application)alias(libs.plugins.org.jetbrains.kotlin.android)alias(libs.plugins.org.jetbrains.kotlin.kapt)
}android {namespace =  "com.example.writelogdemo"compileSdk = 33defaultConfig {applicationId  = "com.example.writelogdemo"minSdk = 23targetSdk = 33versionCode = 1versionName = "1.0"testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {isMinifyEnabled = falseproguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),"proguard-rules.pro")}}compileOptions {sourceCompatibility = JavaVersion.VERSION_17targetCompatibility = JavaVersion.VERSION_17}kotlinOptions {jvmTarget = "17"}
}dependencies {implementation(libs.core.ktx)implementation(libs.appcompat)implementation(libs.material)implementation(libs.constraintlayout)testImplementation(libs.junit)androidTestImplementation(libs.androidx.test.ext.junit)androidTestImplementation(libs.espresso.core)implementation(libs.utilcodex)implementation(libs.arouter)kapt(libs.arouter.compiler)implementation(project(":lib-arouter"))implementation(project(":lib-common"))
}

7.添加ARouter组件化配置:

7.1 引入ARouter依赖:

这里我用的是catelog方式,所以使用kapt方式

@Suppress("DSL_SCOPE_VIOLATION")
plugins {alias(libs.plugins.com.android.library)alias(libs.plugins.org.jetbrains.kotlin.android)alias(libs.plugins.org.jetbrains.kotlin.kapt)
}implementation(libs.arouter)
kapt(libs.arouter.compiler)

7.2 添加模块名称配置:

kapt {arguments {arg("AROUTER_MODULE_NAME", project.name)}
}

7.3 主模块ARouter初始化:

/*** @author: njb* @date: 2023/8/25 22:36* @desc:*/
public class LogApp extends BaseApp {private static LogApp mInstance;@Overridepublic void onCreate() {super.onCreate();mInstance = this;}public static LogApp getInstance() {return mInstance;}
}

7.4 在Activity中绑定Arouter:

ARouter.getInstance().inject(this)

7.5 添加Arouter跳转和传值:

userList = arrayListOf("年龄18","John","身高180","体重60kg","性别female")
tvText.setOnClickListener {ARouter.getInstance().build("/test/TestSplashActivity").withString("name","test张三").withSerializable("userList",userList).navigation()

7.6 test模块添加跳转路径和数据接收:

@Route(path = "/test/TestSplashActivity")
class TestSplashActivity : AppCompatActivity() {val TAG = "TestARouter"@Autowired(name = "name")@JvmFieldvar name: String = ""@Autowired(name = "userList")@JvmFieldvar mList:ArrayList<String> ?= nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_test_splash)ARouter.getInstance().inject(this)initView()}private fun initView() {tvName.text = "测试ARouter跳转$name"tvTextView.text = mList.toString()}
}

8.完整使用示例:

package com.example.writelogdemoimport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import com.alibaba.android.arouter.launcher.ARouterclass MainActivity : AppCompatActivity() {private val tvText : TextView by lazy { findViewById(R.id.tvTest) }var userList:ArrayList<String> ?= nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)ARouter.getInstance().inject(this)userList = arrayListOf("年龄18","John","身高180","体重60kg","性别female")tvText.setOnClickListener {ARouter.getInstance().build("/test/TestSplashActivity").withString("name","test张三").withSerializable("userList",userList).navigation()}}
}

9.主模块布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/tvTest"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

10.lib-arouter测试代码:

package com.example.lib_arouterimport android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.facade.annotation.Autowired
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter@SuppressLint("CustomSplashScreen")
@Route(path = "/test/TestSplashActivity")
class TestSplashActivity : AppCompatActivity() {val TAG = "TestARouter"val tvName:TextView by lazy { findViewById(R.id.tv_name) }val tvTextView:TextView by lazy { findViewById(R.id.tv_test) }@Autowired(name = "name")@JvmFieldvar name: String = ""@Autowired(name = "userList")@JvmFieldvar mList:ArrayList<String> ?= nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_test_splash)ARouter.getInstance().inject(this)Log.d(TAG, "测试ARouter数据传递$name$mList")initView()}private fun initView() {tvName.text = nametvTextView.text = mList.toString()}
}

11.lib-arouter布局代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".TestSplashActivity"><TextViewandroid:id="@+id/tv_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="这是Arouter测试"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/tv_test"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="30dp"android:text="这是数组"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/tv_name" /></androidx.constraintlayout.widget.ConstraintLayout>

12.日志打印如下:

在这里插入图片描述

13.实现效果如下:

在这里插入图片描述

在这里插入图片描述

14.遇到问题:

14.1 测试模块配置不对

由于我是直接新建的模块,所以当作完整项目配置的,这里如果只是测试组件化需要修改配置

在这里插入图片描述

解决方法修改libs.plugins.com.android.application为libs.plugins.com.android.library
在这里插入图片描述

修改完成后可以正常运行:

14.2 跳转时提示path找不到

解决方法:
a.按照上面7中的步骤配置主模块和其他组件模块,一个都不能少。

​b.同时在跳转时保证路径一致即可。

若配置完还有问题,请仔细检查每一步,直到正常跳转和数据传递,本人是亲自尝试了多个项目,基本上都没问题.

14.3 数据传递和接收问题

在这里插入图片描述

解决方法:

a.在kotlin中使用ARouter接收数据时需要使用@JvmField关键字

b.@Autowired(name = “name”),name一定要和传递时一致

c.传递数组时记得序列化,接收也是一样

15.AGP8.1.0小技巧:

15.1 在没有添加统一依赖时配置:

implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
implementation("com.alibaba:arouter-api:1.5.2")
kapt("com.alibaba:arouter-compiler:1.5.2")
implementation(project(":lib-common"))

15.2 添加统一依赖库配置后:

如果添加了统一的catelog配置方式后导入依赖它会自动提示,不需要开发者手动导入,这点我感觉很爽,一键一直替换,用起来简直不要太安逸了,感兴趣的同学可以自行尝试,这里就简单举例。
在这里插入图片描述
在这里插入图片描述

16.总结:

以上就是今天博客的内容在AGP8.1.0中使用组件化和遇到问题,其实本文的目的不是在于如何使用,ARouter这个很简单,相信做过组件化的同学都会,只是需要遇到问题时学会分析和调试,要不然盲目猜测是不会有结果的。开发这条路任重而道远,希望大家都能上下求索,享受这个求索的过程,痛并快乐着,也很重要,新技术出来可以尝试,也可以根据自己需要调整,不一样说非得更新用这个新技术,只要能解决问题,咋好用咋来。

17.demo地址如下:

https://gitee.com/jackning_admin/write-log-demo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/63567.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【docker】容器的运行、停止、查看等基本操作

容器与镜像的区别 image镜像 Docker image是一个read-only文件&#xff0c;位于磁盘上这个文件包含文件系统&#xff0c;源码&#xff0c;库文件&#xff0c;依赖&#xff0c;工具等一些运行application所需要的文件可以理解成一个模板docker image具有分层的概念 container…

3D路径,控件

1控件拖入画板&#xff1a; 2属性配置&#xff1a; 1轨迹颜色 2 3 4

AI建模 | 物体三维重建的高效方法

三维重建是将客观世界中的物体在虚拟空间表达出来&#xff0c;在大众视野中&#xff0c;物品三维重建最直观的应用当属虚拟仿真和VR/AR导航。其实在学科专业领域&#xff0c;三维重建已经更早地应用在高精地图、测绘系统、城市规划等领域。 科技发展的终极方向应当是普适性&am…

R语言nlme、nlmer、lme4用(非)线性混合模型non-linear mixed model分析藻类数据实例...

原文链接&#xff1a;http://tecdat.cn/?p23426 混合线性模型&#xff0c;又名多层线性模型(Hierarchical linear model)。它比较适合处理嵌套设计(nested)的实验和调查研究数据&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 相关视频 序言 此外&#xff0…

uniapp 配置并使用 VueX

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 uni-app 内置了 VueX 1、创建需要的文件 右键点击 根目录【我的是 uni-shop】&#xff0c;然后新建 目录&a…

华为云云服务器评测|华为云云耀云服务器L实例使用教学

文章目录 教学小故事 教学 华为云云耀云服务器L实例是一款提供高效、可靠、安全的基础设施服务的云服务器。下面是使用教学&#xff1a; 登录华为云官网。 测评产品链接&#xff1a;https://www.huaweicloud.com/product/hecs-light.html 进入云耀云服务器管理控制台&#xf…

go语言--锁

锁的基础&#xff0c;go的锁是构建在原子操作和信号锁之上的 原子锁 原子包实现协程的对同一个数据的操作&#xff0c;可以实现原子操作&#xff0c;只能用于简单变量的简单操作&#xff0c;可以把多个操作变成一个操作 sema锁 也叫信号量锁/信号锁 核心是一个uint32值&#…

【Vue3】组件递归

【Vue3】组件递归 实现效果 通过传入一个数字&#xff0c;实现数字次循环 父组件 <script setup> import { ref } from "vue"; import RecursionMe from "./components/RecursionMe/index.vue";const level ref(0);const add () > level.val…

RocketMQ入门

安装 官网 https://rocketmq.apache.org/zh/docs/4.x/introduction/02quickstart 下载 https://archive.apache.org/dist/rocketmq/4.9.4/rocketmq-all-4.9.4-source-release.zip 解压后上传 启动NameServer 修改runserver.sh&#xff0c;分配内存如果比系统高会导致启动…

【MySQL】基础语法总结

MySQL 基础语句 一、DDL 数据库定义语言 1.1CREATE 创建 1.1.1 创建数据库 语法结构 CREATE DATABASE database_name;示例 CREATE DATABASE demo;1.1.2 创建表 语法结构 CREATE TABLE 表名 (列1 数据类型,列2 数据类型,... );示例 CREATE TABLE new_user (id INT PRIMARY KE…

Apifox-比postman更优秀的接口自动化测试平台

一、Apifox介绍 Apifox 是 API 文档、API 调试、API Mock、API 自动化测试一体化协作平台&#xff0c;定位 Postman Swagger Mock JMeter。通过一套系统、一份数据&#xff0c;解决多个系统之间的数据同步问题。只要定义好 API 文档&#xff0c;API 调试、API 数据 Mock、AP…

画流程图都可以用哪些工具?

在日常生活中&#xff0c;我相信我们很多人都看到过流程图。对于设计师来说&#xff0c;它还需要涉及流程图来反映用户的旅程和交互方式。那么你知道哪些流行的流程图设计软件呢&#xff1f;作为高级设计师&#xff0c;我今天推荐10款流程图设计软件。你可以和我一起读这篇文章…

DEAP库文档教程三-----创建类型

本节将继续展示如何通过creator创建类型以及如何使用toolbox如何对复杂问题进行初始化。 Particle的初始化--粒子初始化 一个Particle是另一个特殊类型的个体&#xff0c;这是因为通常情况下它有一个速度&#xff0c;并且有一个最优的位置需要去记忆。这种类型个体的创建与通…

【实训项目】传道学习助手APP设计

1.设计摘要 跨入21世纪以来,伴随着时代的飞速发展&#xff0c;国民对教育的重视度也有了进一步的提升。我们不难发现虽然很多学习内容有学习资料或者答案&#xff0c;但是这些内容并不能达到让所有求学的人对所需知识进行完全地理解与掌握。所以我们需要进行提问与求助。那么一…

国产自主可控C++工业软件可视化图形架构源码

关于国产自主代替的问题是当前热点&#xff0c;尤其是工业软件领域。 “一个功能强大的全自主C跨平台图形可视化架构对开发自主可控工业基础软件至关重要&#xff01;” 作为全球领先的C工业基础图形可视化软件提供商&#xff0c;UCanCode软件有自己的思考&#xff0c;我们认…

Unity实现倒计时和获取系统时间

一:创建UGUI 1.创建Canvas画布组件,调节Canvas画布的分辨率等其他设置。我们可以把视图设置为2D模式下。 2.创建Text文本组件,取名为Timer计时器,我们调整Text文本组件的大小,用锚点设置Text文本组件的位置,并且设置好Text文本组件的颜色。 3.我们再创建一个Text文…

微服务架构|go-zero 的自适应熔断器

原文链接&#xff1a; go-zero 的自适应熔断器 上篇文章我们介绍了微服务的限流&#xff0c;详细分析了计数器限流和令牌桶限流算法&#xff0c;这篇文章来说说熔断。 熔断和限流还不太一样&#xff0c;限流是控制请求速率&#xff0c;只要还能承受&#xff0c;那么都会处理&…

C# 多线程交替按照指定顺序执行

1.关于AutoResetEvent和ManualResetEvent的区别解释如下&#xff1a; AutoResetEvent和ManualResetEvent是.NET中的两个线程同步类。它们之间的主要区别在于其释放信号的方式以及对等待线程的影响。 AutoResetEvent的作用是在等待的线程被信号唤醒后&#xff0c;将信号自动重…

Rust 学习笔记(持续更新中…)

一、 编译和运行是单独的两步 运行 Rust 程序之前必须先编译&#xff0c;命令为&#xff1a;rustc 源文件名 - rustc main.rs编译成功之后&#xff0c;会生成一个二进制文件 - 在 Windows 上还会生产一个 .pdb 文件 &#xff0c;里面包含调试信息Rust 是 ahead-of-time 编译的…

数据库-DML

DML&#xff1a;用来对数据库中表的数据记录进行增、删、改等操作。 添加数据&#xff08;INSERT&#xff09; insert语法&#xff1a; 指定字段添加数据&#xff1a;insert into 表单&#xff08;字段名1&#xff0c;字段名2&#xff09;values&#xff08;值1&#xff0c;值…