Giter Club home page Giter Club logo

jimu's Introduction

JIMU

PRs Welcome License

项目介绍

JIMU(积木)是一套Android组件化框架,支持组件的代码资源隔离、单独调试、集成调试、组件交互、UI跳转、生命周期等完整功能。

取名为JIMU(积木),其含义是应用这套框架可以做到组件之间的完全隔离,每个组件可以单独运行,同时又可以通过“接口”任意拼接成一个完成APP,这种能力就是我们实施组件化的最终目的。

最新版本

2021-06-10补充: 因为我的错误操作,导致发布到MavenCentral的版本:

  • build-gradle:1.3.5
  • componentlib: 1.3.3
  • router-anno-compiler: 1.0.1 均出现了Pom文件错误,遗失了dependency,再问题被修正前,可以按照hotfix-bad-pom分支的内容,做紧急修复。致歉 -- leobert

2021-05-23补充: 受JFrog运营策略影响,项目重新发布到MavenCentral,注意仓库变更

release-note&change-logs 关注版本变更以及注意事项是个好习惯。

模块 build-gradle componentlib router-anno-compiler router-annotation
最新版本 Download Download Download Download

实现功能:

  • 组件可以单独调试
  • 杜绝组件之前相互耦合,代码完全隔离,彻底解耦
  • 组件之间通过接口+实现的方式进行数据传输
  • 使用scheme和host路由的方式进行activity之间的跳转
  • 自动生成路由跳转路由表
  • 任意组件可以充当host,集成其他组件进行集成调试
  • 可以动态对已集成的组件进行加载和卸载
  • 支持kotlin组件
  • 组件独立运行的Manifest可以基于“壳”和组件原始的Manifest合并生成(from version 1.3.4)
  • 组件初始化支持按序(from version 1.3.4)这部分基于Maat, 参考博客

原理解析

组件化设计思路 浅谈Android组件化

原理解释请参考文章Android彻底组件化方案实践

demo解读请参考文章Android彻底组件化demo发布

按序初始化业务组件请参考文章组件化:代码隔离也难不倒组件的按序初始化

单项目,多module背景下,依赖方式的优雅实践探索:三思系列:组件化场景下module依赖优雅实践方案

使用指南

1、主项目引用编译脚本

在根目录的gradle.properties文件中,增加属性:

mainmodulename=app

其中mainmodulename是项目中的host工程,一般为app

添加mavenCentral仓库

在根目录的build.gradle中增加配置

buildscript {
    dependencies {
        classpath 'io.github.leobert-lan:jimu-build-gradle:A.B.C'
    }
}

A.B.C是版本号,最新的版本号可以参考上面的MavenCentral外链

为每个组件引入依赖库,如果项目中存在basiclib等基础库,可以统一交给basiclib引入

compile 'io.github.leobert-lan:jimu-componentlib:A.B.C'

注意GroupId和ArtifactId在重新发布到MavenCentral后已经变更

'componentLib'        : 'io.github.leobert-lan:jimu-componentlib:{version}',
'router_anno'         : 'io.github.leobert-lan:jimu-router-annotation:{version}',
'router_anno_compiler': 'io.github.leobert-lan:jimu-router-anno-compiler:{version}',

2、拆分组件为module工程

在每个组件的工程目录下新建文件gradle.properties文件,增加以下配置:

isRunAlone=true
debugComponent=sharecomponent
compileComponent=sharecomponent

上面三个属性分别对应是否单独调试、debug模式下依赖的组件,release模式下依赖的组件。具体使用方式请解释请参见上文第二篇文章

3、应用组件化编译脚本

在组件和host的build.gradle都增加配置:

apply plugin: 'com.dd.comgradle'

注意:不需要在引用com.android.application或者com.android.library

同时增加以下extension配置:

combuild {
    applicationName = 'com.luojilab.reader.runalone.application.ReaderApplication'
    isRegisterCompoAuto = true
}

组件注册还支持反射的方式,有关isRegisterCompoAuto的解释请参见上文第二篇文章

1.3.4新特性
def projectRoot = project.getRootProject().rootDir.absolutePath

combuild {
    applicationName = 'com.luojilab.reader.runalone.application.ReaderApplication'
    isRegisterCompoAuto = false

    originalManifest = projectRoot + "/readercomponent/src/main/AndroidManifest.xml"

    runAloneManifest = projectRoot + "/readercomponent/src/main/runalone/AndroidManifest.xml"
    targetManifest = projectRoot + "/readercomponent/src/main/runalone/mergedManifest.xml"
    //如果不需要合并,改为false
    enableManifestMerge = true
}

