├── .gitignore ├── .travis.yml ├── KeyDebug.keystore ├── KeyRelease.jks ├── LICENSE ├── README.md ├── build.gradle ├── core-arch-annotations ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── huyingbao │ └── core │ └── annotations │ ├── AppIndex.java │ ├── AppObserver.java │ └── AppOwner.java ├── core-arch-processor ├── .gitignore ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── huyingbao │ │ └── core │ │ └── processor │ │ ├── ArchProcessor.java │ │ ├── ProcessorUtil.java │ │ └── generator │ │ ├── AppIndexerGenerator.java │ │ └── AppOwnerGenerator.java │ └── resources │ └── META-INF │ └── services │ └── javax.annotation.processing.Processor ├── core-arch ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── huyingbao │ └── core │ └── arch │ ├── FluxApp.kt │ ├── FluxCallbacks.kt │ ├── action │ ├── FluxActionCreator.kt │ └── FluxActionManager.kt │ ├── dispatcher │ ├── FluxDispatcher.kt │ └── FluxSubscriber.kt │ ├── model │ ├── Action.kt │ ├── Change.kt │ ├── Error.kt │ └── Loading.kt │ ├── store │ ├── FluxAppStore.kt │ └── FluxStore.kt │ └── view │ └── FluxView.kt ├── core-base ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── huyingbao │ │ └── core │ │ └── base │ │ ├── BaseDialog.kt │ │ ├── BaseFragActivity.kt │ │ ├── BaseFragment.kt │ │ ├── BaseNavActivity.kt │ │ └── BaseView.kt │ └── res │ └── layout │ ├── base_activity_frag.xml │ ├── base_activity_nav.xml │ └── base_appbar_top.xml ├── core-cookie ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── huyingbao │ └── core │ └── cookie │ ├── PersistentCookieStore.java │ └── SerializableOkHttpCookies.java ├── core-eventbus-annotations ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── org │ └── greenrobot │ └── eventbus │ ├── Subscribe.java │ └── ThreadMode.java ├── core-eventbus-processor ├── .gitignore ├── build.gradle └── src │ └── main │ ├── java │ └── org │ │ └── greenrobot │ │ └── eventbus │ │ └── annotationprocessor │ │ └── EventBusAnnotationProcessor.java │ └── resources │ └── META-INF │ └── services │ └── javax.annotation.processing.Processor ├── core-eventbus ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── greenrobot │ └── eventbus │ ├── AsyncPoster.java │ ├── BackgroundPoster.java │ ├── BusEvent.java │ ├── EventBus.java │ ├── EventBusBuilder.java │ ├── EventBusException.java │ ├── EventBusLogger.java │ ├── HandlerPoster.java │ ├── MainThreadSupport.java │ ├── NoSubscriberEvent.java │ ├── PendingPost.java │ ├── PendingPostQueue.java │ ├── Poster.java │ ├── SubscriberExceptionEvent.java │ ├── SubscriberMethod.java │ ├── SubscriberMethodFinder.java │ ├── Subscription.java │ ├── android │ └── AndroidLogger.java │ ├── meta │ ├── AbstractSubscriberInfo.java │ ├── SimpleSubscriberInfo.java │ ├── SubscriberInfo.java │ ├── SubscriberInfoIndex.java │ └── SubscriberMethodInfo.java │ └── util │ ├── AsyncExecutor.java │ ├── ExceptionToResourceMapping.java │ ├── HasExecutionScope.java │ └── ThrowableFailureEvent.java ├── core-progress ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── huyingbao │ └── core │ └── progress │ ├── DownloadApi.kt │ ├── Progress.kt │ ├── ProgressInterceptor.kt │ └── ProgressResponseBody.kt ├── core-test ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ ├── android │ ├── text │ │ └── TextUtils.java │ └── util │ │ └── Base64.java │ └── com │ └── huyingbao │ └── core │ └── test │ └── subscriber │ ├── BaseSubscriberRule.kt │ └── BaseSubscriberTest.kt ├── core-utils ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── huyingbao │ └── core │ └── utils │ ├── AndroidUtils.kt │ ├── AutoClearedValue.kt │ ├── ClassUtils.kt │ ├── Executors.kt │ ├── RecyclerItemClickListener.kt │ ├── TimeUtils.kt │ ├── ViewBindingUtils.kt │ └── ViewUtils.kt ├── depends.gradle ├── depends_compose.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── image ├── Component和Inject的关系.png ├── Context子类区别.jpg ├── 下载.png ├── 依赖注入-Activity与Fragment.jpg ├── 依赖注入-Store.jpg ├── 依赖注入-全局.jpg ├── 架构图.jpg ├── 框架图.jpg └── 生命周期与订阅管理.jpg ├── module-app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── app │ ├── AndroidManifest.xml │ └── java │ └── com │ └── huyingbao │ └── module │ └── app │ └── SimpleApplication.kt ├── module-common ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── app │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── huyingbao │ │ └── module │ │ └── common │ │ └── CommonApplication.kt │ ├── library │ └── AndroidManifest.xml │ └── main │ ├── java │ └── com │ │ └── huyingbao │ │ └── module │ │ └── common │ │ ├── app │ │ ├── CommonAppConstants.kt │ │ ├── CommonAppModule.kt │ │ ├── CommonAppStore.kt │ │ └── CommonStartUp.kt │ │ ├── behavior │ │ ├── BottomNavigationBehavior.kt │ │ └── ScaleDownShowBehavior.kt │ │ ├── ui │ │ ├── info │ │ │ └── CommonInfoDialog.kt │ │ ├── loading │ │ │ └── CommonLoadingDialog.kt │ │ ├── start │ │ │ ├── StartActivity.kt │ │ │ └── StartFragment.kt │ │ ├── update │ │ │ ├── action │ │ │ │ ├── CommonUpdate.kt │ │ │ │ └── CommonUpdateActionCreator.kt │ │ │ ├── model │ │ │ │ └── AppBean.kt │ │ │ ├── module │ │ │ │ └── CommonUpdateDialogModule.kt │ │ │ └── view │ │ │ │ └── CommonUpdateDialog.kt │ │ └── web │ │ │ ├── WebActivity.kt │ │ │ └── WebFragment.kt │ │ ├── utils │ │ ├── CommonUtils.kt │ │ ├── GsonUtils.kt │ │ ├── PageInfoInterceptor.kt │ │ └── ViewUtils.kt │ │ └── widget │ │ └── CommonInfoCardView.kt │ └── res │ ├── color │ └── common_text_tab.xml │ ├── drawable-xxhdpi │ └── bg_app.webp │ ├── drawable │ ├── bg_launch.xml │ ├── ic_arrow_upward.xml │ ├── ic_flux.xml │ ├── ic_more.xml │ ├── ic_star.xml │ ├── ripple_bg.xml │ ├── shape_dialog_bg.xml │ ├── shape_edit_border.xml │ └── shape_side_nav_bar.xml │ ├── layout │ ├── common_cardview_info.xml │ ├── common_dialog_info.xml │ ├── common_dialog_loading.xml │ ├── common_dialog_update.xml │ ├── common_fragment_list.xml │ ├── common_fragment_start.xml │ └── common_fragment_web.xml │ ├── menu │ └── common_web.xml │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── raw │ └── start.json │ ├── values-night │ └── common_colors.xml │ └── values │ ├── common_attrs.xml │ ├── common_colors.xml │ ├── common_dimens.xml │ ├── common_strings.xml │ └── common_styles.xml ├── module-history ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── app │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── huyingbao │ │ └── module │ │ └── history │ │ └── WanApplication.kt │ ├── library │ └── AndroidManifest.xml │ ├── main │ ├── java │ │ └── com │ │ │ └── huyingbao │ │ │ └── module │ │ │ └── wan │ │ │ ├── app │ │ │ ├── WanAppDatabase.kt │ │ │ ├── WanAppLifecycle.kt │ │ │ └── WanAppModule.kt │ │ │ ├── model │ │ │ ├── Article.kt │ │ │ ├── ArticleDao.kt │ │ │ ├── Banner.kt │ │ │ ├── Page.kt │ │ │ ├── Tag.kt │ │ │ ├── WanResponse.kt │ │ │ └── WebSite.kt │ │ │ └── ui │ │ │ ├── article │ │ │ ├── action │ │ │ │ ├── Article.kt │ │ │ │ └── ArticleActionCreator.kt │ │ │ ├── adapter │ │ │ │ ├── ArticleAdapter.kt │ │ │ │ └── BannerAdapter.kt │ │ │ ├── store │ │ │ │ └── ArticleStore.kt │ │ │ └── view │ │ │ │ ├── ArticleActivity.kt │ │ │ │ ├── ArticleListFragment.kt │ │ │ │ └── BannerFragment.kt │ │ │ └── friend │ │ │ ├── action │ │ │ ├── Friend.kt │ │ │ └── FriendActionCreator.kt │ │ │ ├── adapter │ │ │ └── WebSiteAdapter.kt │ │ │ ├── store │ │ │ └── FriendStore.kt │ │ │ └── view │ │ │ └── FriendFragment.kt │ └── res │ │ ├── layout │ │ ├── banner_fragment_list.xml │ │ ├── wan_recycle_item_article.xml │ │ ├── wan_recycle_item_banner.xml │ │ └── wan_recycle_item_friend.xml │ │ ├── menu │ │ └── wan_fragment_article_list.xml │ │ └── values │ │ └── wan_strings.xml │ └── test │ ├── java │ └── com │ │ └── huyingbao │ │ └── module │ │ └── wan │ │ ├── module │ │ └── WanTestModule.kt │ │ └── ui │ │ └── article │ │ ├── action │ │ ├── ArticleActionCreatorTest.kt │ │ └── ArticleActionCreatorTest2.kt │ │ └── view │ │ ├── ArticleActivityTest.kt │ │ └── ArticleListFragmentTest.kt │ └── resources │ └── json │ ├── articleList.json │ ├── bannerList.json │ ├── login.json │ └── register.json ├── module-login ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── app │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── huyingbao │ │ └── module │ │ └── login │ │ └── LoginApplication.kt │ ├── library │ └── AndroidManifest.xml │ ├── main │ ├── java │ │ └── com │ │ │ └── huyingbao │ │ │ └── module │ │ │ └── login │ │ │ ├── app │ │ │ └── LoginAppModule.kt │ │ │ └── ui │ │ │ ├── LoginActivity.kt │ │ │ └── ui │ │ │ └── theme │ │ │ ├── Color.kt │ │ │ ├── Shape.kt │ │ │ ├── Theme.kt │ │ │ └── Type.kt │ └── res │ │ └── values │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ ├── java │ └── com │ │ └── huyingbao │ │ └── module │ │ └── login │ │ └── module │ │ └── WanTestModule.kt │ └── resources │ └── json │ ├── articleList.json │ ├── bannerList.json │ ├── login.json │ └── register.json ├── module-wan ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── app │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── huyingbao │ │ └── module │ │ └── wan │ │ └── WanApplication.kt │ ├── library │ └── AndroidManifest.xml │ ├── main │ ├── java │ │ └── com │ │ │ └── huyingbao │ │ │ └── module │ │ │ └── wan │ │ │ ├── app │ │ │ ├── WanAppDatabase.kt │ │ │ ├── WanAppLifecycle.kt │ │ │ └── WanAppModule.kt │ │ │ ├── model │ │ │ ├── Article.kt │ │ │ ├── ArticleDao.kt │ │ │ ├── Banner.kt │ │ │ ├── Page.kt │ │ │ ├── Tag.kt │ │ │ ├── WanResponse.kt │ │ │ └── WebSite.kt │ │ │ └── ui │ │ │ ├── article │ │ │ ├── action │ │ │ │ ├── Article.kt │ │ │ │ └── ArticleActionCreator.kt │ │ │ ├── adapter │ │ │ │ ├── ArticleAdapter.kt │ │ │ │ └── BannerAdapter.kt │ │ │ ├── store │ │ │ │ └── ArticleStore.kt │ │ │ └── view │ │ │ │ ├── ArticleActivity.kt │ │ │ │ ├── ArticleListFragment.kt │ │ │ │ └── BannerFragment.kt │ │ │ └── friend │ │ │ ├── action │ │ │ ├── Friend.kt │ │ │ └── FriendActionCreator.kt │ │ │ ├── adapter │ │ │ └── WebSiteAdapter.kt │ │ │ ├── store │ │ │ └── FriendStore.kt │ │ │ └── view │ │ │ └── FriendFragment.kt │ └── res │ │ ├── layout │ │ ├── banner_fragment_list.xml │ │ ├── wan_recycle_item_article.xml │ │ ├── wan_recycle_item_banner.xml │ │ └── wan_recycle_item_friend.xml │ │ ├── menu │ │ └── wan_fragment_article_list.xml │ │ └── values │ │ └── wan_strings.xml │ └── test │ ├── java │ └── com │ │ └── huyingbao │ │ └── module │ │ └── wan │ │ ├── module │ │ └── WanTestModule.kt │ │ └── ui │ │ └── article │ │ ├── action │ │ ├── ArticleActionCreatorTest.kt │ │ └── ArticleActionCreatorTest2.kt │ │ └── view │ │ ├── ArticleActivityTest.kt │ │ └── ArticleListFragmentTest.kt │ └── resources │ └── json │ ├── articleList.json │ ├── bannerList.json │ ├── login.json │ └── register.json ├── settings.gradle └── templates ├── activities └── FluxActivity │ ├── globals.xml.ftl │ ├── recipe.xml.ftl │ ├── root │ ├── AndroidManifest.xml.ftl │ ├── res │ │ └── layout │ │ │ └── fragment.xml.ftl │ └── src │ │ └── app_package │ │ ├── FluxAction.kt.ftl │ │ ├── FluxActionCreator.kt.ftl │ │ ├── FluxActivity.kt.ftl │ │ ├── FluxFragment.kt.ftl │ │ └── FluxStore.kt.ftl │ ├── template.xml │ └── template_flux_activity.png └── other └── FluxFragment ├── globals.xml.ftl ├── recipe.xml.ftl ├── root ├── res │ └── layout │ │ └── fragment.xml.ftl └── src │ └── app_package │ └── FluxFragment.kt.ftl ├── template.xml └── template_flux_fragment.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | /captures 5 | /build 6 | /release 7 | /local.properties 8 | core-arch/build 9 | core-arch-annotations/build 10 | core-arch-processor/build 11 | core-base/build 12 | core-res/build 13 | module-common/build 14 | module-wan/build 15 | module-gan/build 16 | module-github/build -------------------------------------------------------------------------------- /KeyDebug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/KeyDebug.keystore -------------------------------------------------------------------------------- /KeyRelease.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/KeyRelease.jks -------------------------------------------------------------------------------- /core-arch-annotations/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /core-arch-annotations/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | 3 | group = "com.github.coolfire2015" 4 | 5 | sourceCompatibility = JavaVersion.VERSION_1_8 6 | targetCompatibility = JavaVersion.VERSION_1_8 -------------------------------------------------------------------------------- /core-arch-annotations/src/main/java/com/huyingbao/core/annotations/AppIndex.java: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 标注编译自动生成的{@link AppObserver}的索引类。 10 | *

11 | * Created by liujunfeng on 2019/1/1. 12 | */ 13 | @Target(ElementType.TYPE) 14 | @Retention(RetentionPolicy.CLASS) 15 | public @interface AppIndex { 16 | /** 17 | * @return 所有被{@link AppLifecycleObserver}标注的androidx.lifecycle.LifecycleObserver的实现类的标准名组成的字符串数组 18 | */ 19 | String[] observers() default {}; 20 | } 21 | -------------------------------------------------------------------------------- /core-arch-annotations/src/main/java/com/huyingbao/core/annotations/AppObserver.java: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 标注androidx.lifecycle.LifecycleObserver的实现类,Application生命周期观察者 10 | *

11 | * 与{@link AppOwner}配合使用。 12 | *

13 | * (主模块)一个{@link AppOwner} 对 (子模块)多个{@link AppObserver} 14 | *

