JessYan: 意见收集 😘,请进 QQ 群: 455850365
JessYanCoding opened this issue · 89 comments
- 关于常见的 issues 在 这里
- 有什么问题可以直接进 咨询
如果您对 MVPArms 和 JessYan 有什么好的建议, 都可以在下面留言以及讨论
谢谢!整合了好多新兴技术,加法做了好多,什么时候做做减法呢?
JessYan 回复: Arms v2.5.0 版本开始, 已经在拆分 Arms 中非必须的库, 并且通过扩展库的方式,保证对旧版本的完美兼容,现在已经拆分了 support-design、AndroidEventBus、Glide、AndroidAutoLayout 等库,这样的好处是使框架使用者可以自由的选择某种类型的三方库,还可以减轻 Arms 的体积,后面还将继续对 Arms 进行拆分,让 Arms 的扩展性更强,体积更轻,新增的功能或库,也将采用 接口 + 扩展库 的方式进行集成
@JessYanCoding 牛逼的不要不要的。看了那么多RxJava、MVP、Retrofit等等的文章和例子,如今终于可以整合了!感谢无私分享,正在学习,准备使用本框架重构旧项目。
@xiaobailong24 好的,可以加qq群,有问题一起交流
@JessYanCoding 好的,周末正好研究一下!
@JessYanCoding 建议 BaseApplication extends MultiDexApplication
@ReepicheepRed BaseApplication 通过 AppDelegate 来做一些框架需要的操作,就是为了让开发者不是必须要继承 BaseApplication, AppDelegate 可以让开发者很方便的自定义一些可以满足自己需求的 Application,并且也不会影响到框架的运行,你的想法是站在 App 开发的角度, 需要框架很方便的实现自己的需求, 我站在框架设计的角度,要满足每个开发者每个 App 的需求是不可能做到的,所以我要做的是提供扩展的方式,让开发者能根据自己的需求自己去扩展,而不是一味的满足每个人的需求,这个是恶性循环,你需要 MultiDexApplication ,其他人可能并不需要,人家为什么要为了方便你的需求,而去被迫继承一个自己并不需要的 Application ,这个对于别人来说是不划算的事
@ReepicheepRed 为了让开发者更方便的使用 MultiDex ,以及对一些框架的初始化,现提供 attachBaseContext 扩展方式
厉害,很好,终于找到组织了
群号是啥?加一下 一起交流
@JanusKun 老哥,第一楼就有群号
真的很棒!**很厉害,向作者学习,多谢开源
首先非常感谢大神的无私奉献!我是一个小白,还是有些地方不懂,如果大神有时间能出个视频讲解一下就好了!
有木有相对简单的mvp模式demo,这个看着有些蒙蔽,熟悉点的只有rxjava,retrofit..。。看引用了很多的框架,,要一个一个学习再学习你在这个哇
@zhou9527 不管是 MVP ,还是 RxJava ,以及 Retrofit 和 Dagger , Github
简单的 Demo 真的太多,一搜一大堆,你就自己找吧,就是因为 Github
上大部分的此类型 App 或 Demo ,写的是在太简单了,所以我才写的这个框架属于进阶版,这个框架自动屏蔽没入门的朋友,因为你没入门根本看不懂,更说明你可成长的空间非常大,这时候你应该感到焦虑而更努力的自己主动去学,这些技术已经不算最火的技术了,我 16年 初就把这个框架写出来了,大部分人都会,大部分人都会的东西,而你不会,那无论面试还是工作肯定会有些许劣势,但现在这个时候才去学也不晚,你也有好处,那就是现在这方面的资料真的太多了,坑被踩完了,学习起来非常快,所以别问我了,直接花时间去硬啃
AndroidAutoLayout 不维护了,之后会选择移除吗
@hxlailfh1314 现在框架不是强制使用 AndroidAutoLayout ,不声明 Androidmanifest 中的 meta,就不会使用, AndroidAutoLayout 虽然不维护了,但是并不代表他没有价值,依然有很多项目在使用它,带来了很多便利,作为使用两年的老用户,也并没遇到什么大的 Bug ,在某些使用场景使用起来非常愉快,所以暂时不会移除,以后看情况再做打算,如果你不喜欢用,可以不声明 meta
框架上少引用了“com.squareup.retrofit2:converter-scalars:2.3.0”
所以不能支持返回参数是 String 类型。 不知道你这边 是否考虑加上这个。
@hxlailfh1314 框架已经提供了 Retrofit 和 Okhttp 扩展参数的方式, 你自己引用, 自己使用就好了, 框架只需要让开发者能够按需扩展自己的需求, 而不需要自己去满足所有人的需求, 这就是框架作者和 App 开发者**上最大的差别
想问个问题哦,发现MVPArms更新迭代蛮快的,但是好像没有向下兼容,当依赖的新版本的时候,会造成很多兼容性问题。有的时候想更新版本,又怕更新出问题
@yeyueduxing 集成化框架和其他功能性框架不一样, 功能性框架只是调用某些 API, 所以他可以很好的屏蔽一些风险, 但是集成化框架要复杂的多, 涉及到的方面远不是简单的调用几个 API 这么简单, 发布新版本时我也是尽量做到不影响旧版本, 在一些做了更改会影响到旧版本更新的地方, 我也在 更新日志 给出了详细的批注以及减小升级成本的方式, 我公司一个十几个模块几百个页面的组件化项目是直接远程依赖 Arms 的, 我每次也都是第一时间升级最新版本, 所以我心里是清楚升级最新版本所花费的成本的, 基本上我这个几百个页面的大项目升级的时间都是在半个小时以内, 大多都是几分钟就搞定, 所以更新你大可不必太过担心, 我这个项目十几个模块几百个页面, 如果更新成本太大我这个项目也是受影响最严重的, 我不可能自己坑自己的, 后面的更新也都会很稳定的
嗯,好的,谢谢啊
@JessYanCoding 你好,关于UserActivity等所有的activity和fragment初始化有个建议:dagger2其实有新的方式来规避,(可以让基类实现baseactivity集成HasActivityInjector),这样一劳永逸!setupActivityComponent这个方法都可以不用再多次初始化,甚至都没必要了。后续所有集成基类的activity或者fragment,都已经有对应HasActivityInjector,HasSupportfragmentInjector的方法了。然hou维护一个androidinjection(是为了activity和fragment oncreate的时候吧它们对应的inject进来!)望采纳。
@kinzirva 谢谢你的建议, 关于 Dagger2 的新特性我也很久没关注了, 一直在忙别的东西, 第二个原因也是因为怕框架使用新的 特性 会影响之前的用户, 我后面会仔细研究下 Dagger2 以及 Dagger.Android 等新功能, 后续会推出
@JessYanCoding 有个小建议哈,其实咱后面,也可以来一版kotlin的项目。我个人现在对app团队要求就是新的业务场景使用kotlin来实现。毕竟是个趋势了。(搞个实验室项目,主要收集和拓展新的框架或者语言特性,像微信 Tinker和360 Repugin那样。研发人员参与进来有贡献就ok)
@kinzirva 你这个建议也是可以的, 但是这个框架, 目前来说基本上是我一个人来维护和迭代升级, 你看我每个月的提交记录也知道我从来就没休息过, 一直在完成自己对这个项目规划的一些目标, 所以在完成现有的一些规划之前, 实在抽不出时间搞其他实验版, 随着项目用户的增长, 我的压力也越来越大, 毕竟没有一个完美的框架可以应对所有用户的需求, 只有不断的用时间去做优化以及对一些东西做取舍框架才能更完美, 但这个推进的速度也许会很慢, 毕竟一个人的力量比不了那些专业团队
在FragmentDelegate类中,有直接插入这个initData方法用于展示数据和网络请求
@OverRide
public void onActivityCreate(Bundle savedInstanceState) {
iFragment.initData(savedInstanceState);
}
但是,如果Fragment想使用懒加载,在setUserVisibleHint中进行判断的话,就只能重新写个网络请求和数据加载的方法了。所以这个方法是不是可以优化下呢
你不实现 initData(), 在 setUserVisibleHint() 中调用自己写的方法进行网络请求就可以了, 预设的方法只是为了规范, 并不强制你在当前的需求中一定会用到
也知道这个,就是Activity中使用initData,Fragment使用其他的,强迫症感觉不对啊(。・`ω´・)。也没啥事就是了,谢谢了啊
@xiaobailong24 嗯,你这样写也考虑过,但就是想直接引用MVPArms,在不修改底层的情况下扩展
Arms只是大多数的情况,实际情况中,自己扩展Base还是没问题的
@xiaobailong24 是的,我也有自己进行扩展,但我的扩展是继承BaseFragment和BaseActivity进行扩展。毕竟直接修改了底层,后面的Arms的升级引用也比较麻烦
@yeyueduxing Base 里面我只会保证精简, 并且只会有基础场景必须的方法, 不会在去过多的考虑某些开发者在某些特有场景的需求, 这不符合我框架的目标, 我会鼓励使用扩展的方式去实现自己的需求, 而不是我帮你们实现, 框架并不一定是功能有多完善, 重要的是扩展性
什么时候吧Dagger2 去掉
@zhaoxiuyu 使用 MVPArt 框架, 不需要开发者必须会使用 Dagger2, MVPArms 什么时候去掉 Dagger2? 大概是有更好的依赖注入框架可以取代 Dagger2 的时候
每次用PermissionUtil申请权限都要传RxErrorHandler,有没有简单的方法?
dragger2的单例模式找起来东西来真费劲,很容易就看丢了
IView中的几个公共方法可以提到Base中去,就不用每个view都实现这些方法了
建议把IView中的几个方法给注释掉,有需要的自己写个base就好了
@zzjian 我每次更新必须对之前版本的使用者负责,如果我注释了这个几个方法,那将导致上千个商业项目报错,小项目还好,大项目几百个页面那他们的工作量就将剧增,所以现在不可能对任何外部接口做较大的改变,你不喜欢这几个方法不实现就好了,对你们并没有什么致命影响,但我如果改了却会给之前的项目造成致命的影响,这一个改动带来价值并不值得让之前的项目付出这么大的代价
@JessYanCoding 你说的也是,没考虑导这点。 不过是否可以提供一个empty IVew, 让现有的IView继承这个空的。这样不需要这几个方法的就可以直接继承empty Iview了
@zzjian IView 是提供给外部使用的接口, 外部很多类都会直接引用或持有 IView,不管你怎么改都会对外面多多少有影响,我前面也说了改动付出的代价并不值得我这样去做,况且我觉得 IView 中大部分方法在 MVP 使用中都会用到,你不想用就不实现,或者自行修改,一个框架或者一个解决方案不可能满足所有人的需求,我只可能尽量的满足大多数人而去做平衡
好的,谢谢回复 @JessYanCoding
能够实用的框架不是大而全的,而是小而精,理念挺好,我感觉就是东西太多了,像eventbus,log这些,成熟的项目都已经有了,再说,这些东西本来就是个性化的,没必要加在框架里
@wanglg 这个框架最初的构想就是大而全,一次引用就拥有项目所必须的主要功能,为新项目的快速构建而生,是一个集成化框架而不是某个特定功能的库,这就是这个产品 (框架) 的定位 (小而精的库我也写过, RetrofitUrlManager 和 ProgressManager 都是小而精并且可热插拔的库,所以我当然明白你的意思,但是 Arms 的定位本就和他们不一样,也注定不能用不同产品的衡量标准去判断另一个产品的好坏),所以也决定了他不可避免的会引入一些三方库,有些库也许你不喜欢,但事实上你们公司大神搭建的框架,你也不一定会全部喜欢,不过后面的迭代肯定会让这些库可配置化
在迭代的过程中,喜欢偷懒的人让我加东西,喜欢个性化的人让我减东西,我也在努力的让框架可配置的功能不断增长,灵活度不断加强,但我做开源这么久也明白一个道理,每个人的需求都不一样,没有一个框架或者解决方案能满足所有人,所以我现在暂时不会盲目减东西也不会盲目加东西,在不做大改变基础上继续增加框架的灵活性,上千商业项目的接入,使我做的每一项决定有益于某一部分人的同时也可能会有害于一部分人
ps: 如果你只想用小而精或更纯粹的 MVP 库欢迎去选择 mosby,nucleus 等库, Arms 不可能小而精,因为它的出现本来就不只是为了 MVP 这一特定功能
@zzjian 我会在后面的版本中准备使用 java 8 的默认接口实现你说的这个需求, 这样不会影响之前项目的同时又可以实现你的需求,敬请期待!
是否会考虑,为更好地支持UT增加一些模板,工具,最佳实践,感谢!
@wanghe UETool? 暂时没精力和时间做 Arms 核心功能以外的东西, 现在有 3 个模板和 近 10 个库, 需要我维护😂
AppComponent中是否可以加个sharedpreferences的管理类呢
@franticn DataHelper
网络请求绑定activity生命周期的时候compose(RxUtils.bindToLifecycle(mRootView))是否能够指定特定的周期,目前是绑定当前的生命周期,导致RESUME时绑定,pause时解绑,无法指定在destroy时解绑。
@siegeout 自己看 RxLifecycleUtils 这个类
为什么mvp arms框架 中的Contract 组合 view 和 model
model 没有必要约束在contract中 感觉是多余的.
IRepositoryManager 是不是可以加入对Room的支持呢?,因为Model是对数据层的抽象,目前框架可以用retrofit+rxcache解决网络访问和缓存的问题,但是没有数据库的支持我这里实现就只能为每个model添加数据库的支持,大多数的业务都是需要同时对数据库和网络做访问,我看IRepositoryManager里面的注释是准备添加数据的请求,不知道作者是准备接入Room这个新的库还是直接上Sqlite的底层api呢?
@luili16 arms 是不会去添加任何指定的数据库的,每个数据库都有一定的用户份额,而且每个数据库的使用方式差异较大,封装任何数据库进 arms 都不能满足大部分人,所以后面可能增加一个抽象层提供扩展方式,实现交给外部使用者,arms 如果要满足更多的人,做一个平台性框架,就不能引入太多三方库,多做抽象,灵活度,扩展性才会更强,才能吸引更多的人使用
RepositoryManager这个类里面有个清除所有缓存的方法,
public void clearAllCache() {
mRxCache.get().evictAll();
}
这样使用并没有清除缓存,这里evictAll()返回的是一个Observable,还需要订阅一下:
public void clearAllCache() {
mRxCache.get().evictAll().subscribe();
}
@tangedegushi 感谢您的指正,这里确实没注意到这个细节,已修复 fc21873
发现项目好大呀,虽然好多东西都了解过,但是不熟练,看起来还是好费劲啊,不知道多久能消化完,膜拜大佬!
@qyliuyawei 加油
楼主您好。希望能考虑放开自定义application的接口约束。我在远程依赖的前提下,尝试把dagger-android接入到框架中遇到了自定义application必须要实现arms框架内提供的App接口,接口里面的方法又必须返回arms框架内的AppComponent的问题。如果不改造这个关键的AppComponent ,dagger-android的优势很难体现出来。
@kandra777 用你说的这种方式 AppComponent 是改造不了,你可以自己倒入 arms 的源码,试试以你的方法是否可以让 AppComponent 独立到外部,让用户可以修改,又可以让框架能正常运行,试试你就知道了,没这么简单
@JessYanCoding 改造好了。我之前对框架和dagger的理解还是不够 想的太复杂了。最后整理了一下思路,尝试框架内的di一套不去动他,还是交给框架内的AppDelegate去管理。然后我们通过自定义的Application在OnCreate方法里面注入我们项目(demo)需要的一套di(AppComponent+allActivityModules+AllFragmentModules)去做依赖注入就行了。在自己的appComponent里面不用写框架内AppComponent的方法 并且可以扩展自己的项目需要的一些临时单例等,感觉可以完美让arms框架用上dagger.android了
@kandra777 我懂你的意思,你是自己写一个自定义 Application 并持有 Component,这样你就可以扩展这个 Component 的字段,也可以加入 dagger.android,这个方式我在其他问题中也提到过,这个方式是不需要修改框架源码的,因为所有更改都是在 App module 中,这个是不更改 Arms 架构又可以扩展的最好方式,但是很多人不太理解 dagger 想要我来提供扩展方式
是不是可以考虑来一个 mvvmArms 框架了
@wfxphoebus https://github.com/xiaobailong24/MVVMArms
可以参考下
网络请求绑定activity生命周期的时候compose(RxUtils.bindToLifecycle(mRootView))是否能够指定特定的周期,目前是绑定当前的生命周期,导致RESUME时绑定,pause时解绑,无法指定在destroy时解绑。
我也遇到这个问题
@JessYanCoding改造好了。我之前对框架和dagger的理解还是不够想的太复杂了。最后整理了一下思路,尝试框架内的di一套不去动他,还是交给框架内的AppDelegate去管理。然后我们通过自定义的Application在OnCreate方法里面注入我们项目(demo)需要的一套di(AppComponent+allActivityModules+AllFragmentModules)去做依赖注入就行了。在自己的appComponent里面不用写框架内AppComponent的方法并且可以扩展自己的项目需要的一些临时单例等,感觉可以完美让arms框架用上dagger.android了
@JessYanCoding 改造好了。我之前对框架和dagger的理解还是不够 想的太复杂了。最后整理了一下思路,尝试框架内的di一套不去动他,还是交给框架内的AppDelegate去管理。然后我们通过自定义的Application在OnCreate方法里面注入我们项目(demo)需要的一套di(AppComponent+allActivityModules+AllFragmentModules)去做依赖注入就行了。在自己的appComponent里面不用写框架内AppComponent的方法 并且可以扩展自己的项目需要的一些临时单例等,感觉可以完美让arms框架用上dagger.android了
这样子重复注入依赖会有问题吗
@ncworm 先实践,再问
有个问题,现在我需要建一个全局的单例对象,找不到合适的地方,只想到自己新建个application来实现。
@xilost 自定义 Application 持有全局单例是可以的,但是需要多一步创建操作,GlobalConfiguration 和 AppLifecyclesImpl 是现成的,里面大部分方法都能拿到 Context,可以在里面创建静态方法
@JessYanCoding ,Glide有with(Fragment)的特性,希望ImageLoader中可以增加loadImage(Fragment fragment, T config)方法来保留这个特性。
@zhuxiaole ImageLoader 是上层,他下层可能是 Glide,或者其他图片加载框架,如果一个上层耦合某一个下层特有的特性,从设计上来说就有很多弊端,而且 Glide 以及其他图片加载框架有很多非常有用的功能,如果一有使用者需要新的功能我就被动的增加方法的话,对我来说是低效的,而且永远满足不了所有人的需求,这就是我为什么要把 ImageConfig 设计成建造者模式,并且推荐让你们自己去实现,因为们你们完全可以自己去创建实现类往里面不断的扩展参数,而 Fragment 不过是里面的参数,我根本就不需要知道你们在图片请求时需要什么参数,需要什么逻辑,但你们照样能满足自己的所有需要,因为这些你们完全可以自定义,这就是我这样设计的本质原因,https://github.com/JessYanCoding/MVPArms/wiki#3.4
android4.4手机不支持吗,报java.lang.RuntimeException: Unable to instantiate application com.jess.arms.base.BaseApplication: java.lang.IllegalArgumentException: Unable to find ConfigModule implementation
Caused by: java.lang.IllegalArgumentException: Unable to find ConfigModule implementation
at com.jess.arms.integration.ManifestParser.parseModule(ManifestParser.java:68)
at com.jess.arms.integration.ManifestParser.parse(ManifestParser.java:52)
at com.jess.arms.base.delegate.AppDelegate.(AppDelegate.java:76)
at com.jess.arms.base.BaseApplication.attachBaseContext(BaseApplication.java:56)
J神,为啥在GlobalConfiguration里设置了ProgressManager.getInstance().with(okhttpBuilder);,监听下载状态的时候没有效果呢?
@xilost https://github.com/JessYanCoding/ProgressManager 兄弟跑下官方 Demo,看下 Demo 里的代码是怎么操作的
J神,有个小疑惑,按照项目里config.gradle的配置拉取第三方库都没问题,但是只要改下某一个第三方包的版本号就不行了,比如photoview升级2.3.0,就开始报”Could not resolve“。
现在框架里的AppGlideModule是写死的,里面的配置无法自定义。而且我看了Glide的官方文档,“程序库一定 不要 包含 AppGlideModule 实现。”它建议在程序库里使用LibraryGlideModule,尽管LibraryGlideModule里不允许配置应用特定的设置项,比如缓存实现和缓存大小。
比如我现在我遇到一个问题,希望Glide使用单独配置的OkHttpClient,但是现在框架里在AppGlideModule中写死的使用和调用普通接口同一个OkHttpClient,根本无法更改。对于一个特定的应用,只能存在一个 AppGlideModule 实现(超过一个会在编译时报错)。
我觉得可以把AppGlideModule开放出来,让用户自己去实现,这样自由度更高。
-
想更改 OkHttpClient 哪怕不使用 AppGlideModule,使用 LibraryGlideModule 就可以更改,因为用来修改 OkHttpClient 的 registerComponents() 方法本身就是 LibraryGlideModule 的方法,AppGlideModule 只不过是继承了 LibraryGlideModule。
-
Glide 的确只允许在项目中只能存在一个 AppGlideModule,所以它在文档中建议三方库只能使用 LibraryGlideModule,但是为什么一定跟随它的思维呢?我在 Arms 中虽然占用了这唯一的 AppGlideModule,但是我可以将 AppGlideModule 的权利分发出去啊,只要外部使用者实现了某个接口,Arms 就赋予这个接口实现类与 AppGlideModule 同样的,可以配置 Glide 的权利,这不就可以了吗。
让 ImageLoaderStrategy 实现 GlideAppliesOptions 接口即可。
@JessYanCoding 我经过多次尝试后,发现通过在应用程序中单独实现LibraryGlideModule来修改 OkHttpClient的方法,并不会起作用,类名一直是灰的,Glide不会去使用它。
只有再添加一个AppGlideModule 实现,前面的LibraryGlideModule才会被调用,但是这个时候就存在了两个AppGlideModule,会起冲突。
@Leu-Z 如果不行的话,如果你执意不想使用同一个 Okhttp,建议先代码拉下来改,这里的代码是很久之前的,当时是测试通过了的,也不知道后来 Glide 升级后,是否改了一些东西,后面有空了再验证下,如果确实不行,我在按上面的方式把 registerComponents() 继续分发给其他接口,实现起来也比较简单
如果只是因为想实现 Okhttp 对不同请求进行不同的 Header 和 Token 等的处理,完全没必要用两个 Okhttp,使用拦截器就可以完成,这个在其他 issues 中我给了解决方案。
请教一个问题,BaseFragment中有setData方法,这里为什么不用Fragment自己的方法setArguments方法来实现呢?
@kkroid setArguments 是在 Fragment 创建时,给 Fragment 传递数据的,Fragment 需要自己去 getArguments 获取数据,而 setData 是在 Fragment 创建后,传递数据并通知的目的,setArguments 并没有通知的目的,无法通过调用 setArguments 让 Fragment 响应某项操作,两个方法不是一个东西
@kkroid setArguments 是在 Fragment 创建时,给 Fragment 传递数据的,Fragment 需要自己去 getArguments 获取数据,而 setData 是在 Fragment 创建后,传递数据并通知的目的,setArguments 并没有通知的目的,无法通过调用 setArguments 让 Fragment 响应某项操作,两个方法不是一个东西
对,setArguments方法的确无法让fragment响应某个操作,只是感觉这两个方法有重叠的功能,所以提问了,感谢回答。
@kkroid 不冲突,一个是用来传参的,一个用来通信的,setData 可以传参,也是为了通信,因为通信的时候进行数据的传递是必备的需求
大神。 看demo中 UserAtivity UserPresenter 中 几乎没有new来的对象。 都是UserModule中注入。 这些比较简单的,需要增加代码 再一个module 去提供实例吗。 是不是意味着 每一个页面都要有一个独立的module? 现在有种疑惑 有没有必要去Inject
@jyy195822328 Demo 只是为了展示会把很多东西都放上去,由于有些对象在 Activity presenter 都会用到,所有我直接就在 Module 中去提供,在开发中也是一样的,某个对象需要在多个地方被使用,就可以用 Module 去提供,如果只有一处使用那就没必要,灵活使用就可以了。
集成了之后app启动速度变得很慢 你们有这样的问题吗