增加了5个可配项目:

  • useMaat 默认为true,本处没有写,如果你不打算使用Maat,务必改为false,否则会织入代码并发生ClassNotFoundException
  • originalManifest 原始manifest文件路径
  • runAloneManifest 一个壳manifest,用于指定独立运行时额外需要的权限、Application配置,启动Activity、额外的四大组件,metadata
  • targetManifest 合并后输出的manifest,需要先创建文件,runalone使用的manifest;如不先创建会影响gradle任务,被认为是一个缺失manifest的Component!
  • enableManifestMerge 如果是true,则会在合适的时机执行manifest合并功能,并且插件中增加的如:runaloneMergeDebugManifest等任务会执行合并,否则该任务并不会合并manifest文件

4、混淆

在混淆文件中增加如下配置

-keep interface * {
  <methods>;
}
-keep class com.luojilab.component.componentlib.** {*;}
-keep class com.luojilab.gen.router.** {*;}
-keep class * implements com.luojilab.component.componentlib.router.ISyringe {*;}
-keep class * implements com.luojilab.component.componentlib.applicationlike.IApplicationLike {*;}

注意:com.luojilab.component.componentlib和com.luojilab.gen.router包可能在项目迁移的过程中发生过或即将发生变化,文档更新不一定及时,请手工确认一下生成类的包路径。

关于如何进行组件之间数据交互和UI跳转,请参看 Wiki 关于消息中间件,请参考v1.3.3releaseNote

组件化讨论群

JIMU的讨论群,群号693097923,欢迎大家加入:

进群请扫码

PS:最近千人群满了,建议一些基础性问题仔细琢磨下文章,比较麻烦的问题提issue求助。

jimu's People

Contributors

adajqd avatar lanjun111 avatar leobert-lan avatar monkeydone avatar mqzhangw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jimu's Issues

這個專案 gradle 版本?

我用 gradle-4.6-all 是無法使用的

Parallel execution is an incubating feature.

FAILURE: Build failed with an exception.

  • What went wrong:
    org.gradle.api.internal.artifacts.ivyservice.projectmodule.DefaultProjectPublication.(Lorg/gradle/api/artifacts/ModuleVersionIdentifier;)V

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

CONFIGURE FAILED in 0s
Unable to find method 'org.gradle.api.internal.artifacts.ivyservice.projectmodule.DefaultProjectPublication.(Lorg/gradle/api/artifacts/ModuleVersionIdentifier;)V'.
Possible causes for this unexpected error include:

  • Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
    Re-download dependencies and sync project (requires network)
  • The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem.
    Stop Gradle build processes (requires restart)
  • Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project.
In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.

去查了所用的
android-maven-gradle-plugin:1.5

dcendents/android-maven-gradle-plugin#66
要升級 2.1
但是
升級完會出現

  • Where:
    Script '/Users/loverfiend/Desktop/project/JIMU/jimu-core/installv1.gradle' line: 1

  • What went wrong:
    A problem occurred evaluating script.

Failed to apply plugin [id 'com.github.dcendents.android-maven']
Configuration with name 'api' not found.

所以想問一下這專案gradle本版是使用啥
看起來4.6 跑不起來

多module之间的资源文件的引用

你的Demo代码过少,看不出来什么,我建立一个公共的Module,用来存放公共的Java代码和res资源文件,引用java代码没有问题,但是引用layout文件会找不到,drawable之类的可以找到,但是需要import一个新的R文件,这样在一个Activity里就有2个R文件的引用了。关于这个不知作者有没有什么体会,希望不吝赐教,谢谢

已解决

Cannot read packageName from ..\src\main\runalone\AndroidManifest.xml

auto register issue

之前一些朋友提过疑问:为什么readerComponent已经标明isRegisterCompoAuto = false但是被集成到宿主中时,其APPLike还是被初始化了。

当时这些朋友被我误导了。原有设计中,isRegisterCompoAuto代表的是,以该Module作为宿主编译时,寄生的Module是否被自动集成(注意,是全部)
long long ago的时候在群里面讨论过这个设计,我是期望设计成寄生Module被集成时是否被自动集成(没记错当时是插件1.1.0版本)所以一直有这样一个映像在脑海中。

进过一些思考,这两种设计都有利弊,所以我在原有的设计上进行了一定的增强:

  • isRegisterCompoAuto 依旧代表寄生的Module是否采取自动集成
    *添加一个注解标识某些Module规避自动集成。

原来的issue并没有找到,新提一个。

java.lang.ClassNotFoundException: com.luojilab.gen.router.AppUiRouter

运行是可以的,但是主app中的build文件的apt中没有自动生成AppUiRouter,排查也没有使用混淆,后来在QQ群中求助,原来是主app中的至少要有一个Activity进行RouteNode()注解才能自动生成,望作者可以提醒一下新手,谢谢。

