luojilab / ddcomponentforandroid Goto Github PK
View Code? Open in Web Editor NEW一套完整有效的android组件化方案,支持组件的组件完全隔离、单独调试、集成调试、组件交互、UI跳转、动态加载卸载等功能
License: MIT License
一套完整有效的android组件化方案,支持组件的组件完全隔离、单独调试、集成调试、组件交互、UI跳转、动态加载卸载等功能
License: MIT License
请问子组件如何调用App组件的接口? 是不是也要在App里实现IApplicationLike接口?
学习了一下,很不错,希望后期能优化支持 Instant Run,我们公司的项目,组件化已经一段时间了,确实没考虑很好的解耦,后面也会改成,面向接口的方式
如题,打得签名包,share module的label是“share”,但签名包安装后app的应用名也跟app的label一致
发现引用第三方库只能采用compile的方式,若用provided或者apt的方式都会导致找不到第三方的库,会报“错误:程序包xxx不存在”
不好意思,我又来打扰了!
根据咱们的思路,进行项目的组件拆分;拆分的时候遇到了写不太明确的地方,再次提问:
1.某个组件中使用了第三方,需要将主module(app)的主Activity赋值给第三方(third.a=MainActivity.class),这个要怎么拆?(主app对外提供一个服务?如果是的话,主app的ApplicationLike怎么注册)?
2.项目中的数据库,怎么拆?(不同组件可能都会用的数据库,数据库用的greendao)
如题
请教下,关于项目混淆,你们的方案是怎样的。aar引入的包你们是单独对每个组件做混淆吗。
startActivity 已实现
startActivityForResult 待实现
startActivities 待实现
对intent的FLAG进行支持 待实现
我打算把这个项目试用到我们新开发的项目中,还是发现各种各种的问题,比如,组件怎么跳到主app模块的activity中?比如当我组件测试完成后,将isAlone=false,然后运行assmeRealese,发现报一个找到模块的问题,比如某些本来没问题的模块资源会突然报无法转换成英文的问题,希望提高稳定性吧,感觉暂时不太适合用于正式项目。
Router.registerComponent();
router.addService();
uiRouter.registerUI();
这三种分别是什么作用
另外项目中
ReadBookService service = (ReadBookService)router.getService(ReadBookService.class.getSimpleName());
service始终是null,会是什么原因呢?
看了博客写的非常好,非常赞,我以前也经常看逻辑思维,只不过今年不在优酷播了之后就没看过了 哈哈哈.
发现了一个bug 第一次点击是无法卸载组件的.调试了一下应该是通过字节码插入模式调用IApplicationLike.onCreate的时候没有注册到Router的Map里面,导致我点击了卸载Share组件之后还能点击下面的文字跳转到ShareAct.不知道能否在用gradle插件 进行字节码插入的的时候把组件也注册到Router里面,这样的话应该就没有这个问题了.
如题,我引用的libs都在basiclib module,那么是每个module都针对用到的libs做混淆处理,还是只在app做混淆处理或者在basiclib做混淆处理?
现在打release包的时候由于有混淆,遇到了这样一个错误:Error:Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.
Unexpected scopes found in folder '/.../app/build/intermediates/transforms/proguard/release'. Required: EXTERNAL_LIBRARIES, PROJECT, SUB_PROJECTS. Found: LOCAL_DEPS, PROJECT
期待comgradle插件在添加依赖的过程能区分Variant,期望能给予支持,谢谢!
比如app有:
2个productFlavors: uat和prod
2个buildType:debug和release
那么会有4个Variant: uatDebug、uatRelease、prodRelease、prodDebug
看了下插件源码,是根据assemble任务是否是debug和release来添加依赖的,只区分了debug和release。
在library我尝试加入了以下代码:
project.afterEvaluate {
project.android.libraryVariants.all { BaseVariant variant ->
.....}
}
将打包区分Variant输入到不同路径下和发布是ok的。但在application去动态添加依赖一直不成功。
比如添加:
uatDebugCompile project(path: ':component_base', configuration: 'uatDebug')
uatReleaseCompile project(path: ':component_base', configuration: 'uatRelease')
prodDebugCompile project(path: ':component_base', configuration: 'prodDebug')
prodReleaseCompile project(path: ':component_base', configuration: 'prodRelease')
在project.afterEvaluate后添加,会报不能在afterEvaluate后改动依赖的错误。
不在project.afterEvaluate后添加,又不能获取到Variant,很纠结...
Error:(2, 0) Could not get unknown property 'mainmodulename' for root project 'ComponentPlugDemo2' of type org.gradle.api.Project.
为什么会找不到我的主项目名字 需要设置吗?
Error:Cannot read packageName from ...readercompone\src\main\runalone\AndroidManifest.xml
使用ButterKnife会出现空指针异常。
12-04 14:06:04.123 5233-5233/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.lxkj.yunhetong.component.testmoudle, PID: 5233 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lxkj.yunhetong.component.testmoudle/com.lxkj.yunhetong.component.testmoudle.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2984) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045) at android.app.ActivityThread.-wrap14(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6776) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.lxkj.yunhetong.component.testmoudle.MainActivity.onCreate(MainActivity.java:21) at android.app.Activity.performCreate(Activity.java:6956) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045) at android.app.ActivityThread.-wrap14(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6776) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
如果阅读与分享等组件单独调试运行的时候都需要一个公共的模块,比如Application类(用来初始化必要组件),启动页,可能还需要登录注册模块等,这部分代码放在哪比较合适。
如题,现在如果直接运行app,当调用用share项目时会报空指针(找不到share的application)
您好,你的组件化方案我从头看了一遍。有个小问题,如果启动一个组件的某个UI页面,能否用StartActivityForResult的方式,想要获取页面回调该如何操作呢?
Error:Execution failed for task ':app:transformClassesWithComponentCodeForDebug'.
No such property: Format for class: com.dd.buildgradle.ComCodeTransform
请问这个是什么原因?demo运行没有问题,删除repo后,重新上传到本地仓库运行出现的错误。
使用了viewdatabinding导出的aar包后 给app模块跑,出现异常,layout的问题,在另外一部电脑导出来的就出现系统生成的viewdatabind对应的类找不到~。。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: net.biaozhun.biaozhun_component, PID: 5119
java.lang.RuntimeException: Unable to start activity ComponentInfo{net.biaozhun.biaozhun_component/net.biaozhun.biaozhun_component.MainActivity}: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class layout
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2519)
at android.app.ActivityThread.access$900(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:635)
Caused by: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class layout
at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at net.biaozhun.framework_base.base.BaseDataBindingFragment.onCreateView(BaseDataBindingFragment.java:88)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:601)
at net.biaozhun.framework_base.base.BaseActivity.onStart(BaseActivity.java:87)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1238)
at android.app.Activity.performStart(Activity.java:6304)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2519)
at android.app.ActivityThread.access$900(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:635)
Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class layout
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:776)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at net.biaozhun.framework_base.base.BaseDataBindingFragment.onCreateView(BaseDataBindingFragment.java:88)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:601)
at net.biaozhun.framework_base.base.BaseActivity.onStart(BaseActivity.java:87)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1238)
at android.app.Activity.performStart(Activity.java:6304)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2519)
at android.app.ActivityThread.access$900(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:635)
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.layout" on path: DexPathList[[zip file "/data/app/net.biaozhun.biaozhun_component-2/base.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_dependencies_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_0_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_1_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_2_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_3_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_4_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_5_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_6_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_7_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_8_apk.apk", zip file "/data/app/net.biaozhun.biaozhun_component-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/net.biaozhun.biaozhun_component-2/lib/arm64, /vendor/lib64, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at android.view.LayoutInflater.createView(LayoutInflater.java:583)
at android.view.LayoutInflater.onCreateView
使用schme和host路由的方式进行activity之间的跳转
scheme
J:\DDComponentForAndroid-master\readercomponent\src\androidTest\java\com\mrzhang\comp_reader\ExampleInstrumentedTest.java
Error:(4, 28) 错误: 程序包android.support.test不存在
Error:(5, 35) 错误: 程序包android.support.test.runner不存在
Error:(7, 17) 错误: 程序包org.junit不存在
Error:(8, 24) 错误: 程序包org.junit.runner不存在
Error:(10, 24) 错误: 程序包org.junit不存在
Error:(17, 2) 错误: 找不到符号
符号: 类 RunWith
Error:(19, 6) 错误: 找不到符号
符号: 类 Test
位置: 类 ExampleInstrumentedTest
Error:(22, 30) 错误: 找不到符号
符号: 变量 InstrumentationRegistry
位置: 类 ExampleInstrumentedTest
Error:(24, 9) 错误: 找不到符号
符号: 方法 assertEquals(String,String)
位置: 类 ExampleInstrumentedTest
如果进行单元测试 是不是每个component里面还要添加测试的依赖包呀?
我的线上线下环境相关的配置,原本是写在app的build.gradle里的,
//本地开发环境[开启日志打印;测试环境ip;不混淆]
debug {
resValue "string", "app_name", "xx线下"
//是否打印日志
buildConfigField "boolean", "IS_DEBUG", "true"
//测试环境ip
buildConfigField "boolean", "API_ONLINE", "false"
//测试环境ip (https)
buildConfigField "boolean", "API_TEST", "false"
// 预上线
buildConfigField "boolean", "API_PREBOARD", "false"
//友盟key配置 线下false
buildConfigField "boolean", "UM_ONLINE", "false"
//是否混淆
minifyEnabled false
// 移除无用的resource文件
shrinkResources false
//Zipalign优化
zipAlignEnabled false
signingConfig signingConfigs.debug
// tinker关闭的情况下 将tinker需要的类放入主dex
multiDexKeepProguard file('multidexConfig.pro')
}
//测试环境[崩溃日志写入sd卡;测试环境ip(https);混淆代码]
dev_test {
resValue "string", "app_name", "xx测试"
//是否打印日志
buildConfigField "boolean", "IS_DEBUG", "false"
//测试环境ip
buildConfigField "boolean", "API_ONLINE", "false"
buildConfigField "boolean", "API_TEST", "true"
// 预上线
buildConfigField "boolean", "API_PREBOARD", "false"
//友盟key配置 线下false
buildConfigField "boolean", "UM_ONLINE", "false"
signingConfig signingConfigs.debug
;组件化拆分后就会出现不同组件都需要这个配置里的东西,我要在每个组件里都写一份?
感谢作者的开源资料及文章,收益匪浅。
有个问题几个问题想请教下:
谢谢!
在定制化的时候替换成maven仓库的地址这里
File file = project.file("../componentrelease/" + str.split(":")[1] + "-release.aar")
是直接将"../componentrelease/"改为maven地址吗?
多谢!
如果某个Component需要在使用前,初始化。而且初始化需要Context对象,有什么好的处理方式吗?
public class ReaderAppLike implements IApplicationLike {
Router router = Router.getInstance();
@Override
public void onCreate() {
router.addService(ReadBookService.class.getSimpleName(), new ReadBookServiceImpl());
}
@Override
public void onStop() {
router.removeService(ReadBookService.class.getSimpleName());
}
}
首先感谢作者开源这么棒的方案,辛苦!有点小疑问,求解答:
1.basiclib中是不是放我的所有基础类,例如基础工具类、项目中统一的BaseActivity等?
2.butterknife在application的时候生成的是R,library的时候是R2,框架能不能兼容这个?
如题:小白
求问:两个module都要用到相同的bean,是copy放在各自模块?还是把所有bean统一放在一个资源module里面好些?类似问题也例如公共接口等。
java.lang.RuntimeException: Unable to instantiate application com.mrzhang.share.runalone.application.ShareApplication: java.lang.ClassNotFoundException: Didn't find class "com.mrzhang.share.runalone.application.ShareApplication" on path: DexPathList[[zip file "/data/app/com.mrzhang.share-1/base.apk"],nativeLibraryDirectories=[/data/app/com.mrzhang.share-1/lib/arm, /vendor/lib, /system/lib]]
1.页面跳转这块建议使用ARouter
2.关于gradle打包所有*.aar文件这块 希望可以给出详细文档
有些组件的入口 activity 需要从其他组件传值过来的怎么办,要写模拟数据吗?
apply plugin: 'com.dd.comgradle' 请问这是个什么插件?
如题,比如业务分为home、a、b、c,但是home、a、b、c在主工程对应4个模块的宿主fragment,这种情况有什么好的建议吗
我在前段时间为我们的项目设计的模块化方案是:
现在已经应用到实际的项目开发中,看过这个库之后有很多收获,但是EoaSplit
与DDComponentForAndroid
的设计有一些区别,可以供参考:
每个业务模块xx
拥有自己的接口层xx-common
,接口层放置的是:
Event
dto
信息各个业务模块的接口层一直存在,可以被任意引用
不是通过指定类名的反射,而是每个业务模块在自己的AndroidManifest.xml
文件中将初始化类信息通过meta-data
节点注册,这样在编译的时候每个模块的meta-data
都会被合并,然后application
初始化的时候会读取android:value="module_init"
的节点,并根据android:name
信息反射读取,这样的好处是如果类被建立了关联,编译器会处理为引用,不会有警告未被调用且重构时不会出现错误,且依赖/解除依赖代码不会报错
<meta-data
android:name="com.ldy.account.receiver.AccountInitReceiver"
android:value="module_init"/>
不只是service
(facad
)的直接调用形式,还提供了Event
NotificationEvent
纯粹的通知事件GetDatasEvent
需要其它模块提供数据时,而数据的提供方又不确定,发出此事件由其它模块调用此事件的add
接口添加数据且事件提供了plug
,用于记录,拦截事件等
Activity的跳转使用接口直接调用实现
模块需要的配置信息,每个模块都需要各种各样的配置信息,这些配置信息可能是java
中的常量,resource
资源,.property
文件等,且配置信息可能多个模块共用,参考spring
的配置形式
account.baseUrl=https://11.12.109.125:8124/eoa-war/api/v2/
public static final String BASE_URL =
getStrValue(new PropertyValue("account.baseUrl"), new PropertyValue("baseUrl"));
模块间依赖是必然存在的,但是不允许平行依赖(业务模块依赖业务模块),业务模块只能依赖别的业务模块的接口层,使用service
(facad
)时需要从仓库中取出同时判空(空为业务模块不存在)
app
作为整个系统的容器,放置配置信息及依赖需要
dependencies {
classpath 'com.mrzhang.andcomponent:build-gradle:0.0.1'
// NOTE: Do not place your com.putao.login.runalone dependencies here; they belong
// in the individual module build.gradle files
}
maven { url uri('./repo') }
两个为何不能选择一个 ,少一个报错。
我想在basiclib module中的ActivityComponent接口中注册inject某一个具体的Activity的方法,可是根本访问不到该Activity,因为该Activity在其他的module中,根本访问不到。哪位大牛有没有好的办法可以解决这个问题
使用该组件化方式后 稍微改动项目 就会出现 java.io.IOException: Could not delete path 请问如何解决
当前UI跳转使用的URI规范还比较粗糙。
而且我觉得host部分还是对应组件比较合适,activity的“地址”对应主机上的path。当前demo中path “share”直接对应了host 。
页面跳转的地方也有一些hardcode
我会在anno分支尝试优化,包括设计也会补充相应文档
System.out.println("apply plugin is " + 'com.android.library');
project.afterEvaluate {
Task assembleReleaseTask = project.tasks.findByPath("assembleRelease")
if (assembleReleaseTask != null) {
assembleReleaseTask.doLast {
File infile = project.file("build/outputs/aar/$module-release.aar")
File outfile = project.file("../componentrelease")
File desFile = project.file("$module-release.aar");
project.copy {
from infile
into outfile
rename {
String fileName -> desFile.name
}
}
System.out.println("$module-release.aar copy success ");
}
}
}
apply plugin: 'com.dd.comgradle'请问这是什么插件工程里搜索不到
这个问题是这样,组件A需要用到组件B提供的数据,但是组件B获取数据是异步的,这种情况应该怎么处理呢?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.