15 | * Created by liujunfeng on 2019/1/1. 16 | */ 17 | @Target(ElementType.TYPE) 18 | @Retention(RetentionPolicy.CLASS) 19 | public @interface AppObserver { 20 | } -------------------------------------------------------------------------------- /core-arch-annotations/src/main/java/com/huyingbao/core/annotations/AppOwner.java: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 标注Application(FluxApp子类)本身,生命周期持有者,被观察者。 10 | *

11 | * 与{@link AppObserver}配合使用。 12 | *

13 | * (主模块)一个{@link AppOwner} 对 (子模块)多个{@link AppObserver} 14 | *

15 | * Created by liujunfeng on 2019/1/1. 16 | */ 17 | @Target(ElementType.TYPE) 18 | @Retention(RetentionPolicy.CLASS) 19 | public @interface AppOwner { 20 | } -------------------------------------------------------------------------------- /core-arch-processor/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core-arch-processor/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | 3 | group = "com.github.coolfire2015" 4 | 5 | sourceCompatibility = JavaVersion.VERSION_1_8 6 | targetCompatibility = JavaVersion.VERSION_1_8 7 | 8 | dependencies { 9 | //注解 10 | implementation project(':core-arch-annotations') 11 | //注解生成文件工具类 12 | compileOnly "com.squareup:javapoet:${JAVAPOET_VERSION}" 13 | compileOnly "com.google.auto.service:auto-service:${AUTO_SERVICE_VERSION}" 14 | annotationProcessor "com.google.auto.service:auto-service:${AUTO_SERVICE_VERSION}" 15 | } -------------------------------------------------------------------------------- /core-arch-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor: -------------------------------------------------------------------------------- 1 | com.huyingbao.core.processor.ArchProcessor 2 | -------------------------------------------------------------------------------- /core-arch/.gitignore: -------------------------------------------------------------------------------- 1 | build -------------------------------------------------------------------------------- /core-arch/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | #lambda 28 | -dontwarn java.lang.invoke.* 29 | 30 | #Arouter 31 | -keep public class com.alibaba.android.arouter.routes.**{*;} 32 | -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} 33 | # 如果使用了 byType 的方式获取 Service,需添加下面规则,保护接口 34 | -keep interface * implements com.alibaba.android.arouter.facade.template.IProvider 35 | # 如果使用了 单类注入,即不定义接口实现 IProvider,需添加下面规则,保护实现 36 | -keep class * implements com.alibaba.android.arouter.facade.template.IProvider -------------------------------------------------------------------------------- /core-arch/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core-arch/src/main/java/com/huyingbao/core/arch/dispatcher/FluxSubscriber.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.arch.dispatcher 2 | 3 | /** 4 | * 事件总线订阅器 5 | * 6 | * Created by liujunfeng on 2019/1/1. 7 | */ 8 | interface FluxSubscriber 9 | -------------------------------------------------------------------------------- /core-arch/src/main/java/com/huyingbao/core/arch/model/Action.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.arch.model 2 | 3 | import android.text.TextUtils 4 | import androidx.collection.ArrayMap 5 | import org.greenrobot.eventbus.BusEvent 6 | 7 | /** 8 | * 操作结果通知,封装操作返回数据。 9 | * 10 | * 由[com.huyingbao.core.arch.action.FluxActionCreator]发送到[com.huyingbao.core.arch.store.FluxStore], 11 | * 12 | * Created by liujunfeng on 2019/1/1. 13 | */ 14 | class Action private constructor( 15 | tag: String, 16 | val data: ArrayMap 17 | ) : BusEvent(tag) { 18 | /** 19 | * 获取ArrayMap中Key对应的Value 20 | */ 21 | @Suppress("UNCHECKED_CAST") 22 | operator fun get(tag: String): T? { 23 | return data[tag] as T? 24 | } 25 | 26 | /** 27 | * 获取ArrayMap中存储的操作结果 28 | */ 29 | fun getResponse(): T? { 30 | return get("response") 31 | } 32 | 33 | /** 34 | * 操作结果存储到ArrayMap中 35 | */ 36 | fun setResponse(response: T) { 37 | data["response"] = response 38 | } 39 | 40 | override fun equals(other: Any?): Boolean { 41 | return this === other || (other != null 42 | && other is Action 43 | && TextUtils.equals(tag, other.tag) 44 | && data == other.data) 45 | } 46 | 47 | override fun hashCode(): Int { 48 | var result = tag.hashCode() 49 | result = 31 * result + data.hashCode() 50 | return result 51 | } 52 | 53 | /** 54 | * 构造器 55 | */ 56 | class Builder(private val tag: String) { 57 | private val data: ArrayMap = ArrayMap() 58 | 59 | /** 60 | * 添加数据 61 | */ 62 | fun put(key: String, value: Any?): Builder { 63 | if (value != null) { 64 | data[key] = value 65 | } 66 | return this 67 | } 68 | 69 | /** 70 | * 构造对象 71 | */ 72 | fun build(): Action { 73 | return Action(tag, data) 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /core-arch/src/main/java/com/huyingbao/core/arch/model/Change.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.arch.model 2 | 3 | import org.greenrobot.eventbus.BusEvent 4 | 5 | /** 6 | * UI响应通知,发送到[com.huyingbao.core.arch.view.FluxView] 7 | * 8 | * Created by liujunfeng on 2019/1/1. 9 | */ 10 | class Change private constructor( 11 | tag: String 12 | ) : BusEvent(tag) { 13 | companion object { 14 | /** 15 | * 生成实例对象 16 | */ 17 | fun newInstance(tag: String): Change { 18 | return Change(tag) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core-arch/src/main/java/com/huyingbao/core/arch/model/Error.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.arch.model 2 | 3 | import org.greenrobot.eventbus.BusEvent 4 | 5 | /** 6 | * 操作异常通知,发送到[com.huyingbao.core.arch.view.FluxView] 7 | * 8 | * Created by liujunfeng on 2019/1/1. 9 | */ 10 | class Error private constructor( 11 | tag: String, 12 | val throwable: Throwable 13 | ) : BusEvent(tag) { 14 | companion object { 15 | fun newInstance(busEvent: BusEvent, throwable: Throwable): Error { 16 | return Error(busEvent.tag, throwable) 17 | .apply { isGlobalCatch = busEvent.isGlobalCatch } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core-arch/src/main/java/com/huyingbao/core/arch/model/Loading.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.arch.model 2 | 3 | import org.greenrobot.eventbus.BusEvent 4 | 5 | /** 6 | * 操作进度通知,发送到[com.huyingbao.core.arch.view.FluxView] 7 | * 8 | * @param isLoading true:操作进行中,用于显示操作进度提示,false:操作结束,用于隐藏操作进度提示 9 | * 10 | * Created by liujunfeng on 2019/1/1. 11 | */ 12 | class Loading private constructor( 13 | tag: String, 14 | val isLoading: Boolean 15 | ) : BusEvent(tag) { 16 | companion object { 17 | fun newInstance(busEvent: BusEvent, isLoading: Boolean): Loading { 18 | return Loading(busEvent.tag, isLoading) 19 | .apply { isGlobalCatch = busEvent.isGlobalCatch } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /core-arch/src/main/java/com/huyingbao/core/arch/store/FluxAppStore.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.arch.store 2 | 3 | import android.app.Application 4 | import android.util.Log 5 | import androidx.annotation.CallSuper 6 | import androidx.annotation.NonNull 7 | import androidx.lifecycle.AndroidViewModel 8 | import androidx.lifecycle.DefaultLifecycleObserver 9 | import androidx.lifecycle.LifecycleOwner 10 | import com.huyingbao.core.arch.FluxCallbacks 11 | import com.huyingbao.core.arch.dispatcher.FluxDispatcher 12 | import com.huyingbao.core.arch.dispatcher.FluxSubscriber 13 | 14 | /** 15 | * 0.继承[AndroidViewModel],内部持有[Application] 16 | * 17 | * 1.存储和管理Application生命周期内的数据 18 | * 19 | * 2.接收[FluxDispatcher]发送的数据。 20 | */ 21 | abstract class FluxAppStore( 22 | @NonNull application: Application 23 | ) : AndroidViewModel(application), DefaultLifecycleObserver, FluxSubscriber { 24 | @CallSuper 25 | override fun onCreate(owner: LifecycleOwner) { 26 | super.onCreate(owner) 27 | Log.i(FluxCallbacks.TAG, "Subscribe Store : " + javaClass.simpleName) 28 | FluxDispatcher.subscribe(this) 29 | } 30 | 31 | @CallSuper 32 | override fun onStop(owner: LifecycleOwner) { 33 | super.onStop(owner) 34 | Log.i(FluxCallbacks.TAG, "Unsubscribe Store : " + javaClass.simpleName) 35 | FluxDispatcher.unsubscribe(this) 36 | } 37 | 38 | @CallSuper 39 | override fun onDestroy(owner: LifecycleOwner) { 40 | super.onDestroy(owner) 41 | Log.i(FluxCallbacks.TAG, "Unsubscribe Store : " + javaClass.simpleName) 42 | FluxDispatcher.unsubscribe(this) 43 | } 44 | } -------------------------------------------------------------------------------- /core-arch/src/main/java/com/huyingbao/core/arch/store/FluxStore.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.arch.store 2 | 3 | import android.util.Log 4 | import androidx.annotation.CallSuper 5 | import androidx.lifecycle.ViewModel 6 | import com.huyingbao.core.arch.FluxCallbacks 7 | import com.huyingbao.core.arch.dispatcher.FluxDispatcher 8 | import com.huyingbao.core.arch.dispatcher.FluxSubscriber 9 | import com.huyingbao.core.arch.model.Change 10 | 11 | 12 | /** 13 | * Store层 14 | * 15 | * 继承[ViewModel],在屏幕旋转或配置更改引起的Activity/Fragment重建时存活下来,其持有数据可以继续使用。 16 | * 17 | * 继承[FluxSubscriber],接受总线事件。 18 | * 19 | * Created by liujunfeng on 2020/8/1. 20 | */ 21 | abstract class FluxStore : ViewModel(), FluxSubscriber { 22 | /** 23 | * 取消[FluxDispatcher]中订阅 24 | */ 25 | @CallSuper 26 | override fun onCleared() { 27 | super.onCleared() 28 | Log.i(FluxCallbacks.TAG, "Unsubscribe Store : " + javaClass.simpleName) 29 | FluxDispatcher.unsubscribe(this) 30 | } 31 | 32 | fun postChange(change: Change) { 33 | FluxDispatcher.postChange(change) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /core-arch/src/main/java/com/huyingbao/core/arch/view/FluxView.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.arch.view 2 | 3 | import com.huyingbao.core.arch.dispatcher.FluxSubscriber 4 | import com.huyingbao.core.arch.store.FluxStore 5 | 6 | /** 7 | * View层 8 | * 9 | * 持有跟随自身生命周期的[FluxStore]。 10 | * 11 | * 继承[FluxSubscriber],接受总线事件,根据自身生命周期,自动注册订阅或者取消订阅 12 | 13 | * View在destroy时,调用[FluxStore]的onCleared()方法清理数据并不再持有[FluxStore]对象。 14 | * 15 | * Created by liujunfeng on 2019/1/1. 16 | */ 17 | interface FluxView : FluxSubscriber { 18 | /** 19 | * 为实现类提供Store 20 | */ 21 | val store: FluxStore 22 | } 23 | -------------------------------------------------------------------------------- /core-base/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /core-base/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-kapt' 4 | 5 | group = "com.github.coolfire2015" 6 | 7 | android { 8 | compileSdkVersion COMPILE_SDK_VERSION as int 9 | 10 | //编译版本 11 | buildToolsVersion BUILD_TOOLS_VERSION 12 | //默认配置 13 | defaultConfig { 14 | //Sdk版本 15 | minSdkVersion MIN_SDK_VERSION as int 16 | targetSdkVersion TARGET_SDK_VERSION as int 17 | //版本信息 18 | versionCode rootProject.gitGitVersionCode() 19 | versionName rootProject.getGitVersionName() 20 | } 21 | //构建过程 22 | buildTypes { 23 | //自定义buildType.name 24 | release { 25 | //混淆开关 26 | minifyEnabled false 27 | //混淆文件 28 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 29 | } 30 | } 31 | //Java1.8支持 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | //Kotlin Java1.8支持 37 | kotlinOptions { 38 | jvmTarget = JavaVersion.VERSION_1_8 39 | } 40 | //构建功能 41 | buildFeatures { 42 | //不生成BuildConfig.java文件 43 | buildConfig = false 44 | //支持 ViewBinding 45 | viewBinding = true 46 | } 47 | } 48 | 49 | //将源代码打包进aar 50 | task sourcesJar(type: Jar) { 51 | classifier = 'sources' 52 | from android.sourceSets.main.javaDirectories 53 | } 54 | 55 | artifacts { 56 | archives sourcesJar 57 | } 58 | 59 | dependencies { 60 | //X-Navigation 61 | api "androidx.navigation:navigation-ui-ktx:${X_NAVIGATION}" 62 | api "androidx.navigation:navigation-fragment-ktx:${X_NAVIGATION}" 63 | //X-Material 64 | api "com.google.android.material:material:${X_MATERIAL}" 65 | } -------------------------------------------------------------------------------- /core-base/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /core-base/src/main/java/com/huyingbao/core/base/BaseFragActivity.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.base 2 | 3 | import android.view.MenuItem 4 | import androidx.appcompat.app.AppCompatActivity 5 | import androidx.fragment.app.Fragment 6 | import androidx.fragment.app.FragmentManager 7 | 8 | /** 9 | * 不使用Dagger.Android,不持有ViewModel,不自动管理订阅 10 | * 11 | * 使用[FragmentManager]管理Fragment 12 | * 13 | * Created by liujunfeng on 2019/1/1. 14 | */ 15 | abstract class BaseFragActivity : BaseView, 16 | AppCompatActivity 17 | () { 18 | /** 19 | * 使用默认Activity布局,可以覆盖该方法,使用自定义布局 20 | */ 21 | override fun getLayoutId(): Int { 22 | return R.layout.base_activity_frag 23 | } 24 | 25 | /** 26 | * 提供activity需要显示的fragment 27 | */ 28 | protected abstract fun createFragment(): Fragment? 29 | 30 | /** 31 | * [androidx.appcompat.widget.Toolbar]Menu点击事件,拦截返回按钮,如果Fragment回退栈不为空,先弹出Fragment 32 | */ 33 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 34 | when (item.itemId) { 35 | // 点击返回图标事件 36 | android.R.id.home -> { 37 | if (supportFragmentManager.backStackEntryCount > 0) { 38 | supportFragmentManager.popBackStack() 39 | return true 40 | } 41 | finish() 42 | return true 43 | } 44 | else -> return super.onOptionsItemSelected(item) 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /core-base/src/main/java/com/huyingbao/core/base/BaseFragment.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.base.common.fragment 2 | 3 | import android.content.Context 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import androidx.fragment.app.Fragment 9 | import com.huyingbao.core.base.BaseView 10 | 11 | /** 12 | * 不使用Dagger.Android,不持有ViewModel,不自动管理订阅 13 | * 14 | * Fragment可创建Menu 15 | * 16 | * Created by liujunfeng on 2019/1/1. 17 | */ 18 | abstract class BaseFragment : 19 | Fragment(), 20 | BaseView { 21 | var backAble: Boolean = false 22 | var title: CharSequence? = null 23 | 24 | /** 25 | * 告诉FragmentManager:其管理的fragment应接收onCreateOptionsMenu(...)方法的调用指令,fragment中创建Menu。 26 | */ 27 | override fun onAttach(context: Context) { 28 | super.onAttach(context) 29 | setHasOptionsMenu(true) 30 | } 31 | 32 | override fun onCreateView( 33 | inflater: LayoutInflater, 34 | container: ViewGroup?, 35 | savedInstanceState: Bundle? 36 | ): View { 37 | return inflater.inflate(getLayoutId(), container, false) 38 | } 39 | 40 | override fun onActivityCreated(savedInstanceState: Bundle?) { 41 | super.onActivityCreated(savedInstanceState) 42 | afterCreate(savedInstanceState) 43 | } 44 | 45 | /** 46 | * 隐藏状态转变, 47 | * 从隐藏转为非隐藏的时候调用,当前页面显示时,显示对应的标题 48 | */ 49 | override fun onHiddenChanged(hidden: Boolean) { 50 | super.onHiddenChanged(hidden) 51 | if (!hidden) { 52 | // setTitle(title, backAble) 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /core-base/src/main/java/com/huyingbao/core/base/BaseView.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.base 2 | 3 | import android.os.Bundle 4 | import androidx.annotation.IdRes 5 | 6 | import androidx.annotation.LayoutRes 7 | 8 | /** 9 | * View抽象接口 10 | * 11 | * Created by liujunfeng on 2019/1/1. 12 | */ 13 | interface BaseView { 14 | /** 15 | * 获取Toolbar ID,使用默认布局中的ID,可以覆盖该方法,使用自定义ID 16 | * 17 | * Activity中调用该方法 18 | */ 19 | @IdRes 20 | fun getToolbarId(): Int = R.id.base_tlb_top 21 | 22 | /** 23 | * 获取可以容纳Fragment的View ID,使用默认布局中的ID,可以覆盖该方法,使用自定义ID 24 | * 25 | * Activity中调用该方法 26 | */ 27 | @IdRes 28 | fun getFragmentContainerId(): Int = R.id.base_fragment_container 29 | 30 | /** 31 | * 获取对应布局文件ID 32 | */ 33 | @LayoutRes 34 | fun getLayoutId(): Int 35 | 36 | /** 37 | * View层创建之后调用方法 38 | */ 39 | fun afterCreate(savedInstanceState: Bundle?) 40 | } -------------------------------------------------------------------------------- /core-base/src/main/res/layout/base_activity_frag.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /core-base/src/main/res/layout/base_activity_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 18 | -------------------------------------------------------------------------------- /core-base/src/main/res/layout/base_appbar_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 18 | -------------------------------------------------------------------------------- /core-cookie/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /core-cookie/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | 4 | group = "com.github.coolfire2015" 5 | 6 | android { 7 | //编译版本 8 | compileSdkVersion COMPILE_SDK_VERSION as int 9 | //默认配置 10 | defaultConfig { 11 | //Sdk版本 12 | minSdkVersion MIN_SDK_VERSION as int 13 | targetSdkVersion TARGET_SDK_VERSION as int 14 | //版本信息 15 | versionCode rootProject.gitGitVersionCode() 16 | versionName rootProject.getGitVersionName() 17 | } 18 | //构建过程 19 | buildTypes { 20 | //自定义buildType.name 21 | release { 22 | //混淆开关 23 | minifyEnabled false 24 | //混淆文件 25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | //Java1.8支持 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | //Kotlin Java1.8支持 34 | kotlinOptions { 35 | jvmTarget = JavaVersion.VERSION_1_8 36 | } 37 | //构建功能 38 | buildFeatures { 39 | //不生成BuildConfig.java文件 40 | buildConfig = false 41 | } 42 | } 43 | 44 | //将源代码打包进aar 45 | task sourcesJar(type: Jar) { 46 | classifier = 'sources' 47 | from android.sourceSets.main.javaDirectories 48 | } 49 | 50 | artifacts { 51 | archives sourcesJar 52 | } 53 | 54 | dependencies { 55 | //OkHttp 56 | implementation "com.squareup.okhttp3:okhttp:${OKHTTP}" 57 | //兼容包,使用ArrayMap 58 | implementation "androidx.collection:collection-ktx:${X_COLLECTION}" 59 | //依赖注入注解 60 | implementation "javax.inject:javax.inject:${JAVAX_INJECT}" 61 | } -------------------------------------------------------------------------------- /core-cookie/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /core-cookie/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core-eventbus-annotations/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /core-eventbus-annotations/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | 3 | 4 | group = "com.github.coolfire2015" 5 | 6 | sourceCompatibility = JavaVersion.VERSION_1_8 7 | targetCompatibility = JavaVersion.VERSION_1_8 -------------------------------------------------------------------------------- /core-eventbus-annotations/src/main/java/org/greenrobot/eventbus/Subscribe.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.greenrobot.eventbus; 18 | 19 | 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | @Documented 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target({ElementType.METHOD}) 29 | public @interface Subscribe { 30 | ThreadMode threadMode() default ThreadMode.POSTING; 31 | 32 | /** 33 | * If true, delivers the most recent sticky event (posted with 34 | * {@link org.greenrobot.eventbus.EventBus#postSticky(Object)}) to this subscriber (if event available). 35 | */ 36 | boolean sticky() default false; 37 | 38 | /** 39 | * Subscriber priority to influence the order of event delivery. 40 | * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before 41 | * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of 42 | * delivery among subscribers with different {@link ThreadMode}s! 43 | */ 44 | int priority() default 0; 45 | 46 | /** 47 | * 事件的tag数组,类似于BroadcastReceiver中的Action,事件的标识符 48 | * 49 | * @return 50 | */ 51 | String[] tags() default {"defaultTag"}; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /core-eventbus-processor/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core-eventbus-processor/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | 3 | 4 | group = "com.github.coolfire2015" 5 | 6 | sourceCompatibility = JavaVersion.VERSION_1_8 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | 9 | dependencies { 10 | //EventBus注解 11 | implementation project(':core-eventbus-annotations') 12 | //Java工具 13 | implementation "de.greenrobot:java-common:${JAVA_COMMON}" 14 | } -------------------------------------------------------------------------------- /core-eventbus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor: -------------------------------------------------------------------------------- 1 | org.greenrobot.eventbus.annotationprocessor.EventBusAnnotationProcessor 2 | -------------------------------------------------------------------------------- /core-eventbus/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /core-eventbus/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | 4 | group = "com.github.coolfire2015" 5 | 6 | android { 7 | //编译版本 8 | compileSdkVersion COMPILE_SDK_VERSION as int 9 | //默认配置 10 | defaultConfig { 11 | //Sdk版本 12 | minSdkVersion MIN_SDK_VERSION as int 13 | targetSdkVersion TARGET_SDK_VERSION as int 14 | //版本信息 15 | versionCode rootProject.gitGitVersionCode() 16 | versionName rootProject.getGitVersionName() 17 | } 18 | //构建过程 19 | buildTypes { 20 | //自定义buildType.name 21 | release { 22 | //混淆开关 23 | minifyEnabled false 24 | //混淆文件 25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | //Java1.8支持 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | //构建功能 34 | buildFeatures { 35 | //不生成BuildConfig.java文件 36 | buildConfig = false 37 | } 38 | } 39 | 40 | //将源代码打包进aar 41 | task sourcesJar(type: Jar) { 42 | classifier = 'sources' 43 | from android.sourceSets.main.javaDirectories 44 | } 45 | 46 | artifacts { 47 | archives sourcesJar 48 | } 49 | 50 | dependencies { 51 | //EventBus注解 52 | api project(':core-eventbus-annotations') 53 | //版本兼容包,使用兼容包中的Pair,方便单元测试 54 | api "androidx.core:core:${X_CORE}" 55 | } -------------------------------------------------------------------------------- /core-eventbus/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/AsyncPoster.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | 19 | /** 20 | * Posts events in background. 21 | * 22 | * @author Markus 23 | */ 24 | class AsyncPoster implements Runnable, Poster { 25 | 26 | private final PendingPostQueue queue; 27 | private final EventBus eventBus; 28 | 29 | AsyncPoster(EventBus eventBus) { 30 | this.eventBus = eventBus; 31 | queue = new PendingPostQueue(); 32 | } 33 | 34 | @Override 35 | public void enqueue(Subscription subscription, Object event, String tag) { 36 | PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event, tag); 37 | queue.enqueue(pendingPost); 38 | eventBus.getExecutorService().execute(this); 39 | } 40 | 41 | @Override 42 | public void run() { 43 | PendingPost pendingPost = queue.poll(); 44 | if (pendingPost == null) { 45 | throw new IllegalStateException("No pending post available"); 46 | } 47 | eventBus.invokeSubscriber(pendingPost); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/BusEvent.java: -------------------------------------------------------------------------------- 1 | package org.greenrobot.eventbus; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | /** 6 | * 用于EventBus传递事件,提供事件标志tag 7 | *

8 | * Created by liujunfeng on 2019/1/1. 9 | */ 10 | public abstract class BusEvent { 11 | /** 12 | * 事件标志tag 13 | */ 14 | protected final String tag; 15 | /** 16 | * 是否被全局捕获处理,默认true:全局捕获处理。 17 | *

18 | * true:{@link EventBus#post(Object)}和{@link EventBus#postSticky(Object)},使用统一tag:"defaultTag"。 19 | *

20 | * false:{@link EventBus#post(Object)}和{@link EventBus#postSticky(Object)},使用自身{@link BusEvent#tag}。 21 | */ 22 | private boolean isGlobalCatch = true; 23 | 24 | protected BusEvent(@NonNull String tag) { 25 | this.tag = tag; 26 | } 27 | 28 | 29 | /** 30 | * @return 31 | */ 32 | public String getTag() { 33 | return tag; 34 | } 35 | 36 | public boolean isGlobalCatch() { 37 | return isGlobalCatch; 38 | } 39 | 40 | /** 41 | * @param globalCatch 42 | * @ 43 | */ 44 | public void setGlobalCatch(boolean globalCatch) { 45 | isGlobalCatch = globalCatch; 46 | } 47 | } -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/EventBusException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * An {@link RuntimeException} thrown in cases something went wrong inside EventBus. 20 | * 21 | * @author Markus 22 | */ 23 | public class EventBusException extends RuntimeException { 24 | 25 | private static final long serialVersionUID = -2912559384646531479L; 26 | 27 | public EventBusException(String detailMessage) { 28 | super(detailMessage); 29 | } 30 | 31 | public EventBusException(Throwable throwable) { 32 | super(throwable); 33 | } 34 | 35 | public EventBusException(String detailMessage, Throwable throwable) { 36 | super(detailMessage, throwable); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/EventBusLogger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | import java.util.logging.Level; 19 | 20 | public interface EventBusLogger { 21 | 22 | void log(Level level, String msg); 23 | 24 | void log(Level level, String msg, Throwable th); 25 | 26 | class JavaLogger implements EventBusLogger { 27 | protected final java.util.logging.Logger logger; 28 | 29 | public JavaLogger(String tag) { 30 | logger = java.util.logging.Logger.getLogger(tag); 31 | } 32 | 33 | @Override 34 | public void log(Level level, String msg) { 35 | // TODO Replace logged method with caller method 36 | logger.log(level, msg); 37 | } 38 | 39 | @Override 40 | public void log(Level level, String msg, Throwable th) { 41 | // TODO Replace logged method with caller method 42 | logger.log(level, msg, th); 43 | } 44 | 45 | } 46 | 47 | class SystemOutLogger implements EventBusLogger { 48 | 49 | @Override 50 | public void log(Level level, String msg) { 51 | System.out.println("[" + level + "] " + msg); 52 | } 53 | 54 | @Override 55 | public void log(Level level, String msg, Throwable th) { 56 | System.out.println("[" + level + "] " + msg); 57 | th.printStackTrace(System.out); 58 | } 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/MainThreadSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | import android.os.Looper; 19 | 20 | /** 21 | * Interface to the "main" thread, which can be whatever you like. Typically on Android, Android's main thread is used. 22 | */ 23 | public interface MainThreadSupport { 24 | 25 | boolean isMainThread(); 26 | 27 | Poster createPoster(EventBus eventBus); 28 | 29 | class AndroidHandlerMainThreadSupport implements MainThreadSupport { 30 | 31 | private final Looper looper; 32 | 33 | public AndroidHandlerMainThreadSupport(Looper looper) { 34 | this.looper = looper; 35 | } 36 | 37 | @Override 38 | public boolean isMainThread() { 39 | return looper == Looper.myLooper(); 40 | } 41 | 42 | @Override 43 | public Poster createPoster(EventBus eventBus) { 44 | return new HandlerPoster(eventBus, looper, 10); 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/NoSubscriberEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * This Event is posted by EventBus when no subscriber is found for a posted event. 20 | * 21 | * @author Markus 22 | */ 23 | public final class NoSubscriberEvent { 24 | /** 25 | * The {@link EventBus} instance to with the original event was posted to. 26 | */ 27 | public final EventBus eventBus; 28 | 29 | /** 30 | * The original event that could not be delivered to any subscriber. 31 | */ 32 | public final Object originalEvent; 33 | 34 | public NoSubscriberEvent(EventBus eventBus, Object originalEvent) { 35 | this.eventBus = eventBus; 36 | this.originalEvent = originalEvent; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/PendingPostQueue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.greenrobot.eventbus; 18 | 19 | final class PendingPostQueue { 20 | private PendingPost head; 21 | private PendingPost tail; 22 | 23 | synchronized void enqueue(PendingPost pendingPost) { 24 | if (pendingPost == null) { 25 | throw new NullPointerException("null cannot be enqueued"); 26 | } 27 | if (tail != null) { 28 | tail.next = pendingPost; 29 | tail = pendingPost; 30 | } else if (head == null) { 31 | head = tail = pendingPost; 32 | } else { 33 | throw new IllegalStateException("Head present, but no tail"); 34 | } 35 | notifyAll(); 36 | } 37 | 38 | synchronized PendingPost poll() { 39 | PendingPost pendingPost = head; 40 | if (head != null) { 41 | head = head.next; 42 | if (head == null) { 43 | tail = null; 44 | } 45 | } 46 | return pendingPost; 47 | } 48 | 49 | synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException { 50 | if (head == null) { 51 | wait(maxMillisToWait); 52 | } 53 | return poll(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/Poster.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * Posts events. 20 | * 21 | * @author William Ferguson 22 | */ 23 | interface Poster { 24 | 25 | /** 26 | * Enqueue an event to be posted for a particular subscription. 27 | * 28 | * @param subscription Subscription which will receive the event. 29 | * @param event Event that will be posted to subscribers. 30 | * @param tag tag with event 31 | */ 32 | void enqueue(Subscription subscription, Object event, String tag); 33 | } 34 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/SubscriberExceptionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * This Event is posted by EventBus when an exception occurs inside a subscriber's event handling method. 20 | * 21 | * @author Markus 22 | */ 23 | public final class SubscriberExceptionEvent { 24 | /** 25 | * The {@link EventBus} instance to with the original event was posted to. 26 | */ 27 | public final EventBus eventBus; 28 | 29 | /** 30 | * The Throwable thrown by a subscriber. 31 | */ 32 | public final Throwable throwable; 33 | 34 | /** 35 | * The original event that could not be delivered to any subscriber. 36 | */ 37 | public final Object causingEvent; 38 | 39 | /** 40 | * The subscriber that threw the Throwable. 41 | */ 42 | public final Object causingSubscriber; 43 | 44 | public SubscriberExceptionEvent(EventBus eventBus, Throwable throwable, Object causingEvent, 45 | Object causingSubscriber) { 46 | this.eventBus = eventBus; 47 | this.throwable = throwable; 48 | this.causingEvent = causingEvent; 49 | this.causingSubscriber = causingSubscriber; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/Subscription.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * 订阅者封装 20 | * 包含订阅者类与订阅者中的订阅方法 21 | */ 22 | final class Subscription { 23 | final Object subscriber; 24 | final SubscriberMethod subscriberMethod; 25 | /** 26 | * Becomes false as soon as {@link EventBus#unregister(Object)} is called, which is checked by queued event delivery 27 | * {@link EventBus#invokeSubscriber(PendingPost)} to prevent race conditions. 28 | */ 29 | volatile boolean active; 30 | 31 | Subscription(Object subscriber, SubscriberMethod subscriberMethod) { 32 | this.subscriber = subscriber; 33 | this.subscriberMethod = subscriberMethod; 34 | active = true; 35 | } 36 | 37 | @Override 38 | public boolean equals(Object other) { 39 | if (other instanceof Subscription) { 40 | Subscription otherSubscription = (Subscription) other; 41 | return subscriber == otherSubscription.subscriber 42 | && subscriberMethod.equals(otherSubscription.subscriberMethod); 43 | } else { 44 | return false; 45 | } 46 | } 47 | 48 | @Override 49 | public int hashCode() { 50 | return subscriber.hashCode() + subscriberMethod.methodString.hashCode(); 51 | } 52 | } -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/meta/SimpleSubscriberInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.meta; 17 | 18 | import org.greenrobot.eventbus.SubscriberMethod; 19 | 20 | /** 21 | * Uses {@link SubscriberMethodInfo} objects to create {@link org.greenrobot.eventbus.SubscriberMethod} objects on demand. 22 | */ 23 | public class SimpleSubscriberInfo extends AbstractSubscriberInfo { 24 | 25 | private final SubscriberMethodInfo[] methodInfos; 26 | 27 | public SimpleSubscriberInfo(Class subscriberClass, boolean shouldCheckSuperclass, SubscriberMethodInfo[] methodInfos) { 28 | super(subscriberClass, null, shouldCheckSuperclass); 29 | this.methodInfos = methodInfos; 30 | } 31 | 32 | @Override 33 | public synchronized SubscriberMethod[] getSubscriberMethods() { 34 | int length = methodInfos.length; 35 | SubscriberMethod[] methods = new SubscriberMethod[length]; 36 | for (int i = 0; i < length; i++) { 37 | SubscriberMethodInfo info = methodInfos[i]; 38 | methods[i] = createSubscriberMethod(info.methodName, info.tags, info.eventType, info.threadMode, 39 | info.priority, info.sticky); 40 | } 41 | return methods; 42 | } 43 | } -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/meta/SubscriberInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.meta; 17 | 18 | import org.greenrobot.eventbus.SubscriberMethod; 19 | 20 | /** 21 | * Base class for generated index classes created by annotation processing. 22 | */ 23 | public interface SubscriberInfo { 24 | Class getSubscriberClass(); 25 | 26 | SubscriberMethod[] getSubscriberMethods(); 27 | 28 | SubscriberInfo getSuperSubscriberInfo(); 29 | 30 | boolean shouldCheckSuperclass(); 31 | } 32 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/meta/SubscriberInfoIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.meta; 17 | 18 | /** 19 | * 3.0版本中,EventBus提供了一个EventBusAnnotationProcessor注解处理器 20 | * 来在编译期通过读取@Subscribe()注解并解析, 21 | * 处理其中所包含的信息,然后生成java类来保存所有订阅者关于订阅的信息, 22 | * 这样就比在运行时使用反射来获得这些订阅者的信息速度要快. 23 | * Interface for generated indexes. 24 | */ 25 | public interface SubscriberInfoIndex { 26 | SubscriberInfo getSubscriberInfo(Class subscriberClass); 27 | } -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/meta/SubscriberMethodInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.meta; 17 | 18 | import org.greenrobot.eventbus.ThreadMode; 19 | 20 | public class SubscriberMethodInfo { 21 | final String methodName; 22 | final String[] tags; 23 | final ThreadMode threadMode; 24 | final Class eventType; 25 | final int priority; 26 | final boolean sticky; 27 | 28 | public SubscriberMethodInfo(String methodName, String[] tags, Class eventType, ThreadMode threadMode, 29 | int priority, boolean sticky) { 30 | this.methodName = methodName; 31 | this.tags = tags; 32 | this.threadMode = threadMode; 33 | this.eventType = eventType; 34 | this.priority = priority; 35 | this.sticky = sticky; 36 | } 37 | 38 | public SubscriberMethodInfo(String methodName, String[] tags, Class eventType) { 39 | this(methodName, tags, eventType, ThreadMode.POSTING, 0, false); 40 | } 41 | 42 | public SubscriberMethodInfo(String methodName, String[] tags, Class eventType, ThreadMode threadMode) { 43 | this(methodName, tags, eventType, threadMode, 0, false); 44 | } 45 | 46 | public SubscriberMethodInfo(String methodName, Class eventType) { 47 | this(methodName, new String[]{"defaultTag"}, eventType, ThreadMode.POSTING, 0, false); 48 | } 49 | } -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/util/HasExecutionScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.greenrobot.eventbus.util; 18 | 19 | public interface HasExecutionScope { 20 | Object getExecutionScope(); 21 | 22 | void setExecutionScope(Object executionScope); 23 | } 24 | -------------------------------------------------------------------------------- /core-eventbus/src/main/java/org/greenrobot/eventbus/util/ThrowableFailureEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.util; 17 | 18 | /** 19 | * A generic failure event, which can be used by apps to propagate thrown exceptions. Also used in conjunction with 20 | * {@link ErrorDialogManager}. 21 | */ 22 | public class ThrowableFailureEvent implements HasExecutionScope { 23 | protected final Throwable throwable; 24 | protected final boolean suppressErrorUi; 25 | private Object executionContext; 26 | 27 | public ThrowableFailureEvent(Throwable throwable) { 28 | this.throwable = throwable; 29 | suppressErrorUi = false; 30 | } 31 | 32 | /** 33 | * @param suppressErrorUi true indicates to the receiver that no error UI (e.g. dialog) should now displayed. 34 | */ 35 | public ThrowableFailureEvent(Throwable throwable, boolean suppressErrorUi) { 36 | this.throwable = throwable; 37 | this.suppressErrorUi = suppressErrorUi; 38 | } 39 | 40 | public Throwable getThrowable() { 41 | return throwable; 42 | } 43 | 44 | public boolean isSuppressErrorUi() { 45 | return suppressErrorUi; 46 | } 47 | 48 | @Override 49 | public Object getExecutionScope() { 50 | return executionContext; 51 | } 52 | 53 | @Override 54 | public void setExecutionScope(Object executionContext) { 55 | this.executionContext = executionContext; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /core-progress/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /core-progress/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | 4 | group = "com.github.coolfire2015" 5 | 6 | android { 7 | //编译版本 8 | compileSdkVersion COMPILE_SDK_VERSION as int 9 | //默认配置 10 | defaultConfig { 11 | //Sdk版本 12 | minSdkVersion MIN_SDK_VERSION as int 13 | targetSdkVersion TARGET_SDK_VERSION as int 14 | //版本信息 15 | versionCode rootProject.gitGitVersionCode() 16 | versionName rootProject.getGitVersionName() 17 | } 18 | //构建过程 19 | buildTypes { 20 | //自定义buildType.name 21 | release { 22 | //混淆开关 23 | minifyEnabled false 24 | //混淆文件 25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | //Java1.8支持 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | //Kotlin Java1.8支持 34 | kotlinOptions { 35 | jvmTarget = JavaVersion.VERSION_1_8 36 | } 37 | //构建功能 38 | buildFeatures { 39 | //不生成BuildConfig.java文件 40 | buildConfig = false 41 | } 42 | } 43 | 44 | //将源代码打包进aar 45 | task sourcesJar(type: Jar) { 46 | classifier = 'sources' 47 | from android.sourceSets.main.javaDirectories 48 | } 49 | 50 | artifacts { 51 | archives sourcesJar 52 | } 53 | 54 | dependencies { 55 | //内核,使用RxError和EventBus 56 | implementation project(':core-arch') 57 | //OkHttp 58 | implementation "com.squareup.okhttp3:okhttp:${OKHTTP}" 59 | //Retrofit 60 | implementation "com.squareup.retrofit2:retrofit:${RETROFIT}" 61 | //依赖注入注解 62 | implementation "javax.inject:javax.inject:${JAVAX_INJECT}" 63 | } -------------------------------------------------------------------------------- /core-progress/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | #lambda 28 | -dontwarn java.lang.invoke.* 29 | 30 | # okhttp 31 | -keepattributes Signature 32 | -keepattributes *Annotation* 33 | -keep class okhttp3.** { *; } 34 | -keep interface okhttp3.** { *; } 35 | -dontwarn okhttp3.** 36 | 37 | # okio 38 | -keep class sun.misc.Unsafe { *; } 39 | -dontwarn java.nio.file.* 40 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 41 | -dontwarn okio.** 42 | 43 | #防止混淆BaseRecyclerViewAdapterHelper 44 | -keep class com.chad.library.adapter.** { *; } 45 | 46 | #防止混淆retrofit2 47 | -dontwarn retrofit2.** 48 | -keep class retrofit2.** { *; } 49 | -keepattributes Signature 50 | -keepattributes Exceptions 51 | 52 | #Arouter 53 | -keep public class com.alibaba.android.arouter.routes.**{*;} 54 | -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} 55 | # 如果使用了 byType 的方式获取 Service,需添加下面规则,保护接口 56 | -keep interface * implements com.alibaba.android.arouter.facade.template.IProvider 57 | # 如果使用了 单类注入,即不定义接口实现 IProvider,需添加下面规则,保护实现 58 | -keep class * implements com.alibaba.android.arouter.facade.template.IProvider -------------------------------------------------------------------------------- /core-progress/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /core-progress/src/main/java/com/huyingbao/core/progress/DownloadApi.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.progress 2 | 3 | import okhttp3.ResponseBody 4 | import retrofit2.http.GET 5 | import retrofit2.http.Header 6 | import retrofit2.http.Streaming 7 | import retrofit2.http.Url 8 | 9 | /** 10 | * Created by liujunfeng on 2019/4/10. 11 | */ 12 | interface DownloadApi { 13 | /** 14 | * 下载文件 15 | * 16 | * @param tag 下载事件的tag,放在Header中,拦截器拦截获取 17 | * @param url 18 | * @return 19 | */ 20 | @GET 21 | @Streaming 22 | suspend fun download( 23 | @Header(Progress.TAG) tag: String?, 24 | @Url url: String? 25 | ): ResponseBody? 26 | } -------------------------------------------------------------------------------- /core-progress/src/main/java/com/huyingbao/core/progress/Progress.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.progress 2 | 3 | import org.greenrobot.eventbus.BusEvent 4 | 5 | /** 6 | * Created by liujunfeng on 2019/1/1. 7 | */ 8 | class RxProgress private constructor( 9 | tag: String 10 | ) : BusEvent(tag) { 11 | /** 12 | * 当前已上传或下载的总长度 13 | */ 14 | var currentLength: Long = 0 15 | 16 | /** 17 | * 数据总长度 18 | */ 19 | var contentLength: Long = 0 20 | 21 | /** 22 | * 本次调用距离上一次被调用所间隔的时间(毫秒) 23 | */ 24 | var intervalTime: Long = 0 25 | 26 | /** 27 | * 本次调用距离上一次被调用的间隔时间内上传或下载的byte长度 28 | */ 29 | var eachLength: Long = 0 30 | 31 | /** 32 | * 获取百分比 33 | * 34 | * @return 35 | */ 36 | val percent: Int 37 | get() = if (currentLength <= 0 || contentLength <= 0) 0 else (100 * currentLength / contentLength).toInt() 38 | 39 | /** 40 | * 获取上传或下载网络速度,单位为byte/s 41 | * 42 | * @return 43 | */ 44 | val speed: Long 45 | get() = if (eachLength <= 0 || intervalTime <= 0) 0 else eachLength * 1000 / intervalTime 46 | 47 | companion object { 48 | const val TAG = "tag" 49 | fun newInstance(tag: String): Progress { 50 | return Progress(tag) 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /core-progress/src/main/java/com/huyingbao/core/progress/ProgressInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.progress 2 | 3 | import android.text.TextUtils 4 | import okhttp3.Interceptor 5 | import okhttp3.Response 6 | import java.io.IOException 7 | import javax.inject.Inject 8 | import javax.inject.Singleton 9 | 10 | /** 11 | * 转换ResponseBody为ProgressResponseBody 12 | * Created by liujunfeng on 2019/4/10. 13 | */ 14 | @Singleton 15 | class ProgressInterceptor @Inject constructor() : Interceptor { 16 | @Throws(IOException::class) 17 | override fun intercept(chain: Interceptor.Chain): Response { 18 | val response = chain.proceed(chain.request()) 19 | if (response.body == null) { 20 | return response 21 | } 22 | //获取Header传递过来的参数,并传递到ProgressResponseBody对象中 23 | var tag: String? = null 24 | if (!TextUtils.isEmpty(response.request.header(Progress.Companion.TAG))) { 25 | tag = response.request.header(Progress.Companion.TAG) 26 | } 27 | val body = ProgressResponseBody(response.body, tag) 28 | return response.newBuilder().body(body).build() 29 | } 30 | } -------------------------------------------------------------------------------- /core-test/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /core-test/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-kapt' 4 | 5 | 6 | group = "com.github.coolfire2015" 7 | 8 | android { 9 | //编译版本 10 | compileSdkVersion COMPILE_SDK_VERSION as int 11 | //默认配置 12 | defaultConfig { 13 | //Sdk版本 14 | minSdkVersion MIN_SDK_VERSION as int 15 | targetSdkVersion TARGET_SDK_VERSION as int 16 | //版本信息 17 | versionCode rootProject.gitGitVersionCode() 18 | versionName rootProject.getGitVersionName() 19 | } 20 | //构建过程 21 | buildTypes { 22 | //自定义buildType.name 23 | release { 24 | //混淆开关 25 | minifyEnabled false 26 | //混淆文件 27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | //Java1.8支持 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | //Kotlin Java1.8支持 36 | kotlinOptions { 37 | jvmTarget = JavaVersion.VERSION_1_8 38 | } 39 | //构建功能 40 | buildFeatures { 41 | //不生成BuildConfig.java文件 42 | buildConfig = false 43 | } 44 | } 45 | 46 | //将源代码打包进aar 47 | task sourcesJar(type: Jar) { 48 | classifier = 'sources' 49 | from android.sourceSets.main.javaDirectories 50 | } 51 | 52 | artifacts { 53 | archives sourcesJar 54 | } 55 | 56 | dependencies { 57 | //内核 58 | api project(':core-arch') 59 | //Junit 60 | api "junit:junit:${TEST_JUNIT}" 61 | //Mockito 62 | api "org.mockito:mockito-core:${TEST_MOCKITO}" 63 | //Android 64 | api "androidx.test:core:${TEST_X_CORE}" 65 | api "androidx.test:rules:${TEST_X_RULES}" 66 | api "com.google.dagger:hilt-android-testing:${HILT}" 67 | debugImplementation "androidx.fragment:fragment-testing:${X_FRAGMENT}" 68 | } 69 | -------------------------------------------------------------------------------- /core-test/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /core-test/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core-test/src/main/java/com/huyingbao/core/test/subscriber/BaseSubscriberTest.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.test.subscriber 2 | 3 | import com.huyingbao.core.arch.action.ActionManager 4 | import com.huyingbao.core.arch.dispatcher.Dispatcher 5 | import dagger.hilt.android.testing.HiltAndroidRule 6 | import org.junit.Rule 7 | import org.mockito.Spy 8 | import org.mockito.junit.MockitoJUnit 9 | 10 | /** 11 | * 所有Subscriber测试类的父类 12 | * 13 | * Created by liujunfeng on 2019/4/3. 14 | */ 15 | abstract class BaseSubscriberTest { 16 | /** 17 | * 初始化[org.mockito.Spy]和[org.mockito.Mock]标注的对象 18 | */ 19 | @get:Rule 20 | var mockitoRule = MockitoJUnit.rule() 21 | 22 | /** 23 | * [com.huyingbao.core.arch.store.RxStore]和[com.huyingbao.core.arch.view.RxSubscriberView] 24 | * 自动注册订阅和取消订阅 25 | */ 26 | @get:Rule 27 | var actionCreatorRule = BaseSubscriberRule() 28 | 29 | /** 30 | * 有无参构造函数 31 | */ 32 | @Spy 33 | lateinit var dispatcher: Dispatcher 34 | 35 | /** 36 | * 有无参构造函数 37 | */ 38 | @Spy 39 | lateinit var actionManager: ActionManager 40 | 41 | /** 42 | * 初始化[HiltAndroidRule] 43 | */ 44 | abstract var hiltRule: HiltAndroidRule 45 | 46 | /** 47 | * 获取所有需要管理订阅的 [com.huyingbao.core.arch.store.RxStore]和[com.huyingbao.core.arch.view.RxSubscriberView] 48 | * 实现类对象列表 49 | */ 50 | abstract fun getSubscriberList(): List 51 | } -------------------------------------------------------------------------------- /core-utils/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /core-utils/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | 4 | group = "com.github.coolfire2015" 5 | 6 | android { 7 | //编译版本 8 | compileSdkVersion COMPILE_SDK_VERSION as int 9 | buildToolsVersion BUILD_TOOLS_VERSION 10 | //默认配置 11 | defaultConfig { 12 | //Sdk版本 13 | minSdkVersion MIN_SDK_VERSION as int 14 | targetSdkVersion TARGET_SDK_VERSION as int 15 | //版本信息 16 | versionCode rootProject.gitGitVersionCode() 17 | versionName rootProject.getGitVersionName() 18 | } 19 | //构建过程 20 | buildTypes { 21 | //自定义buildType.name 22 | release { 23 | //混淆开关 24 | minifyEnabled false 25 | //混淆文件 26 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | //Java1.8支持 30 | compileOptions { 31 | sourceCompatibility JavaVersion.VERSION_1_8 32 | targetCompatibility JavaVersion.VERSION_1_8 33 | } 34 | //Kotlin Java1.8支持 35 | kotlinOptions { 36 | jvmTarget = JavaVersion.VERSION_1_8 37 | } 38 | //构建功能 39 | buildFeatures { 40 | //不生成BuildConfig.java文件 41 | buildConfig = false 42 | } 43 | } 44 | 45 | //将源代码打包进aar 46 | task sourcesJar(type: Jar) { 47 | classifier = 'sources' 48 | from android.sourceSets.main.javaDirectories 49 | } 50 | 51 | artifacts { 52 | archives sourcesJar 53 | } 54 | 55 | dependencies { 56 | //X_Navigation 57 | implementation "androidx.navigation:navigation-ui-ktx:${X_NAVIGATION}" 58 | implementation "androidx.navigation:navigation-fragment-ktx:${X_NAVIGATION}" 59 | } 60 | -------------------------------------------------------------------------------- /core-utils/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /core-utils/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core-utils/src/main/java/com/huyingbao/core/utils/AndroidUtils.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.utils 2 | 3 | import android.content.Context 4 | import android.text.TextUtils 5 | import java.io.BufferedReader 6 | import java.io.FileReader 7 | import java.io.IOException 8 | 9 | /** 10 | * Android系统相关工具类 11 | * 12 | * Created by liujunfeng on 2019/1/1. 13 | */ 14 | object AndroidUtils { 15 | /** 16 | * 获取进程号对应的进程名 17 | * 18 | * @param pid 进程号 19 | * @return 进程名 20 | */ 21 | fun getProcessName(pid: Int): String? { 22 | var reader: BufferedReader? = null 23 | try { 24 | reader = BufferedReader(FileReader("/proc/$pid/cmdline")) 25 | var processName = reader.readLine() 26 | if (!TextUtils.isEmpty(processName)) { 27 | processName = processName.trim { it <= ' ' } 28 | } 29 | return processName 30 | } catch (throwable: Throwable) { 31 | throwable.printStackTrace() 32 | } finally { 33 | try { 34 | reader?.close() 35 | } catch (exception: IOException) { 36 | exception.printStackTrace() 37 | } 38 | } 39 | return null 40 | } 41 | 42 | /** 43 | * 获取当前Application的Label 44 | */ 45 | fun getApplicationLabel(context: Context?): String? = 46 | context?.getString( 47 | context.packageManager.getApplicationInfo( 48 | context.packageName, 49 | 0 50 | ).labelRes 51 | ) 52 | } 53 | -------------------------------------------------------------------------------- /core-utils/src/main/java/com/huyingbao/core/utils/AutoClearedValue.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.utils 2 | 3 | import androidx.lifecycle.Lifecycle 4 | import androidx.lifecycle.LifecycleObserver 5 | import androidx.lifecycle.LifecycleOwner 6 | import androidx.lifecycle.OnLifecycleEvent 7 | import kotlin.properties.ReadWriteProperty 8 | import kotlin.reflect.KProperty 9 | 10 | /** 11 | * 绑定[LifecycleOwner]子类生命周期,销毁时自动清理数据,一般用于Fragment和Activity内。 12 | * 13 | * Created by liujunfeng on 2019/1/1. 14 | */ 15 | class AutoClearedValue( 16 | lifecycleOwner: LifecycleOwner 17 | ) : ReadWriteProperty { 18 | private var _value: T? = null 19 | 20 | init { 21 | lifecycleOwner.lifecycle.addObserver(object : LifecycleObserver { 22 | @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 23 | fun onDestroy() { 24 | _value = null 25 | } 26 | }) 27 | } 28 | 29 | override fun getValue(thisRef: LifecycleOwner, property: KProperty<*>): T? { 30 | return _value 31 | } 32 | 33 | override fun setValue(thisRef: LifecycleOwner, property: KProperty<*>, value: T?) { 34 | _value = value 35 | } 36 | } 37 | 38 | /** 39 | * Creates an [AutoClearedValue] associated with this lifecycleOwner. 40 | */ 41 | fun LifecycleOwner.autoCleared() = AutoClearedValue(this) -------------------------------------------------------------------------------- /core-utils/src/main/java/com/huyingbao/core/utils/ClassUtils.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.utils 2 | 3 | import java.lang.reflect.ParameterizedType 4 | 5 | /** 6 | * Class工具类 7 | * 8 | * Created by liujunfeng on 2019/1/1. 9 | */ 10 | object ClassUtils { 11 | /** 12 | * 得到类的泛型类型 13 | */ 14 | @JvmStatic 15 | @SuppressWarnings("unchecked") 16 | fun getGenericClass(aClass: Class<*>, index: Int): Class? { 17 | var genericClass: Class? = null 18 | //返回直接继承的父类(包含泛型参数) 19 | val genericSuperclass = aClass.genericSuperclass 20 | if (genericSuperclass is ParameterizedType) { 21 | try { 22 | genericClass = genericSuperclass.actualTypeArguments[index] as Class 23 | } catch (e: Exception) { 24 | e.printStackTrace() 25 | } 26 | } 27 | return genericClass 28 | } 29 | } -------------------------------------------------------------------------------- /core-utils/src/main/java/com/huyingbao/core/utils/Executors.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.huyingbao.module.common.utils 18 | 19 | import java.util.concurrent.Executors 20 | 21 | private val IO_EXECUTOR = Executors.newSingleThreadExecutor() 22 | 23 | private val NETWORK_EXECUTOR = Executors.newFixedThreadPool(5) 24 | 25 | /** 26 | * Utility method to run blocks on a dedicated background thread, used for io/database work. 27 | */ 28 | fun ioThread(f: () -> Unit) { 29 | IO_EXECUTOR.execute(f) 30 | } 31 | 32 | /** 33 | * Utility method to run blocks on a dedicated background thread, used for net work. 34 | */ 35 | fun networkThread(f: () -> Unit) { 36 | NETWORK_EXECUTOR.execute(f) 37 | } -------------------------------------------------------------------------------- /core-utils/src/main/java/com/huyingbao/core/utils/ViewBindingUtils.kt: -------------------------------------------------------------------------------- 1 | //package com.huyingbao.core.utils 2 | // 3 | //import android.view.LayoutInflater 4 | //import android.view.ViewGroup 5 | //import androidx.viewbinding.ViewBinding 6 | // 7 | //object ViewBindingUtils { 8 | // 9 | // /** 10 | // * 生成ViewBinding,主要给Fragment使用 11 | // */ 12 | // fun inflateViewBinding(inflater: LayoutInflater, container: ViewGroup?) = 13 | // ClassUtils.getGenericClass(javaClass, 0) 14 | // ?.getMethod("inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.java) 15 | // ?.invoke(null, inflater, container, false) 16 | // as VB 17 | // 18 | // /** 19 | // * 生成ViewBinding,主要给Activity使用 20 | // */ 21 | // fun inflateViewBinding(inflater: LayoutInflater) = 22 | // ClassUtils.getGenericClass(javaClass, 0) 23 | // ?.getMethod("inflate", LayoutInflater::class.java) 24 | // ?.invoke(null, inflater) 25 | // as VB 26 | // 27 | //} 28 | // 29 | -------------------------------------------------------------------------------- /core-utils/src/main/java/com/huyingbao/core/utils/ViewUtils.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.core.utils 2 | 3 | import android.animation.ObjectAnimator 4 | import android.animation.StateListAnimator 5 | import android.view.View 6 | import androidx.recyclerview.widget.LinearLayoutManager 7 | import androidx.recyclerview.widget.RecyclerView 8 | import com.google.android.material.appbar.AppBarLayout 9 | 10 | /** 11 | * 解决[com.google.android.material.appbar.AppBarLayout.setElevation]无效问题。 12 | * 13 | * @param view 一般是[com.google.android.material.appbar.AppBarLayout] 14 | */ 15 | fun View.setAppBarElevation(elevation: Float) { 16 | stateListAnimator = StateListAnimator().apply { 17 | addState( 18 | IntArray(0), 19 | ObjectAnimator.ofFloat(this@setAppBarElevation, "elevation", elevation) 20 | ) 21 | } 22 | } 23 | 24 | /** 25 | * 设置View滑动联动[AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL]和[AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS] 26 | * 27 | * @param view 一般是[com.google.android.material.appbar.AppBarLayout]中的子布局。 28 | */ 29 | fun View.setAppBarScroll() { 30 | if (layoutParams is AppBarLayout.LayoutParams) { 31 | (layoutParams as AppBarLayout.LayoutParams).scrollFlags = 32 | AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL or AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS 33 | } 34 | } 35 | 36 | /** 37 | * [RecyclerView]滑动到顶部 38 | */ 39 | fun RecyclerView.scrollToTop() { 40 | if (layoutManager is LinearLayoutManager) { 41 | if ((layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() > 20) { 42 | scrollToPosition(0) 43 | } else { 44 | smoothScrollToPosition(0) 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Apr 18 22:09:20 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip -------------------------------------------------------------------------------- /image/Component和Inject的关系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/image/Component和Inject的关系.png -------------------------------------------------------------------------------- /image/Context子类区别.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/image/Context子类区别.jpg -------------------------------------------------------------------------------- /image/下载.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/image/下载.png -------------------------------------------------------------------------------- /image/依赖注入-Activity与Fragment.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/image/依赖注入-Activity与Fragment.jpg -------------------------------------------------------------------------------- /image/依赖注入-Store.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/image/依赖注入-Store.jpg -------------------------------------------------------------------------------- /image/依赖注入-全局.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/image/依赖注入-全局.jpg -------------------------------------------------------------------------------- /image/架构图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/image/架构图.jpg -------------------------------------------------------------------------------- /image/框架图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/image/框架图.jpg -------------------------------------------------------------------------------- /image/生命周期与订阅管理.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/image/生命周期与订阅管理.jpg -------------------------------------------------------------------------------- /module-app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /module-app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | #lambda 28 | -dontwarn java.lang.invoke.* 29 | 30 | # okhttp 31 | -keepattributes Signature 32 | -keepattributes *Annotation* 33 | -keep class okhttp3.** { *; } 34 | -keep interface okhttp3.** { *; } 35 | -dontwarn okhttp3.** 36 | 37 | # okio 38 | -keep class sun.misc.Unsafe { *; } 39 | -dontwarn java.nio.file.* 40 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 41 | -dontwarn okio.** 42 | 43 | #防止混淆BaseRecyclerViewAdapterHelper 44 | -keep class com.chad.library.adapter.** { *; } 45 | 46 | #防止混淆retrofit2 47 | -dontwarn retrofit2.** 48 | -keep class retrofit2.** { *; } 49 | -keepattributes Signature 50 | -keepattributes Exceptions 51 | 52 | #Arouter 53 | -keep public class com.alibaba.android.arouter.routes.**{*;} 54 | -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} 55 | # 如果使用了 byType 的方式获取 Service,需添加下面规则,保护接口 56 | -keep interface * implements com.alibaba.android.arouter.facade.template.IProvider 57 | # 如果使用了 单类注入,即不定义接口实现 IProvider,需添加下面规则,保护实现 58 | -keep class * implements com.alibaba.android.arouter.facade.template.IProvider -------------------------------------------------------------------------------- /module-app/src/app/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 19 | -------------------------------------------------------------------------------- /module-app/src/app/java/com/huyingbao/module/app/SimpleApplication.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.app 2 | 3 | import com.huyingbao.core.annotations.AppOwner 4 | import com.huyingbao.core.arch.FluxApp 5 | import dagger.hilt.android.HiltAndroidApp 6 | 7 | /** 8 | * 主Application 9 | * 10 | * Created by liujunfeng on 2019/1/1. 11 | */ 12 | @AppOwner 13 | @HiltAndroidApp 14 | class SimpleApplication : FluxApp() 15 | -------------------------------------------------------------------------------- /module-common/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /module-common/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | #lambda 28 | -dontwarn java.lang.invoke.* 29 | 30 | # okhttp 31 | -keepattributes Signature 32 | -keepattributes *Annotation* 33 | -keep class okhttp3.** { *; } 34 | -keep interface okhttp3.** { *; } 35 | -dontwarn okhttp3.** 36 | 37 | # okio 38 | -keep class sun.misc.Unsafe { *; } 39 | -dontwarn java.nio.file.* 40 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 41 | -dontwarn okio.** 42 | 43 | #防止混淆BaseRecyclerViewAdapterHelper 44 | -keep class com.chad.library.adapter.** { *; } 45 | 46 | #防止混淆retrofit2 47 | -dontwarn retrofit2.** 48 | -keep class retrofit2.** { *; } 49 | -keepattributes Signature 50 | -keepattributes Exceptions 51 | 52 | #Arouter 53 | -keep public class com.alibaba.android.arouter.routes.**{*;} 54 | -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} 55 | # 如果使用了 byType 的方式获取 Service,需添加下面规则,保护接口 56 | -keep interface * implements com.alibaba.android.arouter.facade.template.IProvider 57 | # 如果使用了 单类注入,即不定义接口实现 IProvider,需添加下面规则,保护实现 58 | -keep class * implements com.alibaba.android.arouter.facade.template.IProvider -------------------------------------------------------------------------------- /module-common/src/app/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /module-common/src/app/java/com/huyingbao/module/common/CommonApplication.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.common 2 | 3 | import com.huyingbao.core.annotations.AppOwner 4 | import com.huyingbao.core.base.BaseApp 5 | import dagger.hilt.android.HiltAndroidApp 6 | 7 | /** 8 | * Created by liujunfeng on 2019/1/1. 9 | */ 10 | @AppOwner 11 | @HiltAndroidApp 12 | class CommonApplication : BaseApp() { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /module-common/src/library/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /module-common/src/main/java/com/huyingbao/module/common/app/CommonAppModule.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.common.app 2 | 3 | import com.huyingbao.module.common.BuildConfig 4 | import dagger.Module 5 | import dagger.Provides 6 | import dagger.hilt.InstallIn 7 | import dagger.hilt.components.SingletonComponent 8 | import okhttp3.OkHttpClient 9 | import okhttp3.logging.HttpLoggingInterceptor 10 | import java.util.concurrent.TimeUnit 11 | import javax.inject.Singleton 12 | 13 | /** 14 | * 基础依赖注入仓库,所有子模块中的AppModule中需要包括该类,实现Store注入和Dagger.Android注入 15 | * 16 | * Created by liujunfeng on 2019/1/1. 17 | */ 18 | @Module 19 | @InstallIn(SingletonComponent::class) 20 | class CommonAppModule { 21 | @Singleton 22 | @Provides 23 | fun provideClientBuilder(): OkHttpClient.Builder { 24 | //设置日志拦截器 25 | val interceptor = HttpLoggingInterceptor() 26 | interceptor.level = if (BuildConfig.DEBUG) 27 | HttpLoggingInterceptor.Level.BODY 28 | else 29 | HttpLoggingInterceptor.Level.NONE 30 | return OkHttpClient.Builder() 31 | .connectTimeout(CommonAppConstants.Config.HTTP_TIME_OUT, TimeUnit.SECONDS) 32 | .readTimeout(CommonAppConstants.Config.HTTP_TIME_OUT, TimeUnit.SECONDS) 33 | .writeTimeout(CommonAppConstants.Config.HTTP_TIME_OUT, TimeUnit.SECONDS) 34 | .addInterceptor(interceptor) 35 | } 36 | } -------------------------------------------------------------------------------- /module-common/src/main/java/com/huyingbao/module/common/app/CommonStartUp.kt: -------------------------------------------------------------------------------- 1 | //package com.huyingbao.module.common.app 2 | // 3 | //import android.app.Application 4 | //import android.content.Context 5 | //import androidx.startup.Initializer 6 | // 7 | //class CommonStartUp : Initializer { 8 | // override fun create(context: Context): CommonAppStore { 9 | // return CommonAppStore(context as Application) 10 | // } 11 | // 12 | // override fun dependencies(): List>> { 13 | // return emptyList() 14 | // } 15 | //} -------------------------------------------------------------------------------- /module-common/src/main/java/com/huyingbao/module/common/behavior/ScaleDownShowBehavior.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.common.behavior 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.View 6 | import androidx.coordinatorlayout.widget.CoordinatorLayout 7 | import androidx.core.view.ViewCompat 8 | import com.google.android.material.floatingactionbutton.FloatingActionButton 9 | 10 | /** 11 | * [FloatingActionButton]滑动联动隐藏 12 | */ 13 | class ScaleDownShowBehavior( 14 | context: Context, 15 | attrs: AttributeSet? 16 | ) : FloatingActionButton.Behavior(context, attrs) { 17 | override fun onStartNestedScroll( 18 | coordinatorLayout: CoordinatorLayout, 19 | child: FloatingActionButton, 20 | directTargetChild: View, 21 | target: View, 22 | axes: Int, 23 | type: Int 24 | ): Boolean { 25 | return axes == ViewCompat.SCROLL_AXIS_VERTICAL || 26 | super.onStartNestedScroll( 27 | coordinatorLayout, 28 | child, 29 | directTargetChild, 30 | target, 31 | axes, 32 | type 33 | ) 34 | } 35 | 36 | override fun onNestedScroll( 37 | coordinatorLayout: CoordinatorLayout, 38 | child: FloatingActionButton, 39 | target: View, 40 | dxConsumed: Int, 41 | dyConsumed: Int, 42 | dxUnconsumed: Int, 43 | dyUnconsumed: Int, 44 | type: Int 45 | ) { 46 | if (dyConsumed > 0 && child.visibility == View.VISIBLE) { 47 | child.visibility = View.INVISIBLE 48 | } else if (dyConsumed < 0 && child.visibility != View.VISIBLE) { 49 | child.show() 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /module-common/src/main/java/com/huyingbao/module/common/ui/start/StartActivity.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.common.ui.start 2 | 3 | import android.graphics.Color 4 | import android.os.Bundle 5 | import android.view.View 6 | import androidx.fragment.app.Fragment 7 | import com.alibaba.android.arouter.facade.annotation.Route 8 | import com.huyingbao.core.base.BaseFragActivity 9 | import com.huyingbao.module.common.app.CommonAppConstants 10 | 11 | /** 12 | * 引导页面,使用standard模式启动 13 | * 14 | * Created by liujunfeng on 2019/5/31. 15 | */ 16 | @Route(path = CommonAppConstants.Router.StartActivity) 17 | class StartActivity : BaseFragActivity() { 18 | override fun createFragment(): Fragment? { 19 | return StartFragment.newInstance() 20 | } 21 | 22 | override fun afterCreate(savedInstanceState: Bundle?) { 23 | //隐藏ActionBar 24 | supportActionBar?.hide() 25 | //全屏 26 | window.decorView.systemUiVisibility = 27 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE or// 应用的主体内容占用系统status bar的空间 28 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or// 应用的主体内容占用系统status bar的空间 29 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or // 应用的主体内容占navigation bar的空间,同样占用status bar空间 30 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or// 隐藏navigation bar 31 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY// 沉浸式响应 32 | // status bar颜色设置为透明 33 | window.statusBarColor = Color.TRANSPARENT 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /module-common/src/main/java/com/huyingbao/module/common/ui/start/StartFragment.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.common.ui.start 2 | 3 | import android.os.Bundle 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.huyingbao.core.base.common.fragment.BaseFragment 6 | import com.huyingbao.core.utils.AndroidUtils 7 | import com.huyingbao.module.common.R 8 | import com.huyingbao.module.common.app.CommonAppConstants 9 | 10 | 11 | /** 12 | * 引导页面 13 | * 14 | * Created by liujunfeng on 2019/5/31. 15 | */ 16 | class StartFragment : BaseFragment() { 17 | companion object { 18 | fun newInstance() = StartFragment() 19 | } 20 | 21 | override fun getLayoutId() = R.layout.common_fragment_start 22 | 23 | override fun afterCreate(savedInstanceState: Bundle?) { 24 | val appRouter = 25 | CommonAppConstants.Router.getAppRouter(AndroidUtils.getApplicationLabel(context)) 26 | ARouter.getInstance().build(appRouter).navigation() 27 | activity?.finish() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /module-common/src/main/java/com/huyingbao/module/common/ui/update/action/CommonUpdate.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.common.ui.update.action 2 | 3 | import com.huyingbao.module.common.ui.update.model.AppBean 4 | import retrofit2.Response 5 | import retrofit2.http.GET 6 | import retrofit2.http.Path 7 | import retrofit2.http.Query 8 | 9 | /** 10 | * 通用Action 11 | * 12 | * Created by liujunfeng on 2019/6/10. 13 | */ 14 | internal interface DownloadAction { 15 | /** 16 | * 开始下载 17 | * 18 | * @param tag 下载的唯一标记 19 | * @param url 下载地址 20 | * @param local 本地存储地址 21 | */ 22 | fun downloadStart(tag: String, url: String, local: String): Boolean 23 | } 24 | 25 | interface AppAction { 26 | companion object { 27 | /** 28 | * 获取App最新版本信息 29 | */ 30 | const val GET_APP_LATEST = "getAppLatest" 31 | } 32 | 33 | /** 34 | * 获取App最新版本信息 35 | */ 36 | fun getAppLatest(id: String, token: String) 37 | } 38 | 39 | /** 40 | * App分发平台Fir接口Api 41 | */ 42 | interface FirApi { 43 | /** 44 | * 获取App最新版本信息 45 | */ 46 | @GET("apps/latest/{id}") 47 | suspend fun getAppLatest( 48 | @Path("id") id: String, 49 | @Query("api_token") token: String 50 | ): Response 51 | } -------------------------------------------------------------------------------- /module-common/src/main/java/com/huyingbao/module/common/ui/update/module/CommonUpdateDialogModule.kt: -------------------------------------------------------------------------------- 1 | //package com.huyingbao.module.common.ui.update.module 2 | // 3 | //import com.huyingbao.core.progress.DownloadApi 4 | //import com.huyingbao.core.progress.ProgressInterceptor 5 | //import dagger.Module 6 | //import dagger.Provides 7 | //import dagger.hilt.InstallIn 8 | //import dagger.hilt.android.components.FragmentComponent 9 | //import dagger.hilt.android.scopes.FragmentScoped 10 | //import okhttp3.OkHttpClient 11 | //import retrofit2.Retrofit 12 | // 13 | ///** 14 | // * [com.huyingbao.module.common.ui.update.view.CommonUpdateDialog]的依赖注入仓库 15 | // * 16 | // * Created by liujunfeng on 2019/1/1. 17 | // */ 18 | //@Module 19 | //@InstallIn(FragmentComponent::class) 20 | //class CommonUpdateDialogModule { 21 | // @FragmentScoped 22 | // @Provides 23 | // fun provideDownloadApi( 24 | // builder: OkHttpClient.Builder, 25 | // progressInterceptor: ProgressInterceptor 26 | // ): DownloadApi { 27 | // //初始化OkHttp 28 | // val client = builder 29 | // .addInterceptor(progressInterceptor) 30 | // .retryOnConnectionFailure(true) 31 | // .build() 32 | // //初始化Retrofit 33 | // val retrofit = Retrofit.Builder() 34 | // .baseUrl("https://www.debug.com/") 35 | // .client(client) 36 | // .build() 37 | // return retrofit.create(DownloadApi::class.java) 38 | // } 39 | //} -------------------------------------------------------------------------------- /module-common/src/main/java/com/huyingbao/module/common/utils/ViewUtils.kt: -------------------------------------------------------------------------------- 1 | //package com.huyingbao.module.common.utils 2 | // 3 | //import android.content.Context 4 | //import android.view.Gravity 5 | //import android.view.View 6 | //import android.view.ViewGroup 7 | //import android.widget.ImageView 8 | //import androidx.coordinatorlayout.widget.CoordinatorLayout 9 | //import com.google.android.material.floatingactionbutton.FloatingActionButton 10 | //import com.huyingbao.core.test.R 11 | //import com.huyingbao.module.common.behavior.ScaleDownShowBehavior 12 | // 13 | ///** 14 | // * 公用添加[FloatingActionButton]方法 15 | // */ 16 | //fun ViewGroup.addFloatingActionButton(context: Context, onClickListener: View.OnClickListener) { 17 | // addView( 18 | // FloatingActionButton(context).apply { 19 | // //设置图片 20 | // setImageResource(R.drawable.ic_arrow_upward) 21 | // //图片自适应居中 22 | // scaleType = ImageView.ScaleType.FIT_CENTER 23 | // //设置点击事件 24 | // setOnClickListener(onClickListener) 25 | // }, 26 | // CoordinatorLayout.LayoutParams( 27 | // ViewGroup.LayoutParams.WRAP_CONTENT, 28 | // ViewGroup.LayoutParams.WRAP_CONTENT 29 | // ).apply { 30 | // //位于右下 31 | // gravity = Gravity.BOTTOM or Gravity.END 32 | // //边距16dp 33 | // setMargins(0, 0, 34 | // resources.getDimensionPixelSize(R.dimen.dp_16), 35 | // resources.getDimensionPixelSize(R.dimen.dp_16) 36 | // ) 37 | // //设置滑动隐藏行为 38 | // behavior = ScaleDownShowBehavior(context, null) 39 | // }) 40 | //} -------------------------------------------------------------------------------- /module-common/src/main/res/color/common_text_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /module-common/src/main/res/drawable-xxhdpi/bg_app.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/module-common/src/main/res/drawable-xxhdpi/bg_app.webp -------------------------------------------------------------------------------- /module-common/src/main/res/drawable/bg_launch.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 15 | -------------------------------------------------------------------------------- /module-common/src/main/res/drawable/ic_arrow_upward.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /module-common/src/main/res/drawable/ic_more.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /module-common/src/main/res/drawable/ic_star.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /module-common/src/main/res/drawable/ripple_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /module-common/src/main/res/drawable/shape_dialog_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /module-common/src/main/res/drawable/shape_edit_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /module-common/src/main/res/drawable/shape_side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | -------------------------------------------------------------------------------- /module-common/src/main/res/layout/common_cardview_info.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | 22 | 23 | 32 | 33 | 41 | 42 | 47 | 48 | -------------------------------------------------------------------------------- /module-common/src/main/res/layout/common_dialog_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 18 | 19 | 30 | 31 | 42 | 43 | -------------------------------------------------------------------------------- /module-common/src/main/res/layout/common_fragment_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /module-common/src/main/res/layout/common_fragment_start.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | -------------------------------------------------------------------------------- /module-common/src/main/res/layout/common_fragment_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 15 | 16 | 21 | 22 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /module-common/src/main/res/menu/common_web.xml: -------------------------------------------------------------------------------- 1 | 2 |

4 | 5 | 9 | 13 | 17 | -------------------------------------------------------------------------------- /module-common/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolfire2015/RxFluxArchitecture/3bb18e343d8e0b3e28faa3fe49c1d7c7dc837075/module-common/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /module-common/src/main/res/values-night/common_colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #35464e 5 | #212a2f 6 | @color/Grey600 7 | 8 | @color/Grey300 9 | 10 | @color/Grey300 11 | @color/Grey500 12 | 13 | @color/Grey700 14 | 15 | @color/Cyan 16 | @color/White 17 | 18 | @color/Grey800 19 | 20 | -------------------------------------------------------------------------------- /module-common/src/main/res/values/common_attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /module-common/src/main/res/values/common_dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 0.4dp 3 | 2dp 4 | 4dp 5 | 6dp 6 | 10dp 7 | 12dp 8 | 16dp 9 | 20dp 10 | 24dp 11 | 32dp 12 | 40dp 13 | 48dp 14 | 64dp 15 | 72dp 16 | 80dp 17 | 100dp 18 | 120dp 19 | 160dp 20 | 200dp 21 | 320dp 22 | 400dp 23 | 24 | 8sp 25 | 10sp 26 | 12sp 27 | 14sp 28 | 16sp 29 | 18sp 30 | 20sp 31 | 22sp 32 | 33 | -------------------------------------------------------------------------------- /module-common/src/main/res/values/common_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | RxFluxApp 4 | 引导 5 | 玩安卓 6 | 疫情查询 7 | 干货集中营 8 | Github 9 | 10 | 取消 11 | 重试 12 | 确定 13 | 请输入标题 14 | 请输入内容 15 | 16 | 分享 17 | 复制 18 | 收藏 19 | 用浏览器打开 20 | 21 | 已经复制到粘贴板 22 | -------------------------------------------------------------------------------- /module-history/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /module-history/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | #lambda 28 | -dontwarn java.lang.invoke.* 29 | 30 | # okhttp 31 | -keepattributes Signature 32 | -keepattributes *Annotation* 33 | -keep class okhttp3.** { *; } 34 | -keep interface okhttp3.** { *; } 35 | -dontwarn okhttp3.** 36 | 37 | # okio 38 | -keep class sun.misc.Unsafe { *; } 39 | -dontwarn java.nio.file.* 40 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 41 | -dontwarn okio.** 42 | 43 | #防止混淆BaseRecyclerViewAdapterHelper 44 | -keep class com.chad.library.adapter.** { *; } 45 | 46 | #防止混淆retrofit2 47 | -dontwarn retrofit2.** 48 | -keep class retrofit2.** { *; } 49 | -keepattributes Signature 50 | -keepattributes Exceptions 51 | 52 | #Arouter 53 | -keep public class com.alibaba.android.arouter.routes.**{*;} 54 | -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} 55 | # 如果使用了 byType 的方式获取 Service,需添加下面规则,保护接口 56 | -keep interface * implements com.alibaba.android.arouter.facade.template.IProvider 57 | # 如果使用了 单类注入,即不定义接口实现 IProvider,需添加下面规则,保护实现 58 | -keep class * implements com.alibaba.android.arouter.facade.template.IProvider -------------------------------------------------------------------------------- /module-history/src/app/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /module-history/src/app/java/com/huyingbao/module/history/WanApplication.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history 2 | 3 | import com.huyingbao.core.annotations.AppOwner 4 | import com.huyingbao.core.base.BaseApp 5 | 6 | import dagger.hilt.android.HiltAndroidApp 7 | 8 | /** 9 | * Created by liujunfeng on 2019/1/1. 10 | */ 11 | @AppOwner 12 | @HiltAndroidApp 13 | class WanApplication : BaseApp() { 14 | } 15 | -------------------------------------------------------------------------------- /module-history/src/library/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/app/WanAppDatabase.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.app 2 | 3 | import androidx.room.Database 4 | import androidx.room.RoomDatabase 5 | import com.huyingbao.module.history.model.Article 6 | import com.huyingbao.module.history.model.ArticleDao 7 | 8 | /** 9 | *GithubAppDatabase是一个继承[RoomDatabase]的抽象类。 10 | * 11 | *在[Database]注解中包含与数据库相关联的实体列表。 12 | * 13 | *包含一个具有0个参数的抽象方法,并返回用@Dao注释的类。 14 | */ 15 | @Database( 16 | entities = [Article::class], 17 | version = 3, 18 | exportSchema = false 19 | ) 20 | abstract class WanAppDatabase : RoomDatabase() { 21 | abstract fun reposDao(): ArticleDao 22 | } 23 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/app/WanAppLifecycle.kt: -------------------------------------------------------------------------------- 1 | //package com.huyingbao.module.history.app 2 | // 3 | // 4 | //import androidx.lifecycle.Lifecycle 5 | //import androidx.lifecycle.OnLifecycleEvent 6 | //import com.huyingbao.core.annotations.AppObserver 7 | //import com.huyingbao.core.arch.lifecycle.AppLifecycleObserver 8 | //import com.huyingbao.module.history.WanEventBusIndex 9 | //import org.greenrobot.eventbus.EventBus 10 | //import javax.inject.Inject 11 | // 12 | ///** 13 | // * Application生命周期方法分发类 14 | // * 15 | // * Created by liujunfeng on 2019/8/1. 16 | // */ 17 | //@AppObserver 18 | //class WanAppLifecycle @Inject constructor() : AppLifecycleObserver() { 19 | // @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) 20 | // override fun onCreate() { 21 | // EventBus.builder() 22 | // .addIndex(WanEventBusIndex()) 23 | // .eventInheritance(false) 24 | // } 25 | // 26 | // @OnLifecycleEvent(Lifecycle.Event.ON_STOP) 27 | // override fun onLowMemory() { 28 | // 29 | // } 30 | // 31 | // @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 32 | // override fun onTerminate() { 33 | // } 34 | //} 35 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/app/WanAppModule.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.app 2 | 3 | 4 | import android.app.Application 5 | import androidx.room.Room 6 | import androidx.room.RoomDatabase 7 | import com.huyingbao.module.history.BuildConfig 8 | import dagger.Module 9 | import dagger.Provides 10 | import dagger.hilt.InstallIn 11 | import dagger.hilt.components.SingletonComponent 12 | import okhttp3.OkHttpClient 13 | import retrofit2.Retrofit 14 | import retrofit2.converter.gson.GsonConverterFactory 15 | import javax.inject.Named 16 | import javax.inject.Singleton 17 | 18 | /** 19 | * Created by liujunfeng on 2019/1/1. 20 | */ 21 | @Module 22 | @InstallIn(SingletonComponent::class) 23 | object WanAppModule { 24 | /** 25 | * Api根路径 26 | */ 27 | const val BASE_API = "https://www.historyandroid.com/" 28 | 29 | /** 30 | * 需要创建的数据库名字 31 | */ 32 | const val DATABASE_NAME = "history-db" 33 | 34 | /** 35 | * 提供[Retrofit]单例对象 36 | * 37 | * 每个子模块的Module中都提供[Retrofit]单例对象,使用[Named]注解,子模块提供的单例对象。 38 | */ 39 | @Singleton 40 | @Provides 41 | @Named(BuildConfig.MODULE_NAME) 42 | fun provideRetrofit(builder: OkHttpClient.Builder): Retrofit { 43 | return Retrofit.Builder() 44 | .baseUrl(BASE_API) 45 | .addConverterFactory(GsonConverterFactory.create()) 46 | .client(builder.build()) 47 | .build() 48 | } 49 | 50 | /** 51 | * 提供[RoomDatabase]单例对象,获得创建数据库的实例: 52 | */ 53 | @Singleton 54 | @Provides 55 | fun provideDataBase(application: Application): WanAppDatabase { 56 | val databaseBuilder = Room.databaseBuilder( 57 | application, 58 | WanAppDatabase::class.java, 59 | DATABASE_NAME 60 | ) 61 | //允许Room破坏性地重新创建数据库表。 62 | .fallbackToDestructiveMigration() 63 | return databaseBuilder.build() 64 | } 65 | } -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/model/Article.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.model 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.Ignore 6 | import androidx.room.PrimaryKey 7 | 8 | /** 9 | * 默认情况下,Room使用类名作为数据库表名,SQLite中的表名不区分大小写。 10 | * 11 | * Created by liujunfeng on 2019/1/1. 12 | */ 13 | @Entity(tableName = "article") 14 | data class Article( 15 | 16 | /** 17 | * apkLink : 18 | * author : 郭霖 19 | * chapterId : 409 20 | * chapterName : 郭霖 21 | * collect : false 22 | * courseId : 13 23 | * desc : 24 | * envelopePic : 25 | * fresh : false 26 | * id : 7668 27 | * link : https://mp.weixin.qq.com/s/s4WgLFN0A-vO0ko0wi25mA 28 | * niceDate : 2018-12-17 29 | * origin : 30 | * projectLink : 31 | * publishTime : 1544976000000 32 | * superChapterId : 408 33 | * superChapterName : 公众号 34 | * tags : [{"name":"公众号","url":"/wxarticle/list/409/1"}] 35 | * title : 一起玩转Android项目中的字节码 36 | * type : 0 37 | * userId : -1 38 | * visible : 1 39 | * zan : 0 40 | */ 41 | var apkLink: String? = null, 42 | var author: String? = null, 43 | var chapterId: Int = 0, 44 | var chapterName: String? = null, 45 | var isCollect: Boolean = false, 46 | var courseId: Int = 0, 47 | var desc: String? = null, 48 | var envelopePic: String? = null, 49 | var isFresh: Boolean = false, 50 | @PrimaryKey 51 | var id: Int = 0, 52 | var link: String? = null, 53 | var niceDate: String? = null, 54 | var origin: String? = null, 55 | var projectLink: String? = null, 56 | //具有不同的名称 57 | @ColumnInfo(name = "publish_time") 58 | var publishTime: Long = 0, 59 | var superChapterId: Int = 0, 60 | var superChapterName: String? = null, 61 | var title: String? = null, 62 | var type: Int = 0, 63 | var userId: Int = 0, 64 | var visible: Int = 0, 65 | var zan: Int = 0, 66 | @Ignore //不想持久的字段 67 | var tags: List? = null 68 | ) 69 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/model/ArticleDao.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.model 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.paging.DataSource 5 | import androidx.room.* 6 | 7 | /** 8 | * 包含用于访问数据库的方法。 9 | * 通过使用DAO类访问数据库而不是查询构造器或直接查询,可以分离数据库体系结构的不同组件。 10 | * 此外,DAOs允许您在测试应用程序时轻松模拟数据库访问。 11 | * DAO既可以是接口,也可以是抽象类。如果是抽象类,它可以有一个构造函数,它把RoomDatabase作为唯一的参数。 12 | * Room在编译时创建每个DAO实现。 13 | * 除非调用[RoomDatabase.Builder.allowMainThreadQueries],否则Room不支持在主线程上的数据访问。 14 | * 而返回[LiveData]或者[io.reactivex.Flowable]实例的异步查询可免除此规则,因为它们在需要时异步地在后台线程上运行查询。 15 | */ 16 | @Dao 17 | interface ArticleDao { 18 | /** 19 | * SQLite处理@Insert(onConflict = OnConflictStrategy.REPLACE)作为一套REMOVE和REPLACE操作而不是单一的更新操作。 20 | * 本替换冲突值的方法有可能影响外键约束 21 | */ 22 | @Insert(onConflict = OnConflictStrategy.REPLACE) 23 | fun insertAll(list: ArrayList
) 24 | 25 | @Query("SELECT * FROM article ORDER BY publish_time DESC") 26 | fun getArticleList(): DataSource.Factory 27 | 28 | @Query("DELETE FROM article") 29 | fun deleteAll() 30 | } 31 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/model/Banner.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.model 2 | 3 | /** 4 | * Created by liujunfeng on 2019/1/1. 5 | */ 6 | class Banner { 7 | 8 | /** 9 | * desc : 一起来做个App吧 10 | * id : 10 11 | * imagePath : http://www.historyandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png 12 | * isVisible : 1 13 | * order : 3 14 | * title : 一起来做个App吧 15 | * type : 0 16 | * url : http://www.historyandroid.com/blog/show/2 17 | */ 18 | 19 | var desc: String? = null 20 | var id: Int = 0 21 | var imagePath: String? = null 22 | var isVisible: Int = 0 23 | var order: Int = 0 24 | var title: String? = null 25 | var type: Int = 0 26 | var url: String? = null 27 | } 28 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/model/Tag.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.model 2 | 3 | /** 4 | * Created by liujunfeng on 2019/1/1. 5 | */ 6 | class Tag { 7 | /** 8 | * name : 公众号 9 | * url : /wxarticle/list/409/1 10 | */ 11 | 12 | var name: String? = null 13 | var url: String? = null 14 | } 15 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/model/WanResponse.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.model 2 | 3 | /** 4 | * Created by liujunfeng on 2019/1/1. 5 | */ 6 | class WanResponse { 7 | var data: T? = null 8 | var errorCode: Int = 0 9 | var errorMsg: String? = null 10 | } 11 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/model/WebSite.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.model 2 | 3 | /** 4 | * Created by liujunfeng on 2019/1/1. 5 | */ 6 | class WebSite { 7 | 8 | /** 9 | * icon : 10 | * id : 17 11 | * link : http://www.historyandroid.com/article/list/0?cid=176 12 | * name : 国内大牛博客集合 13 | * order : 1 14 | * visible : 1 15 | */ 16 | 17 | var icon: String? = null 18 | var id: Int = 0 19 | var link: String? = null 20 | var name: String? = null 21 | var order: Int = 0 22 | var visible: Int = 0 23 | } 24 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/ui/article/action/Article.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.ui.article.action 2 | 3 | import com.huyingbao.module.history.model.Article 4 | import com.huyingbao.module.history.model.Banner 5 | import com.huyingbao.module.history.model.Page 6 | import com.huyingbao.module.history.model.WanResponse 7 | import retrofit2.http.GET 8 | import retrofit2.http.Path 9 | import java.util.* 10 | 11 | /** 12 | * Created by liujunfeng on 2019/1/1. 13 | */ 14 | interface ArticleAction { 15 | 16 | companion object { 17 | const val TO_BANNER = "toBanner" 18 | const val TO_FRIEND = "toFriend" 19 | 20 | /** 21 | * 获取文章列表 22 | */ 23 | const val GET_ARTICLE_LIST = "getArticleList" 24 | 25 | /** 26 | * 获取Banner列表 27 | */ 28 | const val GET_BANNER_LIST = "getBannerList" 29 | } 30 | 31 | /** 32 | * 获取文章列表 33 | * 34 | * @param page 页码 35 | */ 36 | fun getArticleList(page: Int) 37 | 38 | /** 39 | * 获取Banner列表 40 | */ 41 | fun getBannerList() 42 | } 43 | 44 | interface ArticleApi { 45 | /** 46 | * 获取文章列表 47 | * 48 | * @param page 页码 49 | */ 50 | @GET("article/list/{page}/json") 51 | suspend fun getArticleList(@Path("page") page: Int): WanResponse> 52 | 53 | /** 54 | * 获取Banner列表 55 | */ 56 | @GET("banner/json") 57 | suspend fun getBannerList(): WanResponse> 58 | } 59 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/ui/article/action/ArticleActionCreator.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.ui.article.action 2 | 3 | import com.huyingbao.core.arch.action.FluxActionCreator 4 | import com.huyingbao.module.common.app.CommonAppConstants 5 | import com.huyingbao.module.history.BuildConfig 6 | import dagger.hilt.android.scopes.ActivityRetainedScoped 7 | import kotlinx.coroutines.flow.flow 8 | import retrofit2.Retrofit 9 | import javax.inject.Inject 10 | import javax.inject.Named 11 | 12 | 13 | /** 14 | * rxAction创建发送管理类 15 | * 16 | * Created by liujunfeng on 2019/1/1. 17 | */ 18 | @ActivityRetainedScoped 19 | class ArticleActionCreator @Inject constructor( 20 | @param:Named(BuildConfig.MODULE_NAME) private val retrofit: Retrofit 21 | ) : FluxActionCreator(), ArticleAction { 22 | 23 | override fun getArticleList(page: Int) { 24 | val rxAction = newAction( 25 | ArticleAction.GET_ARTICLE_LIST, 26 | CommonAppConstants.Key.PAGE, page 27 | ) 28 | rxAction.isGlobalCatch = false 29 | val articleApi = retrofit.create(ArticleApi::class.java) 30 | postHttpLoadingAction(rxAction, flow { emit(articleApi.getArticleList(page)) }) 31 | } 32 | 33 | override fun getBannerList() { 34 | val rxAction = newAction(ArticleAction.GET_BANNER_LIST) 35 | rxAction.isGlobalCatch = false 36 | postHttpLoadingAction( 37 | rxAction, 38 | flow { emit(retrofit.create(ArticleApi::class.java).getBannerList()) }) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/ui/article/adapter/BannerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.ui.article.adapter 2 | 3 | import com.chad.library.adapter.base.BaseQuickAdapter 4 | import com.chad.library.adapter.base.viewholder.BaseViewHolder 5 | import com.huyingbao.module.history.R 6 | import com.huyingbao.module.history.model.Banner 7 | 8 | /** 9 | * Created by liujunfeng on 2019/1/1. 10 | */ 11 | class BannerAdapter( 12 | data: MutableList? 13 | ) : BaseQuickAdapter( 14 | R.layout.history_recycle_item_banner, 15 | data 16 | ) { 17 | override fun convert(helper: BaseViewHolder, item: Banner) { 18 | helper.setText(R.id.tv_item_title, item.title) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/ui/article/view/ArticleActivity.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.ui.article.view 2 | 3 | import android.os.Bundle 4 | import androidx.activity.viewModels 5 | import androidx.fragment.app.Fragment 6 | import com.alibaba.android.arouter.facade.annotation.Route 7 | import com.huyingbao.core.arch.model.Change 8 | import com.huyingbao.core.arch.view.FluxView 9 | import com.huyingbao.core.base.BaseFragActivity 10 | import com.huyingbao.module.common.app.CommonAppConstants 11 | import com.huyingbao.module.history.ui.article.action.ArticleAction 12 | import com.huyingbao.module.history.ui.article.store.ArticleStore 13 | import dagger.hilt.android.AndroidEntryPoint 14 | import org.greenrobot.eventbus.Subscribe 15 | 16 | /** 17 | * Created by liujunfeng on 2019/1/1. 18 | */ 19 | @Route(path = CommonAppConstants.Router.ArticleActivity) 20 | @AndroidEntryPoint 21 | class ArticleActivity : FluxView, BaseFragActivity() { 22 | override val store: ArticleStore by viewModels() 23 | 24 | override fun createFragment(): Fragment? { 25 | return ArticleListFragment.newInstance() 26 | } 27 | 28 | override fun afterCreate(savedInstanceState: Bundle?) { 29 | //设置联动 30 | // findViewById(R.id.).setAppBarScroll() 31 | //添加FloatingActionButton 32 | // findViewById(R.id.cdl_content) 33 | // .addFloatingActionButton(this, View.OnClickListener { 34 | // baseActionCreator.postLocalChange(CommonAppAction.SCROLL_TO_TOP) 35 | // }) 36 | } 37 | 38 | @Subscribe(tags = [ArticleAction.TO_FRIEND], sticky = true) 39 | fun toFriend(change: Change) { 40 | // setFragment(getFragmentContainerId(), FriendFragment.newInstance(), FragmentOp.OP_HIDE) 41 | } 42 | 43 | @Subscribe(tags = [ArticleAction.TO_BANNER], sticky = true) 44 | fun toBanner(change: Change) { 45 | // setFragment(getFragmentContainerId(), BannerFragment.newInstance(), FragmentOp.OP_HIDE) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/ui/friend/action/Friend.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.ui.friend.action 2 | 3 | import com.huyingbao.module.history.model.WanResponse 4 | import com.huyingbao.module.history.model.WebSite 5 | import retrofit2.http.GET 6 | import java.util.* 7 | 8 | /** 9 | * Created by liujunfeng on 2019/1/1. 10 | */ 11 | interface FriendAction { 12 | 13 | companion object { 14 | /** 15 | * 获取友站列表 16 | */ 17 | const val GET_FRIEND_LIST = "get_friend_list" 18 | } 19 | 20 | /** 21 | * 获取友站列表 22 | */ 23 | fun getFriendList() 24 | } 25 | 26 | interface FriendApi { 27 | /** 28 | * 获取友站列表 29 | */ 30 | @GET("friend/json") 31 | suspend fun getFriendList(): WanResponse> 32 | } 33 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/ui/friend/action/FriendActionCreator.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.ui.friend.action 2 | 3 | import com.huyingbao.core.arch.action.FluxActionCreator 4 | import com.huyingbao.module.history.BuildConfig 5 | import dagger.hilt.android.scopes.FragmentScoped 6 | import kotlinx.coroutines.flow.flow 7 | import retrofit2.Retrofit 8 | import javax.inject.Inject 9 | import javax.inject.Named 10 | 11 | /** 12 | * Created by liujunfeng on 2019/1/1. 13 | */ 14 | @FragmentScoped 15 | class FriendActionCreator @Inject constructor( 16 | @param:Named(BuildConfig.MODULE_NAME) private val retrofit: Retrofit 17 | ) : FluxActionCreator(), FriendAction { 18 | override fun getFriendList() { 19 | val rxAction = newAction(FriendAction.GET_FRIEND_LIST) 20 | rxAction.isGlobalCatch = false 21 | postHttpLoadingAction( 22 | rxAction, 23 | flow { emit(retrofit.create(FriendApi::class.java).getFriendList()) }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/ui/friend/adapter/WebSiteAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.ui.friend.adapter 2 | 3 | import com.chad.library.adapter.base.BaseQuickAdapter 4 | import com.chad.library.adapter.base.viewholder.BaseViewHolder 5 | import com.huyingbao.module.history.R 6 | import com.huyingbao.module.history.model.WebSite 7 | 8 | /** 9 | * Created by liujunfeng on 2019/1/1. 10 | */ 11 | class WebSiteAdapter( 12 | data: MutableList? 13 | ) : BaseQuickAdapter( 14 | R.layout.history_recycle_item_friend, 15 | data 16 | ) { 17 | override fun convert(helper: BaseViewHolder, item: WebSite) { 18 | helper.setText(R.id.tv_item_title, item.name) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /module-history/src/main/java/com/huyingbao/module/wan/ui/friend/store/FriendStore.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.history.ui.friend.store 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.huyingbao.core.arch.model.Action 5 | import com.huyingbao.core.arch.store.FluxStore 6 | import com.huyingbao.module.history.model.WanResponse 7 | import com.huyingbao.module.history.model.WebSite 8 | import com.huyingbao.module.history.ui.friend.action.FriendAction 9 | import dagger.hilt.android.lifecycle.HiltViewModel 10 | import org.greenrobot.eventbus.Subscribe 11 | import java.util.* 12 | import javax.inject.Inject 13 | 14 | /** 15 | * Created by liujunfeng on 2019/1/1. 16 | */ 17 | @HiltViewModel 18 | class FriendStore @Inject constructor( 19 | ) : FluxStore() { 20 | val webSiteListData = MutableLiveData>>() 21 | 22 | override fun onCleared() { 23 | super.onCleared() 24 | webSiteListData.value = null 25 | } 26 | 27 | @Subscribe(tags = [FriendAction.GET_FRIEND_LIST]) 28 | fun setWebSiteListData(rxAction: Action) { 29 | webSiteListData.value = rxAction.getResponse() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /module-history/src/main/res/layout/banner_fragment_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /module-history/src/main/res/layout/wan_recycle_item_banner.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /module-history/src/main/res/layout/wan_recycle_item_friend.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /module-history/src/main/res/menu/wan_fragment_article_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 13 | 17 | -------------------------------------------------------------------------------- /module-history/src/main/res/values/wan_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 文章 4 | 常用网站 5 | 横幅 6 | 干货集中营 7 | 置顶 8 | 9 | -------------------------------------------------------------------------------- /module-history/src/test/java/com/huyingbao/module/wan/ui/article/view/ArticleActivityTest.kt: -------------------------------------------------------------------------------- 1 | //package com.huyingbao.module.history.ui.article.view 2 | // 3 | //import androidx.lifecycle.Lifecycle 4 | //import androidx.test.ext.junit.rules.ActivityScenarioRule 5 | //import androidx.test.ext.junit.runners.AndroidJUnit4 6 | //import com.huyingbao.module.history.R 7 | //import com.huyingbao.module.history.WanApplication 8 | //import org.junit.* 9 | //import org.junit.runner.RunWith 10 | //import org.robolectric.annotation.Config 11 | // 12 | ///** 13 | // * Robolectric配合Espresso使用,实际运行scenario对应的方法。 14 | // * build.gradle配置test src之后,Robolectric使用当前model作为App时的[WanApplication]和AndroidManifest.xml文件。 15 | // * 16 | // * Created by liujunfeng on 2019/3/28. 17 | // */ 18 | //@RunWith(AndroidJUnit4::class) 19 | //@Config(application = WanApplication::class, sdk = [28]) 20 | //class ArticleActivityTest { 21 | // @get:Rule 22 | // var scenarioRule = ActivityScenarioRule(ArticleActivity::class.java) 23 | // 24 | // @Before 25 | // fun setUp() { 26 | // //Activity场景移动到Lifecycle.State.CREATED 27 | // scenarioRule.scenario.moveToState(Lifecycle.State.CREATED) 28 | // } 29 | // 30 | // @After 31 | // fun tearDown() { 32 | // //Activity场景移动到Lifecycle.State.DESTROYED 33 | // scenarioRule.scenario.moveToState(Lifecycle.State.DESTROYED) 34 | // } 35 | // 36 | // @Test 37 | // fun afterCreate() { 38 | // scenarioRule.scenario.moveToState(Lifecycle.State.RESUMED) 39 | // scenarioRule.scenario.onActivity { 40 | // //验证ArticleListFragment已经添加到当前Activity中 41 | // val fragment = it.supportFragmentManager.findFragmentById(R.id.fl_container) 42 | // Assert.assertTrue(fragment is ArticleListFragment) 43 | // } 44 | // } 45 | //} -------------------------------------------------------------------------------- /module-history/src/test/resources/json/articleList.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "curPage": 2, 4 | "datas": [ 5 | { 6 | "apkLink": "", 7 | "author": "鸿洋", 8 | "chapterId": 408, 9 | "chapterName": "鸿洋", 10 | "collect": false, 11 | "courseId": 13, 12 | "desc": "", 13 | "envelopePic": "", 14 | "fresh": false, 15 | "id": 8182, 16 | "link": "https://mp.weixin.qq.com/s/9lytCZN_xSyGVGleCMenRA", 17 | "niceDate": "2019-03-28", 18 | "origin": "", 19 | "projectLink": "", 20 | "publishTime": 1553702400000, 21 | "superChapterId": 408, 22 | "superChapterName": "公众号", 23 | "tags": [ 24 | { 25 | "name": "公众号", 26 | "url": "/wxarticle/list/408/1" 27 | } 28 | ], 29 | "title": "七个方面带你玩转Java线程池", 30 | "type": 0, 31 | "userId": -1, 32 | "visible": 1, 33 | "zan": 0 34 | }, 35 | { 36 | "apkLink": "", 37 | "author": "郭霖", 38 | "chapterId": 409, 39 | "chapterName": "郭霖", 40 | "collect": false, 41 | "courseId": 13, 42 | "desc": "", 43 | "envelopePic": "", 44 | "fresh": false, 45 | "id": 8186, 46 | "link": "https://mp.weixin.qq.com/s/wE07hFTPKBo6drkqpO8YAA", 47 | "niceDate": "2019-03-28", 48 | "origin": "", 49 | "projectLink": "", 50 | "publishTime": 1553702400000, 51 | "superChapterId": 408, 52 | "superChapterName": "公众号", 53 | "tags": [ 54 | { 55 | "name": "公众号", 56 | "url": "/wxarticle/list/409/1" 57 | } 58 | ], 59 | "title": "通过王者荣耀来学习策略模式", 60 | "type": 0, 61 | "userId": -1, 62 | "visible": 1, 63 | "zan": 0 64 | } 65 | ], 66 | "offset": 20, 67 | "over": false, 68 | "pageCount": 315, 69 | "size": 20, 70 | "total": 6283 71 | }, 72 | "errorCode": 0, 73 | "errorMsg": "" 74 | } -------------------------------------------------------------------------------- /module-history/src/test/resources/json/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "chapterTops": [], 4 | "collectIds": [], 5 | "email": "", 6 | "icon": "", 7 | "id": 14918, 8 | "password": "", 9 | "token": "", 10 | "type": 0, 11 | "username": "coolfire" 12 | }, 13 | "errorCode": 0, 14 | "errorMsg": "" 15 | } -------------------------------------------------------------------------------- /module-history/src/test/resources/json/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "chapterTops": [], 4 | "collectIds": [], 5 | "email": "", 6 | "icon": "", 7 | "id": 21768, 8 | "password": "", 9 | "token": "", 10 | "type": 0, 11 | "username": "lslllkasdfjkkjlasdfdfg" 12 | }, 13 | "errorCode": 0, 14 | "errorMsg": "" 15 | } -------------------------------------------------------------------------------- /module-login/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /module-login/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | #lambda 28 | -dontwarn java.lang.invoke.* 29 | 30 | # okhttp 31 | -keepattributes Signature 32 | -keepattributes *Annotation* 33 | -keep class okhttp3.** { *; } 34 | -keep interface okhttp3.** { *; } 35 | -dontwarn okhttp3.** 36 | 37 | # okio 38 | -keep class sun.misc.Unsafe { *; } 39 | -dontwarn java.nio.file.* 40 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 41 | -dontwarn okio.** 42 | 43 | #防止混淆BaseRecyclerViewAdapterHelper 44 | -keep class com.chad.library.adapter.** { *; } 45 | 46 | #防止混淆retrofit2 47 | -dontwarn retrofit2.** 48 | -keep class retrofit2.** { *; } 49 | -keepattributes Signature 50 | -keepattributes Exceptions 51 | 52 | #Arouter 53 | -keep public class com.alibaba.android.arouter.routes.**{*;} 54 | -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} 55 | # 如果使用了 byType 的方式获取 Service,需添加下面规则,保护接口 56 | -keep interface * implements com.alibaba.android.arouter.facade.template.IProvider 57 | # 如果使用了 单类注入,即不定义接口实现 IProvider,需添加下面规则,保护实现 58 | -keep class * implements com.alibaba.android.arouter.facade.template.IProvider -------------------------------------------------------------------------------- /module-login/src/app/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /module-login/src/app/java/com/huyingbao/module/login/LoginApplication.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.login 2 | 3 | import com.huyingbao.core.annotations.AppOwner 4 | import com.huyingbao.core.arch.FluxApp 5 | 6 | import dagger.hilt.android.HiltAndroidApp 7 | 8 | /** 9 | * Created by liujunfeng on 2021/12/4. 10 | */ 11 | @AppOwner 12 | @HiltAndroidApp 13 | class LoginApplication : FluxApp() { 14 | } 15 | -------------------------------------------------------------------------------- /module-login/src/library/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /module-login/src/main/java/com/huyingbao/module/login/app/LoginAppModule.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.login.app 2 | 3 | import com.huyingbao.module.login.BuildConfig 4 | import dagger.Module 5 | import dagger.Provides 6 | import dagger.hilt.InstallIn 7 | import dagger.hilt.components.SingletonComponent 8 | import okhttp3.OkHttpClient 9 | import retrofit2.Retrofit 10 | import retrofit2.converter.gson.GsonConverterFactory 11 | import javax.inject.Named 12 | import javax.inject.Singleton 13 | 14 | /** 15 | * Created by liujunfeng on 2021/12/4. 16 | */ 17 | @Module 18 | @InstallIn(SingletonComponent::class) 19 | object LoginAppModule { 20 | /** 21 | * Api根路径 22 | */ 23 | const val BASE_API = "https://www.wanandroid.com/" 24 | 25 | /** 26 | * 提供[Retrofit]单例对象 27 | * 28 | * 每个子模块的Module中都提供[Retrofit]单例对象,使用[Named]注解,子模块提供的单例对象。 29 | */ 30 | @Singleton 31 | @Provides 32 | @Named(BuildConfig.MODULE_NAME) 33 | fun provideRetrofit(builder: OkHttpClient.Builder): Retrofit { 34 | return Retrofit.Builder() 35 | .baseUrl(BASE_API) 36 | .addConverterFactory(GsonConverterFactory.create()) 37 | .client(builder.build()) 38 | .build() 39 | } 40 | } -------------------------------------------------------------------------------- /module-login/src/main/java/com/huyingbao/module/login/ui/LoginActivity.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.login.ui 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.compose.material.MaterialTheme 7 | import androidx.compose.material.Surface 8 | import androidx.compose.material.Text 9 | import androidx.compose.runtime.Composable 10 | import androidx.compose.ui.tooling.preview.Preview 11 | import com.huyingbao.module.login.ui.ui.theme.RxFluxArchitectureTheme 12 | 13 | class LoginActivity : ComponentActivity() { 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContent { 17 | RxFluxArchitectureTheme { 18 | // A surface container using the 'background' color from the theme 19 | Surface(color = MaterialTheme.colors.background) { 20 | Greeting("Android") 21 | } 22 | } 23 | } 24 | } 25 | } 26 | 27 | @Composable 28 | fun Greeting(name: String) { 29 | Text(text = "Hello $name!") 30 | } 31 | 32 | @Preview(showBackground = true) 33 | @Composable 34 | fun DefaultPreview() { 35 | RxFluxArchitectureTheme { 36 | Greeting("Android") 37 | } 38 | } -------------------------------------------------------------------------------- /module-login/src/main/java/com/huyingbao/module/login/ui/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.login.ui.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple200 = Color(0xFFBB86FC) 6 | val Purple500 = Color(0xFF6200EE) 7 | val Purple700 = Color(0xFF3700B3) 8 | val Teal200 = Color(0xFF03DAC5) -------------------------------------------------------------------------------- /module-login/src/main/java/com/huyingbao/module/login/ui/ui/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.login.ui.ui.theme 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.material.Shapes 5 | import androidx.compose.ui.unit.dp 6 | 7 | val Shapes = Shapes( 8 | small = RoundedCornerShape(4.dp), 9 | medium = RoundedCornerShape(4.dp), 10 | large = RoundedCornerShape(0.dp) 11 | ) -------------------------------------------------------------------------------- /module-login/src/main/java/com/huyingbao/module/login/ui/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.login.ui.ui.theme 2 | 3 | import androidx.compose.foundation.isSystemInDarkTheme 4 | import androidx.compose.material.MaterialTheme 5 | import androidx.compose.material.darkColors 6 | import androidx.compose.material.lightColors 7 | import androidx.compose.runtime.Composable 8 | 9 | private val DarkColorPalette = darkColors( 10 | primary = Purple200, 11 | primaryVariant = Purple700, 12 | secondary = Teal200 13 | ) 14 | 15 | private val LightColorPalette = lightColors( 16 | primary = Purple500, 17 | primaryVariant = Purple700, 18 | secondary = Teal200 19 | 20 | /* Other default colors to override 21 | background = Color.White, 22 | surface = Color.White, 23 | onPrimary = Color.White, 24 | onSecondary = Color.Black, 25 | onBackground = Color.Black, 26 | onSurface = Color.Black, 27 | */ 28 | ) 29 | 30 | @Composable 31 | fun RxFluxArchitectureTheme( 32 | darkTheme: Boolean = isSystemInDarkTheme(), 33 | content: @Composable() () -> Unit 34 | ) { 35 | val colors = if (darkTheme) { 36 | DarkColorPalette 37 | } else { 38 | LightColorPalette 39 | } 40 | 41 | MaterialTheme( 42 | colors = colors, 43 | typography = Typography, 44 | shapes = Shapes, 45 | content = content 46 | ) 47 | } -------------------------------------------------------------------------------- /module-login/src/main/java/com/huyingbao/module/login/ui/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package com.huyingbao.module.login.ui.ui.theme 2 | 3 | import androidx.compose.material.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.FontFamily 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.unit.sp 8 | 9 | // Set of Material typography styles to start with 10 | val Typography = Typography( 11 | body1 = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp 15 | ) 16 | /* Other default text styles to override 17 | button = TextStyle( 18 | fontFamily = FontFamily.Default, 19 | fontWeight = FontWeight.W500, 20 | fontSize = 14.sp 21 | ), 22 | caption = TextStyle( 23 | fontFamily = FontFamily.Default, 24 | fontWeight = FontWeight.Normal, 25 | fontSize = 12.sp 26 | ) 27 | */ 28 | ) -------------------------------------------------------------------------------- /module-login/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | LoginActivity 3 | -------------------------------------------------------------------------------- /module-login/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 |