在app gadle.properties 中compileComponent=module名字时,一直报这个错,看了下demo,没有找到问题,希望得到解决

Unable to find source java class: 'E:\zkb\zMall\trunk\code\ZkbAndroid\zkb\homepage\src\main\runalone\java\com\zkb\homepage\application\HomePageActivityModule.java' because it does not belong to any of the source dirs: '[E:\zkb\zMall\trunk\code\ZkbAndroid\zkb\homepage\src\main\java, E:\zkb\zMall\trunk\code\ZkbAndroid\zkb\homepage\src\debug\java, E:\zkb\zMall\trunk\code\ZkbAndroid\zkb\homepage\build\generated\source\r\debug, E:\zkb\zMall\trunk\code\ZkbAndroid\zkb\homepage\build\generated\source\buildConfig\debug, E:\zkb\zMall\trunk\code\ZkbAndroid\zkb\homepage\build\generated\source\aidl\debug, E:\zkb\zMall\trunk\code\ZkbAndroid\zkb\homepage\build\generated\source\rs\debug]'

同步问题

sharecomponent -->Activity的资源文件 添加一个Textview属性

运行 app 的share模块不同步

运行reader 的share模块同步

运行share 的share模块同步

app 的share模块是怎摸使其同步资源或者修改呢?

compileDebugJavaWithJavac

conponent以application编译之后,再编译app,就会出现以下错误,有遇到过吗?

  • What went wrong:
    Execution failed for task '::compileDebugJavaWithJavac'.

Unable to find source java class: '/src/main/runalone/java/com/runalone/application/Application.java' because it does not belong to any of the source dirs: '[/Users/admin/src/main/java, /Users/admin/src/main/java, /Users/admin/src/debug/java, /Users/admint/build/generated/source/r/debug, /Users/admint/build/generated/source/buildConfig/debug, /Users/admint/build/generated/source/aidl/debug, /Users/admin/build/generated/source/rs/debug]'

Gradle插件与uploadArchives

在组件里 build.gradle 里使用了我们自定义的Gradle插件 再使用uploadArchives 无法上传aar包到maven服务器 显示任务执行完成但是实际没有成功。uploadArchives的相关任务都没有执行,请问 怎么解决呢?

WIN10下,Android Studio 3.1.1 上的使用问题

在WIN10系统下:
版本:Android Studio 3.1.1
classpath 'com.android.tools.build:gradle:3.1.1'
gradle-4.4版本
第一次能编译能通过,第二次编译必现:
Could not delete path ... app\build\intermediates\transforms\desugar\debug\0.jar

jar文件被占用,该问题必现。必须手动结束所有java进程,才能再次编译,很影响效率。
目前不知道问题在哪里,该怎么排查,不集成JIMU不会有这个问题。

Kotlin+DataBinding+JIMU遇到的问题

如题, 目前我是将项目分成
app (host)
app-1
app-2
...
这样的模块化. 之前在集成项目时写了个demo 各module均可单独运行, host也可运行. 但是最近开发时出现了问题. 只要app 依赖 app-x 就会报错
image
Btw , 路由用的阿里的ARouter

build-gradle插件疑问

本人先把build-gradle插件运行在本地仓库方便调试
运行任意 modle task 例如 readercomponent/ Tasks/install/ installDebug
getTaskInfo方法 返回的AssembleTask对象里的 List modules 添加的 一直是 all。
导致 fetchMainModulename方法里compilemodule 一直是app
导致 非mainmodule的组件 isRunAlone 被置为false。。
组件被视为一个依赖库添加 project.apply plugin: 'com.android.library'
没有生成对应apk安装到手机上,
问题 同时发现 运行 installDebug 任务 安装的readercomponent-debug-androidTest.apk
Installing APK 'readercomponent-debug-androidTest.apk' on 'HL3001 - 6.0.1' for readercomponent:debugAndroidTest
Installed on 1 device.
BUILD SUCCESSFUL
下午 4:06:45: Task execution finished 'installDebug'.

关于集成最终打包apk问题。

我是将module打包aar文件,在app里面引用。
1:最后集成打包成最终的apk时候,安装会生成两个或多个应用,一个是app,一个是module应用。
2:module的名字还和app的一样,好像被app的名字代替了,我明明在module里面写的是module的名字。

clone下来无法编译过

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.

Job failed, see logs for details

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

Error:java.lang.RuntimeException: java.lang.NullPointerException: element == null

我仿照您的代码,编译报错:Error:java.lang.RuntimeException: java.lang.NullPointerException: element == null;
在messages中看到如下错误信息:
注: [Router-Anno-Compiler]-- >>> AutowiredProcessor init. <<<
注: [Router-Anno-Compiler]-- >>> host is app <<<
注: [Router-Anno-Compiler]-- >>> RouteProcessor init. <<<
注: [Router-Anno-Compiler]-- >>> Found routes, start... <<<
注: [Router-Anno-Compiler]-- >>> Found activity route: com.test.jm.MainActivity <<<
:app:compileDebugJavaWithJavac FAILED
:app:compileDebugJavaWithJavac (Thread[Daemon worker Thread 46,5,main]) completed. Took 0.647 secs.

现在一直无法解决。烦劳大神判断一下什么地方不对!

javassist.NotFoundException: broken jar file?: com.yibogame.component.app.module1.applike.Module1AppLike

自己写了一个测试module,报了这个错。啥原因呢?

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:transformClassesWithComponentCodeForDebug'.
> javassist.NotFoundException: broken jar file?: com.yibogame.component.app.module1.applike.Module1AppLike

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2s

Gradle报错,我的Gradle版本是4.6,项目里的各个插件版本需要更新了吧

Unable to find method 'org.gradle.api.internal.artifacts.ivyservice.projectmodule.DefaultProjectPublication.(Lorg/gradle/api/artifacts/ModuleVersionIdentifier;)V'.
Possible causes for this unexpected error include:

  • Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
    Re-download dependencies and sync project (requires network)
  • The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem.
    Stop Gradle build processes (requires restart)
  • Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project.
In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.

关于ui的耦合问题

有这样的场景,使用了一个开源库里的view,把这个库单独作为一个module,现在在主module里怎么使用这个view,如果直接在布局文件里使用的话就会造成主module与开源库的module代码耦合,当然根据你的demo可以在service里通过提供类似getXxxView方法,主module可以获得到此View,但是这样做的缺点是1.只能通过代码动态添加view,不能写布局文件。如果现有项目里已经使用了布局文件方式,然后全部改成使用代码方式也比较麻烦。2.无法使用此view里的方法。请问一下,有没有比较好的方法来解决类似ui代码的耦合问题。谢谢

低版本无法兼容运行的问题

编译版本27 然后经过了测试机和 模拟器多种方式测试,发现只有7.0以上的手机能加载组件,6.0及以下的版本都不能加载组件,这是什么原因?

引入rxlifecycle:2.2.2引起的问题

在baseLib里面引入了com.trello.rxlifecycle2:rxlifecycle:2.2.2 com.trello.rxlifecycle2:rxlifecycle-components:2.2.2 出现了:
java.lang.Error: Cleaner terminated abnormally
at sun.misc.Cleaner$1.run(Cleaner.java:148)
at sun.misc.Cleaner$1.run(Cleaner.java:145)
at java.security.AccessController.doPrivileged(Native Method)
at sun.misc.Cleaner.clean(Cleaner.java:145)
at sun.nio.ch.FileChannelImpl.unmap(FileChannelImpl.java:849)
at sun.nio.ch.FileChannelImpl.transferFromFileChannel(FileChannelImpl.java:647)
at sun.nio.ch.FileChannelImpl.transferFrom(FileChannelImpl.java:708)
at org.apache.commons.io.FileUtils.doCopyFile(FileUtils.java:1147)
at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1091)
at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1038)
at org.apache.commons.io.FileUtils$copyFile$0.call(Unknown Source)
at com.dd.buildgradle.ComCodeTransform$_transform_closure3$_closure5.doCall(ComCodeTransform.groovy:79)
at sun.reflect.GeneratedMethodAccessor166.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
。。。。

Caused by: java.io.IOException: 试图访问无效的地址。
at sun.nio.ch.FileChannelImpl.unmap0(Native Method)
at sun.nio.ch.FileChannelImpl.access$000(FileChannelImpl.java:50)
at sun.nio.ch.FileChannelImpl$Unmapper.run(FileChannelImpl.java:826)
at sun.misc.Cleaner.clean(Cleaner.java:143)
... 99 more

关于component R资源问题及databinding问题。

如果单独运行conponent,则每次生成的databing再切回去运行app时会报错。
如果耽误运行component,则每次在类比如activity中需要导入当前R文件,在运行app时会报错。
希望作者百忙之中能看下,

建议

// 是否是maven 坐标
            if (StringUtil.isMavenArtifact(str)) {
                /**
                 * 示例语法:groupId:artifactId:version(@aar)
                 * compileComponent=com.luojilab.reader:readercomponent:1.0.0
                 * 注意,前提是已经将组件aar文件发布到maven上,并配置了相应的repositories
                 */
                if (!str.equals(currentModule)) {
                    project.dependencies.add("api", str)
                    System.out.println("add dependencies lib  : " + str)
                }
            } 

if (!str.equals(currentModule)) {}
假如一个判断 如果当前编译的不是主module 主module就不引用子module,这样在主module的配置文件中也就不用改了

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.