├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CONTRIBUTING_APP.md ├── LICENSE ├── MVPArms.md ├── MVP_generator_solution ├── README.md ├── arms-autolayout ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── jess │ │ └── arms │ │ └── widget │ │ └── autolayout │ │ ├── AutoAppBarLayout.java │ │ ├── AutoCardView.java │ │ ├── AutoCollapsingToolbarLayout.java │ │ ├── AutoRadioGroup.java │ │ ├── AutoScrollView.java │ │ ├── AutoTabLayout.java │ │ └── AutoToolbar.java │ └── res │ └── values │ ├── attrs.xml │ └── strings.xml ├── arms-imageloader-glide ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── jess │ │ └── arms │ │ └── http │ │ └── imageloader │ │ └── glide │ │ ├── BlurTransformation.java │ │ ├── CacheStrategy.java │ │ ├── GlideImageLoaderStrategy.java │ │ └── ImageConfigImpl.java │ └── res │ └── values │ └── strings.xml ├── arms ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── jess │ │ └── arms │ │ ├── base │ │ ├── AdapterViewPager.java │ │ ├── App.java │ │ ├── BaseActivity.java │ │ ├── BaseApplication.java │ │ ├── BaseFragment.java │ │ ├── BaseHolder.java │ │ ├── BaseLazyLoadFragment.java │ │ ├── BaseService.java │ │ ├── DefaultAdapter.java │ │ ├── Platform.java │ │ ├── Unused.java │ │ └── delegate │ │ │ ├── ActivityDelegate.java │ │ │ ├── ActivityDelegateImpl.java │ │ │ ├── AppDelegate.java │ │ │ ├── AppLifecycles.java │ │ │ ├── FragmentDelegate.java │ │ │ ├── FragmentDelegateImpl.java │ │ │ ├── IActivity.java │ │ │ └── IFragment.java │ │ ├── di │ │ ├── component │ │ │ └── AppComponent.java │ │ ├── module │ │ │ ├── AppModule.java │ │ │ ├── ClientModule.java │ │ │ └── GlobalConfigModule.java │ │ └── scope │ │ │ ├── ActivityScope.java │ │ │ └── FragmentScope.java │ │ ├── http │ │ ├── BaseUrl.java │ │ ├── GlobalHttpHandler.java │ │ ├── OkHttpStreamFetcher.java │ │ ├── OkHttpUrlLoader.java │ │ ├── imageloader │ │ │ ├── BaseImageLoaderStrategy.java │ │ │ ├── ImageConfig.java │ │ │ ├── ImageLoader.java │ │ │ └── glide │ │ │ │ ├── GlideAppliesOptions.java │ │ │ │ └── GlideConfiguration.java │ │ └── log │ │ │ ├── DefaultFormatPrinter.java │ │ │ ├── FormatPrinter.java │ │ │ └── RequestInterceptor.java │ │ ├── integration │ │ ├── ActivityLifecycle.java │ │ ├── AppManager.java │ │ ├── ConfigModule.java │ │ ├── EventBusManager.java │ │ ├── FragmentLifecycle.java │ │ ├── IRepositoryManager.java │ │ ├── ManifestParser.java │ │ ├── RepositoryManager.java │ │ ├── RetrofitServiceProxyHandler.java │ │ ├── cache │ │ │ ├── Cache.java │ │ │ ├── CacheType.java │ │ │ ├── IntelligentCache.java │ │ │ └── LruCache.java │ │ └── lifecycle │ │ │ ├── ActivityLifecycleForRxLifecycle.java │ │ │ ├── ActivityLifecycleable.java │ │ │ ├── FragmentLifecycleForRxLifecycle.java │ │ │ ├── FragmentLifecycleable.java │ │ │ └── Lifecycleable.java │ │ ├── mvp │ │ ├── BaseModel.java │ │ ├── BasePresenter.java │ │ ├── IModel.java │ │ ├── IPresenter.java │ │ └── IView.java │ │ ├── utils │ │ ├── ArmsUtils.java │ │ ├── CharacterHandler.java │ │ ├── DataHelper.java │ │ ├── DeviceUtils.java │ │ ├── DrawableProvider.java │ │ ├── FastBlur.java │ │ ├── LogUtils.java │ │ ├── PermissionUtil.java │ │ ├── Preconditions.java │ │ ├── RxLifecycleUtils.java │ │ ├── ThirdViewUtil.java │ │ ├── UrlEncoderUtils.java │ │ └── ZipHelper.java │ │ └── widget │ │ └── CustomPopupWindow.java │ └── res │ └── values │ └── strings.xml ├── bintray.gradle ├── build.gradle ├── config.gradle ├── demo ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── jessyan │ │ └── mvparms │ │ └── demo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── me │ │ │ └── jessyan │ │ │ └── mvparms │ │ │ └── demo │ │ │ ├── app │ │ │ ├── ActivityLifecycleCallbacksImpl.java │ │ │ ├── AppLifecyclesImpl.java │ │ │ ├── EventBusTags.java │ │ │ ├── FragmentLifecycleCallbacksImpl.java │ │ │ ├── GlobalConfiguration.java │ │ │ ├── GlobalHttpHandlerImpl.java │ │ │ ├── ResponseErrorListenerImpl.java │ │ │ ├── service │ │ │ │ └── DemoService.java │ │ │ └── utils │ │ │ │ └── RxUtils.java │ │ │ ├── di │ │ │ ├── component │ │ │ │ └── UserComponent.java │ │ │ └── module │ │ │ │ └── UserModule.java │ │ │ └── mvp │ │ │ ├── contract │ │ │ └── UserContract.java │ │ │ ├── model │ │ │ ├── UserModel.java │ │ │ ├── api │ │ │ │ ├── Api.java │ │ │ │ ├── cache │ │ │ │ │ └── CommonCache.java │ │ │ │ └── service │ │ │ │ │ ├── CommonService.java │ │ │ │ │ └── UserService.java │ │ │ └── entity │ │ │ │ ├── BaseResponse.java │ │ │ │ └── User.java │ │ │ ├── presenter │ │ │ └── UserPresenter.java │ │ │ └── ui │ │ │ ├── activity │ │ │ └── UserActivity.java │ │ │ ├── adapter │ │ │ └── UserAdapter.java │ │ │ └── holder │ │ │ └── UserItemHolder.java │ └── res │ │ ├── anim │ │ ├── translate_center_to_left.xml │ │ ├── translate_center_to_right.xml │ │ ├── translate_left_to_center.xml │ │ └── translate_right_to_center.xml │ │ ├── layout │ │ ├── activity_user.xml │ │ ├── include_title.xml │ │ └── recycle_list.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ ├── ic_arrow_back_white_24dp.png │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ ├── arms_logo.png │ │ ├── ic_arrow_back_white_24dp.png │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_arrow_back_white_24dp.png │ │ └── ic_launcher.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── me │ └── jessyan │ └── mvparms │ └── demo │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── image ├── ApplicationArchitecture.jpg ├── Architecture.png ├── android_logo.png ├── arms_banner_v1.0.jpg ├── hui_cai_fu_logo.png ├── mi_lu_logo.png ├── mi_wo_logo.png ├── official.jpeg ├── package.png ├── shaimobao_logo.png ├── step_1.png ├── step_2.png ├── tianfutong_logo.png ├── tiantian_live_logo.png ├── tiantian_video_logo.png ├── tong_hang_logo.png ├── top_net_work_logo.png ├── xiang_yun_logo.png ├── xiaoding_foreman_logo.png ├── xiaoding_material_logo.png ├── xiaoding_worker_logo.png └── zhibo_logo.png └── settings.gradle /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Look at here 2 | 3 | - → Did you conform to the [Rules](https://github.com/JessYanCoding/MVPArms/issues/150)? 4 | - → Did you read the [Wiki](https://github.com/JessYanCoding/MVPArms/wiki) **Carefully**? 5 | - → Did you search in Google? 6 | - → Did you search in openned&closed Issues? 7 | - → **Receive only bugs and suggestions** 8 | 9 | ### Environment 10 | 11 | - [x] MVPArms Version: 12 | - [x] AndroidStudio Version: 13 | - [x] Gradle Plugin Version: 14 | - [x] Target Android Version: 15 | - [x] Device Model: 16 | 17 | 18 | ### Bug Description: 19 | 20 | 21 | 22 | ### Related Code: 23 | ```java 24 | 25 | 26 | ``` 27 | 28 | ### Bug Log: 29 | ```log 30 | 31 | 32 | ``` 33 | 34 | ### Others: 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea 38 | 39 | # Keystore files 40 | *.jks 41 | 42 | # MacOS 43 | .DS_Store 44 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk8 3 | before_install: 4 | - yes | sdkmanager "platforms;android-28" 5 | 6 | env: 7 | global: 8 | - ANDROID_API_LEVEL=28 9 | - ANDROID_BUILD_TOOLS_VERSION=28.0.3 10 | - TRAVIS_SECURE_ENV_VARS=true 11 | 12 | android: 13 | components: 14 | # The BuildTools version used by your project 15 | - tools 16 | - platform-tools 17 | - build-tools-$ANDROID_BUILD_TOOLS_VERSION 18 | - extra-android-m2repository 19 | - extra-google-android-support 20 | 21 | # The SDK version used to compile your project 22 | - android-$ANDROID_API_LEVEL 23 | licenses: 24 | - '.+' 25 | 26 | script: 27 | - ./gradlew clean 28 | # - ./gradlew install 29 | # - ./gradlew bintrayUpload 30 | - ./gradlew assembleDebug -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | [UpdateLog](https://github.com/JessYanCoding/MVPArms/wiki/UpdateLog) -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting jess.yan.effort@gmail.com. All complaints will be reviewed and investigated and will result in a response that 59 | is deemed necessary and appropriate to the circumstances. The project team is 60 | obligated to maintain confidentiality with regard to the reporter of an incident. 61 | Further details of specific enforcement policies may be posted separately. 62 | 63 | Project maintainers who do not follow or enforce the Code of Conduct in good 64 | faith may face temporary or permanent repercussions as determined by other 65 | members of the project's leadership. 66 | 67 | ## Attribution 68 | 69 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 70 | available at [http://contributor-covenant.org/version/1/4][version] 71 | 72 | [homepage]: http://contributor-covenant.org 73 | [version]: http://contributor-covenant.org/version/1/4/ 74 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | If you would like to contribute code you can do so through GitHub by forking the repository and sending a pull request targeting the branch `master`. 3 | 4 | When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible. 5 | 6 | ## License 7 | 8 | By contributing your code, you agree to license your contribution under the terms of the APLv2: https://github.com/JessYanCoding/MVPArms/blob/master/LICENSE 9 | 10 | All files are released with the Apache 2.0 license. 11 | 12 | If you are adding a new file it should have a header like this: 13 | 14 | ``` 15 | /* 16 | * Copyright 2018 JessYan 17 | * 18 | * Licensed under the Apache License, Version 2.0 (the "License"); 19 | * you may not use this file except in compliance with the License. 20 | * You may obtain a copy of the License at 21 | * 22 | * http://www.apache.org/licenses/LICENSE-2.0 23 | * 24 | * Unless required by applicable law or agreed to in writing, software 25 | * distributed under the License is distributed on an "AS IS" BASIS, 26 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 27 | * See the License for the specific language governing permissions and 28 | * limitations under the License. 29 | */ 30 | ``` -------------------------------------------------------------------------------- /CONTRIBUTING_APP.md: -------------------------------------------------------------------------------- 1 | **如果您使用或基于 MVPArms 开发过开源的 APP 或者 Framework, 恳请您将项目地址 [Pull Request](https://github.com/JessYanCoding/MVPArms/pull/new/master) 到这个页面, 方便更多人学习的同时, 也能为您的开源项目引入更多的流量, 也衷心的希望大家在学习 MVPArms 获得自我提升的同时, 也能帮助其他朋友更快的成长, 将开源精神传递下去!** 2 | 3 | **同时您也可以给自己的开源项目打上 mvparms 的标签,这样大家就能在 [Topics](https://github.com/topics/mvparms) 中找到您的开源项目** 4 | 5 | > **Tips: 以下项目并不能百分百保证完全按照框架的正规流程和正确配置, 大家可以作为参考, 但主要还是以官方 Demo 为准** 6 | 7 | 8 | ### App 9 | #### Kotlin 10 | * [**养眼** : 这是一个基于 **MVPArms** 使用 **kotlin** 开发的 **看图 App** (**程序媛建议路过**) ](https://github.com/miaoMiaoDaShi/YangYanNew) 11 | * [**NoblesSpiritsKotlin** : 这是一个基于 **MVPArms** 使用 **kotlin** 开发的 **Mall App**](https://github.com/haife/NoblesSpiritsKotlin) 12 | 13 | #### Java 14 | * [**Hands-Chopping** : 这是一个基于 **MVPArms + ArmsComponent** 开发的包含 **Steam** 和 **杉果** 的组件化客户端](https://github.com/noterpopo/Hands-Chopping) 15 | * [**YeLearns** : 这是一个基于 **MVPArms** 开发的包含 **玩安卓、DIYcode、干货、微信资讯、游明星空** 等多个模块的客户端](https://github.com/yeyueduxing/YeLearns) 16 | * [**LQRBiliBlili** : 这是一个基于 **MVPArms** 开发的高仿 **bilibili** 安卓客户端 (**!!!请注意, 此项目在 GlobalConfiguration 中的部分配置是不正确的, 特别是对 Retrofit 的配置, 如非特殊需求, 请不要再一次给 Retrofit 设置新的 OkHttpClient, 框架内部已提供有 OkHttpClient, 请以官方 Demo 为准**)](https://github.com/GitLqr/LQRBiliBlili) 17 | * [**DiyCode** : 这是一个基于 **MVPArms** 开发的 **DiyCode** 社区客户端](https://github.com/linsneider/DiyCodeAndroid) 18 | * [**Ganamrs** : 这是一个基于 **MVPArms** 开发的 **Gank** 开源客户端](https://github.com/lianhuo/Ganamrs) 19 | * [**P2P** : 这是一个基于 **MVPArms** 开发的 **金融** 客户端](https://github.com/Everglowzz/P2P) 20 | * [**ZackShop** : 这是一个基于 **MVPArms** 开发的 **仿京东** 客户端](https://github.com/zhangqian666/shop-front-android) 21 | 22 | ### Framework 23 | * [**MVPFrames** : 这个项目是将 **MVPArms** 框架和 **MVPArt** 框架合并成一个通用型项目, 并增加了数据库](https://github.com/DesignQu/MVPFrames) 24 | * [**MVVMArms** : Android MVVM Architecture Components based on **MVPArms** and **Android Architecture Components**.](https://github.com/xiaobailong24/MVVMArms) 25 | * [**smartframework-android-atlas** : 这是一个将 **MVPArms** 框架和 **Atlas** 框架相结合的组件化 **MVP** 框架](https://github.com/smarthane/smartframework-android-atlas) 26 | * [**smartframework-android** : 这是一个将 **MVPArms** 框架和 **VirtualAPK** 框架相结合的插件化 **MVP** 框架](https://github.com/smarthane/smartframework-android) 27 | * [**Atoms-mvp** : 这是一个参考 **MVPArms** 框架, 将自己对框架的理解相结合的 **MVP** 框架](https://github.com/xwc520/Atoms-mvp) 28 | 29 | -------------------------------------------------------------------------------- /arms-autolayout/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /arms-autolayout/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.android["compileSdkVersion"] 5 | buildToolsVersion rootProject.ext.android["buildToolsVersion"] 6 | 7 | defaultConfig { 8 | minSdkVersion rootProject.ext.android["minSdkVersion"] 9 | targetSdkVersion rootProject.ext.android["targetSdkVersion"] 10 | versionCode rootProject.ext.android["versionCode"] 11 | versionName rootProject.ext.android["versionName"] 12 | } 13 | 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | } 22 | 23 | dependencies { 24 | compileOnly rootProject.ext.dependencies["appcompat"] 25 | compileOnly rootProject.ext.dependencies["annotations"] 26 | api(rootProject.ext.dependencies["design"]) { 27 | exclude module: 'annotation' 28 | exclude module: 'appcompat' 29 | exclude module: 'legacy-support-v4' 30 | exclude module: 'recyclerview' 31 | } 32 | api(rootProject.ext.dependencies["cardview"]) { 33 | exclude module: 'annotation' 34 | } 35 | api(rootProject.ext.dependencies["autolayout"]) { 36 | exclude module: 'recyclerview' 37 | exclude module: 'appcompat' 38 | exclude module: 'vectordrawable-animated' 39 | } 40 | } 41 | 42 | apply from: '../bintray.gradle' -------------------------------------------------------------------------------- /arms-autolayout/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=MVPArms-AndroidAutoLayout 2 | -------------------------------------------------------------------------------- /arms-autolayout/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 | -------------------------------------------------------------------------------- /arms-autolayout/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /arms-autolayout/src/main/java/com/jess/arms/widget/autolayout/AutoAppBarLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.widget.autolayout; 17 | 18 | import android.content.Context; 19 | import android.util.AttributeSet; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | 23 | import com.google.android.material.appbar.AppBarLayout; 24 | import com.zhy.autolayout.AutoLayoutInfo; 25 | import com.zhy.autolayout.utils.AutoLayoutHelper; 26 | 27 | /** 28 | * ================================================ 29 | * 实现 AndroidAutoLayout 规范的 {@link AppBarLayout} 30 | * 可使用 MVP_generator_solution 中的 AutoView 模版生成各种符合 AndroidAutoLayout 规范的 {@link View} 31 | * 32 | * @see AutoLayout wiki 官方文档 33 | * Created by JessYan on 4/14/2016 34 | * Contact me 35 | * Follow me 36 | * ================================================ 37 | */ 38 | public class AutoAppBarLayout extends AppBarLayout { 39 | 40 | private AutoLayoutHelper mHelper = new AutoLayoutHelper(this); 41 | 42 | public AutoAppBarLayout(Context context) { 43 | super(context); 44 | } 45 | 46 | public AutoAppBarLayout(Context context, AttributeSet attrs) { 47 | super(context, attrs); 48 | } 49 | 50 | @Override 51 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 52 | if (!isInEditMode()) { 53 | mHelper.adjustChildren(); 54 | } 55 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 56 | } 57 | 58 | @Override 59 | protected void onLayout(boolean changed, int l, int t, int r, int b) { 60 | super.onLayout(changed, l, t, r, b); 61 | } 62 | 63 | @Override 64 | public LayoutParams generateLayoutParams(AttributeSet attrs) { 65 | return new LayoutParams(getContext(), attrs); 66 | } 67 | 68 | public static class LayoutParams extends AppBarLayout.LayoutParams 69 | implements AutoLayoutHelper.AutoLayoutParams { 70 | private AutoLayoutInfo mAutoLayoutInfo; 71 | 72 | public LayoutParams(Context c, AttributeSet attrs) { 73 | super(c, attrs); 74 | mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); 75 | } 76 | 77 | public LayoutParams(int width, int height) { 78 | super(width, height); 79 | } 80 | 81 | public LayoutParams(ViewGroup.LayoutParams source) { 82 | super(source); 83 | } 84 | 85 | public LayoutParams(ViewGroup.MarginLayoutParams source) { 86 | super(source); 87 | } 88 | 89 | @Override 90 | public AutoLayoutInfo getAutoLayoutInfo() { 91 | return mAutoLayoutInfo; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /arms-autolayout/src/main/java/com/jess/arms/widget/autolayout/AutoCardView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.widget.autolayout; 17 | 18 | import android.content.Context; 19 | import android.util.AttributeSet; 20 | import android.view.View; 21 | 22 | import androidx.cardview.widget.CardView; 23 | 24 | import com.zhy.autolayout.AutoFrameLayout; 25 | import com.zhy.autolayout.utils.AutoLayoutHelper; 26 | 27 | /** 28 | * ================================================ 29 | * 实现 AndroidAutoLayout 规范的 {@link CardView} 30 | * 可使用 MVP_generator_solution 中的 AutoView 模版生成各种符合 AndroidAutoLayout 规范的 {@link View} 31 | * 32 | * @see AutoLayout wiki 官方文档 33 | * Created by JessYan on 9/3/16 21:40 34 | * Contact me 35 | * Follow me 36 | * ================================================ 37 | */ 38 | public class AutoCardView extends CardView { 39 | private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this); 40 | 41 | public AutoCardView(Context context) { 42 | super(context); 43 | } 44 | 45 | public AutoCardView(Context context, AttributeSet attrs) { 46 | super(context, attrs); 47 | } 48 | 49 | public AutoCardView(Context context, AttributeSet attrs, int defStyleAttr) { 50 | super(context, attrs, defStyleAttr); 51 | } 52 | 53 | @Override 54 | public AutoFrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) { 55 | return new AutoFrameLayout.LayoutParams(getContext(), attrs); 56 | } 57 | 58 | @Override 59 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 60 | if (!isInEditMode()) { 61 | mHelper.adjustChildren(); 62 | } 63 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 64 | } 65 | } -------------------------------------------------------------------------------- /arms-autolayout/src/main/java/com/jess/arms/widget/autolayout/AutoCollapsingToolbarLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.widget.autolayout; 17 | 18 | import android.content.Context; 19 | import android.util.AttributeSet; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | 23 | import com.google.android.material.appbar.CollapsingToolbarLayout; 24 | import com.zhy.autolayout.AutoLayoutInfo; 25 | import com.zhy.autolayout.utils.AutoLayoutHelper; 26 | 27 | /** 28 | * ================================================ 29 | * 实现 AndroidAutoLayout 规范的 {@link CollapsingToolbarLayout} 30 | * 可使用 MVP_generator_solution 中的 AutoView 模版生成各种符合 AndroidAutoLayout 规范的 {@link View} 31 | * 32 | * @see AutoLayout wiki 官方文档 33 | * Created by JessYan on 4/14/2016 34 | * Contact me 35 | * Follow me 36 | * ================================================ 37 | */ 38 | public class AutoCollapsingToolbarLayout extends CollapsingToolbarLayout { 39 | private AutoLayoutHelper mHelper = new AutoLayoutHelper(this); 40 | 41 | public AutoCollapsingToolbarLayout(Context context) { 42 | super(context); 43 | } 44 | 45 | public AutoCollapsingToolbarLayout(Context context, AttributeSet attrs) { 46 | super(context, attrs); 47 | } 48 | 49 | public AutoCollapsingToolbarLayout(Context context, AttributeSet attrs, int defStyleAttr) { 50 | super(context, attrs, defStyleAttr); 51 | } 52 | 53 | @Override 54 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 55 | if (!isInEditMode()) { 56 | mHelper.adjustChildren(); 57 | } 58 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 59 | } 60 | 61 | @Override 62 | protected void onLayout(boolean changed, int l, int t, int r, int b) { 63 | super.onLayout(changed, l, t, r, b); 64 | } 65 | 66 | @Override 67 | public LayoutParams generateLayoutParams(AttributeSet attrs) { 68 | return new LayoutParams(getContext(), attrs); 69 | } 70 | 71 | public static class LayoutParams extends CollapsingToolbarLayout.LayoutParams 72 | implements AutoLayoutHelper.AutoLayoutParams { 73 | private AutoLayoutInfo mAutoLayoutInfo; 74 | 75 | public LayoutParams(Context c, AttributeSet attrs) { 76 | super(c, attrs); 77 | mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); 78 | } 79 | 80 | public LayoutParams(int width, int height) { 81 | super(width, height); 82 | } 83 | 84 | public LayoutParams(ViewGroup.LayoutParams source) { 85 | super(source); 86 | } 87 | 88 | public LayoutParams(ViewGroup.MarginLayoutParams source) { 89 | super(source); 90 | } 91 | 92 | @Override 93 | public AutoLayoutInfo getAutoLayoutInfo() { 94 | return mAutoLayoutInfo; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /arms-autolayout/src/main/java/com/jess/arms/widget/autolayout/AutoRadioGroup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.widget.autolayout; 17 | 18 | import android.content.Context; 19 | import android.util.AttributeSet; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | import android.widget.RadioGroup; 23 | 24 | import com.zhy.autolayout.AutoLayoutInfo; 25 | import com.zhy.autolayout.utils.AutoLayoutHelper; 26 | 27 | /** 28 | * ================================================ 29 | * 实现 AndroidAutoLayout 规范的 {@link RadioGroup} 30 | * 可使用 MVP_generator_solution 中的 AutoView 模版生成各种符合 AndroidAutoLayout 规范的 {@link View} 31 | * 32 | * @see AutoLayout wiki 官方文档 33 | * Created by JessYan on 9/3/16 21:40 34 | * Contact me 35 | * Follow me 36 | * ================================================ 37 | */ 38 | public class AutoRadioGroup extends RadioGroup { 39 | private AutoLayoutHelper mHelper = new AutoLayoutHelper(this); 40 | 41 | public AutoRadioGroup(Context context) { 42 | super(context); 43 | } 44 | 45 | public AutoRadioGroup(Context context, AttributeSet attrs) { 46 | super(context, attrs); 47 | } 48 | 49 | @Override 50 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 51 | if (!isInEditMode()) { 52 | mHelper.adjustChildren(); 53 | } 54 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 55 | } 56 | 57 | @Override 58 | protected void onLayout(boolean changed, int l, int t, int r, int b) { 59 | super.onLayout(changed, l, t, r, b); 60 | } 61 | 62 | @Override 63 | public LayoutParams generateLayoutParams(AttributeSet attrs) { 64 | return new LayoutParams(getContext(), attrs); 65 | } 66 | 67 | public static class LayoutParams extends RadioGroup.LayoutParams 68 | implements AutoLayoutHelper.AutoLayoutParams { 69 | private AutoLayoutInfo mAutoLayoutInfo; 70 | 71 | public LayoutParams(Context c, AttributeSet attrs) { 72 | super(c, attrs); 73 | mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); 74 | } 75 | 76 | public LayoutParams(int width, int height) { 77 | super(width, height); 78 | } 79 | 80 | public LayoutParams(ViewGroup.LayoutParams source) { 81 | super(source); 82 | } 83 | 84 | public LayoutParams(MarginLayoutParams source) { 85 | super(source); 86 | } 87 | 88 | @Override 89 | public AutoLayoutInfo getAutoLayoutInfo() { 90 | return mAutoLayoutInfo; 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /arms-autolayout/src/main/java/com/jess/arms/widget/autolayout/AutoScrollView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.widget.autolayout; 17 | 18 | import android.content.Context; 19 | import android.util.AttributeSet; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | import android.widget.ScrollView; 23 | 24 | import androidx.annotation.Nullable; 25 | 26 | import com.zhy.autolayout.AutoLayoutInfo; 27 | import com.zhy.autolayout.utils.AutoLayoutHelper; 28 | 29 | /** 30 | * ================================================ 31 | * 实现 AndroidAutoLayout 规范的 {@link ScrollView} 32 | * 可使用 MVP_generator_solution 中的 AutoView 模版生成各种符合 AndroidAutoLayout 规范的 {@link View} 33 | * 34 | * @see AutoLayout wiki 官方文档 35 | * Created by JessYan on 4/14/2016 36 | * Contact me 37 | * Follow me 38 | * ================================================ 39 | */ 40 | public class AutoScrollView extends ScrollView { 41 | private AutoLayoutHelper mHelper = new AutoLayoutHelper(this); 42 | 43 | public AutoScrollView(Context context) { 44 | super(context); 45 | } 46 | 47 | public AutoScrollView(Context context, @Nullable AttributeSet attrs) { 48 | super(context, attrs); 49 | } 50 | 51 | public AutoScrollView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 52 | super(context, attrs, defStyleAttr); 53 | } 54 | 55 | @Override 56 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 57 | if (!isInEditMode()) { 58 | mHelper.adjustChildren(); 59 | } 60 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 61 | } 62 | 63 | @Override 64 | protected void onLayout(boolean changed, int l, int t, int r, int b) { 65 | super.onLayout(changed, l, t, r, b); 66 | } 67 | 68 | @Override 69 | public LayoutParams generateLayoutParams(AttributeSet attrs) { 70 | return new LayoutParams(getContext(), attrs); 71 | } 72 | 73 | public static class LayoutParams extends ScrollView.LayoutParams 74 | implements AutoLayoutHelper.AutoLayoutParams { 75 | private AutoLayoutInfo mAutoLayoutInfo; 76 | 77 | public LayoutParams(Context c, AttributeSet attrs) { 78 | super(c, attrs); 79 | mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); 80 | } 81 | 82 | public LayoutParams(int width, int height) { 83 | super(width, height); 84 | } 85 | 86 | public LayoutParams(ViewGroup.LayoutParams source) { 87 | super(source); 88 | } 89 | 90 | public LayoutParams(MarginLayoutParams source) { 91 | super(source); 92 | } 93 | 94 | @Override 95 | public AutoLayoutInfo getAutoLayoutInfo() { 96 | return mAutoLayoutInfo; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /arms-autolayout/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /arms-autolayout/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | arms-autolayout 3 | 4 | -------------------------------------------------------------------------------- /arms-imageloader-glide/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /arms-imageloader-glide/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.android["compileSdkVersion"] 5 | buildToolsVersion rootProject.ext.android["buildToolsVersion"] 6 | 7 | defaultConfig { 8 | minSdkVersion rootProject.ext.android["minSdkVersion"] 9 | targetSdkVersion rootProject.ext.android["targetSdkVersion"] 10 | versionCode rootProject.ext.android["versionCode"] 11 | versionName rootProject.ext.android["versionName"] 12 | } 13 | 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | } 22 | 23 | dependencies { 24 | api(rootProject.ext.dependencies["glide"]) { 25 | exclude module: 'annotation' 26 | exclude module: 'fragment' 27 | exclude module: 'vectordrawable-animated' 28 | } 29 | compileOnly project(':arms') 30 | } 31 | 32 | apply from: '../bintray.gradle' -------------------------------------------------------------------------------- /arms-imageloader-glide/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=MVPArms-ImageLoader-Glide 2 | -------------------------------------------------------------------------------- /arms-imageloader-glide/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 | -------------------------------------------------------------------------------- /arms-imageloader-glide/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /arms-imageloader-glide/src/main/java/com/jess/arms/http/imageloader/glide/BlurTransformation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.http.imageloader.glide; 17 | 18 | import android.graphics.Bitmap; 19 | 20 | import androidx.annotation.IntRange; 21 | import androidx.annotation.NonNull; 22 | 23 | import com.bumptech.glide.load.Key; 24 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; 25 | import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; 26 | import com.jess.arms.utils.FastBlur; 27 | 28 | import java.security.MessageDigest; 29 | 30 | /** 31 | * ================================================ 32 | * 高斯模糊 33 | *

34 | * Created by JessYan on 03/04/2018 15:14 35 | * Contact me 36 | * Follow me 37 | * ================================================ 38 | */ 39 | public class BlurTransformation extends BitmapTransformation { 40 | public static final int DEFAULT_RADIUS = 15; 41 | private static final String ID = BlurTransformation.class.getName(); 42 | private static final byte[] ID_BYTES = ID.getBytes(Key.CHARSET); 43 | private int mRadius; 44 | 45 | public BlurTransformation(@IntRange(from = 0) int radius) { 46 | mRadius = radius; 47 | } 48 | 49 | @Override 50 | public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) { 51 | messageDigest.update(ID_BYTES); 52 | 53 | } 54 | 55 | @Override 56 | protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { 57 | return FastBlur.doBlur(toTransform, mRadius, true); 58 | } 59 | 60 | @Override 61 | public boolean equals(Object o) { 62 | return o instanceof BlurTransformation; 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | return ID.hashCode(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /arms-imageloader-glide/src/main/java/com/jess/arms/http/imageloader/glide/CacheStrategy.java: -------------------------------------------------------------------------------- 1 | package com.jess.arms.http.imageloader.glide; 2 | 3 | import androidx.annotation.IntDef; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | 9 | /** 10 | * Incremental change is better than ambitious failure. 11 | * 12 | * @author : MysticCoder 13 | * @date : 2019/4/29 14 | * @desc :0对应DiskCacheStrategy.all,1对应DiskCacheStrategy.NONE,2对应DiskCacheStrategy.SOURCE,3对应DiskCacheStrategy.RESULT 15 | * see {@link com.bumptech.glide.load.engine.DiskCacheStrategy} 16 | */ 17 | 18 | public interface CacheStrategy { 19 | 20 | 21 | int ALL = 0; 22 | 23 | int NONE = 1; 24 | 25 | int RESOURCE = 2; 26 | 27 | int DATA = 3; 28 | 29 | int AUTOMATIC = 4; 30 | 31 | @IntDef({ALL, NONE, RESOURCE, DATA, AUTOMATIC}) 32 | @Retention(RetentionPolicy.SOURCE) 33 | @interface Strategy { 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /arms-imageloader-glide/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | arms-glide 3 | 4 | -------------------------------------------------------------------------------- /arms/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /arms/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.android["compileSdkVersion"] 5 | buildToolsVersion rootProject.ext.android["buildToolsVersion"] 6 | useLibrary 'org.apache.http.legacy' 7 | 8 | compileOptions { 9 | targetCompatibility JavaVersion.VERSION_1_8 10 | sourceCompatibility JavaVersion.VERSION_1_8 11 | } 12 | 13 | defaultConfig { 14 | minSdkVersion rootProject.ext.android["minSdkVersion"] 15 | targetSdkVersion rootProject.ext.android["targetSdkVersion"] 16 | versionCode rootProject.ext.android["versionCode"] 17 | versionName rootProject.ext.android["versionName"] 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | } 27 | 28 | dependencies { 29 | api(rootProject.ext.dependencies["legacy-support-v4"]) { 30 | exclude module: 'annotation' 31 | exclude module: 'coordinatorlayout' 32 | } 33 | //androidx 34 | api(rootProject.ext.dependencies["appcompat"]) { 35 | exclude module: 'annotation' 36 | } 37 | compileOnly rootProject.ext.dependencies["design"] 38 | api(rootProject.ext.dependencies["recyclerview"]) { 39 | exclude module: 'annotation' 40 | } 41 | api rootProject.ext.dependencies["annotations"] 42 | 43 | //view 44 | compileOnly rootProject.ext.dependencies["autolayout"] 45 | api(rootProject.ext.dependencies["butterknife"]) { 46 | exclude module: 'annotation' 47 | exclude module: 'core' 48 | } 49 | 50 | //rx 51 | api rootProject.ext.dependencies["rxjava2"] 52 | api(rootProject.ext.dependencies["rxandroid2"]) { 53 | exclude module: 'rxjava' 54 | } 55 | api(rootProject.ext.dependencies["rxcache2"]) { 56 | exclude module: 'rxjava' 57 | exclude module: 'dagger' 58 | exclude module: 'api' 59 | } 60 | implementation(rootProject.ext.dependencies["rxcache-jolyglot-gson"]) { 61 | exclude module: 'gson' 62 | } 63 | api(rootProject.ext.dependencies["rxlifecycle2"]) { 64 | exclude module: 'rxjava' 65 | exclude module: 'jsr305' 66 | } 67 | api(rootProject.ext.dependencies["rxlifecycle2-android"]) { 68 | exclude module: 'annotation' 69 | exclude module: 'rxjava' 70 | exclude module: 'rxandroid' 71 | exclude module: 'rxlifecycle' 72 | } 73 | api(rootProject.ext.dependencies["rxpermissions2"]) { 74 | exclude module: 'rxjava' 75 | exclude module: 'annotation' 76 | } 77 | api rootProject.ext.dependencies['rxerrorhandler2'] 78 | 79 | //network 80 | api(rootProject.ext.dependencies["retrofit"]) { 81 | exclude module: 'okhttp' 82 | exclude module: 'okio' 83 | } 84 | implementation(rootProject.ext.dependencies["retrofit-converter-gson"]) { 85 | exclude module: 'gson' 86 | exclude module: 'okhttp' 87 | exclude module: 'okio' 88 | exclude module: 'retrofit' 89 | } 90 | implementation(rootProject.ext.dependencies["retrofit-adapter-rxjava2"]) { 91 | exclude module: 'rxjava' 92 | exclude module: 'okhttp' 93 | exclude module: 'retrofit' 94 | exclude module: 'okio' 95 | } 96 | api rootProject.ext.dependencies["okhttp3"] 97 | compileOnly rootProject.ext.dependencies["glide"] 98 | annotationProcessor(rootProject.ext.dependencies["glide-compiler"]) { 99 | exclude module: 'jsr305' 100 | } 101 | 102 | //tools 103 | compileOnly rootProject.ext.dependencies["javax.annotation"] 104 | api rootProject.ext.dependencies["dagger2"] 105 | annotationProcessor rootProject.ext.dependencies["dagger2-compiler"] 106 | compileOnly rootProject.ext.dependencies["androideventbus"] 107 | compileOnly rootProject.ext.dependencies["eventbus"] 108 | api rootProject.ext.dependencies["gson"] 109 | 110 | //test 111 | api rootProject.ext.dependencies["timber"] 112 | } 113 | 114 | apply from: '../bintray.gradle' -------------------------------------------------------------------------------- /arms/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=MVPArms 2 | -------------------------------------------------------------------------------- /arms/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/AdapterViewPager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base; 17 | 18 | import androidx.fragment.app.Fragment; 19 | import androidx.fragment.app.FragmentManager; 20 | import androidx.fragment.app.FragmentStatePagerAdapter; 21 | 22 | import java.util.List; 23 | 24 | /** 25 | * ================================================ 26 | * 基类 {@link FragmentStatePagerAdapter} 27 | *

28 | * Created by JessYan on 22/03/2016 29 | * Contact me 30 | * Follow me 31 | * ================================================ 32 | */ 33 | public class AdapterViewPager extends FragmentStatePagerAdapter { 34 | private List mList; 35 | private CharSequence[] mTitles; 36 | 37 | public AdapterViewPager(FragmentManager fragmentManager, List list) { 38 | super(fragmentManager); 39 | this.mList = list; 40 | } 41 | 42 | public AdapterViewPager(FragmentManager fragmentManager, List list, CharSequence[] titles) { 43 | super(fragmentManager); 44 | this.mList = list; 45 | this.mTitles = titles; 46 | } 47 | 48 | @Override 49 | public Fragment getItem(int position) { 50 | return mList.get(position); 51 | } 52 | 53 | @Override 54 | public CharSequence getPageTitle(int position) { 55 | if (mTitles != null && position < mTitles.length) { 56 | return mTitles[position]; 57 | } 58 | return super.getPageTitle(position); 59 | } 60 | 61 | @Override 62 | public int getCount() { 63 | return mList.size(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base; 17 | 18 | import androidx.annotation.NonNull; 19 | 20 | import com.jess.arms.di.component.AppComponent; 21 | 22 | /** 23 | * ================================================ 24 | * 框架要求框架中的每个 {@link android.app.Application} 都需要实现此类, 以满足规范 25 | * 26 | * @see BaseApplication 27 | * @see 请配合官方 Wiki 文档学习本框架 28 | * @see 更新日志, 升级必看! 29 | * @see 常见 Issues, 踩坑必看! 30 | * @see MVPArms 官方组件化方案 ArmsComponent, 进阶指南! 31 | * Created by JessYan on 25/04/2017 14:54 32 | * Contact me 33 | * Follow me 34 | * ================================================ 35 | */ 36 | public interface App { 37 | @NonNull 38 | AppComponent getAppComponent(); 39 | } 40 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/BaseApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base; 17 | 18 | import android.app.Application; 19 | import android.content.Context; 20 | 21 | import androidx.annotation.NonNull; 22 | 23 | import com.jess.arms.base.delegate.AppDelegate; 24 | import com.jess.arms.base.delegate.AppLifecycles; 25 | import com.jess.arms.di.component.AppComponent; 26 | import com.jess.arms.utils.ArmsUtils; 27 | import com.jess.arms.utils.Preconditions; 28 | 29 | /** 30 | * ================================================ 31 | * MVPArms 是一个整合了大量主流开源项目的 Android MVP 快速搭建框架, 其中包含 Dagger2、Retrofit、RxJava 以及 32 | * RxLifecycle、RxCache 等 Rx 系三方库, 并且提供 UI 自适应方案, 本框架将它们结合起来, 并全部使用 Dagger2 管理 33 | * 并提供给开发者使用, 使用本框架开发您的项目, 就意味着您已经拥有一个 MVP + Dagger2 + Retrofit + RxJava 项目 34 | * 35 | * @see 请配合官方 Wiki 文档学习本框架 36 | * @see 更新日志, 升级必看! 37 | * @see 常见 Issues, 踩坑必看! 38 | * @see MVPArms 官方组件化方案 ArmsComponent, 进阶指南! 39 | * Created by JessYan on 22/03/2016 40 | * Contact me 41 | * Follow me 42 | * ================================================ 43 | */ 44 | public class BaseApplication extends Application implements App { 45 | private AppLifecycles mAppDelegate; 46 | 47 | /** 48 | * 这里会在 {@link BaseApplication#onCreate} 之前被调用,可以做一些较早的初始化 49 | * 常用于 MultiDex 以及插件化框架的初始化 50 | * 51 | * @param base 52 | */ 53 | @Override 54 | protected void attachBaseContext(Context base) { 55 | super.attachBaseContext(base); 56 | if (mAppDelegate == null) { 57 | this.mAppDelegate = new AppDelegate(base); 58 | } 59 | this.mAppDelegate.attachBaseContext(base); 60 | } 61 | 62 | @Override 63 | public void onCreate() { 64 | super.onCreate(); 65 | if (mAppDelegate != null) { 66 | this.mAppDelegate.onCreate(this); 67 | } 68 | } 69 | 70 | /** 71 | * 在模拟环境中程序终止时会被调用 72 | */ 73 | @Override 74 | public void onTerminate() { 75 | super.onTerminate(); 76 | if (mAppDelegate != null) { 77 | this.mAppDelegate.onTerminate(this); 78 | } 79 | } 80 | 81 | /** 82 | * 将 {@link AppComponent} 返回出去, 供其它地方使用, {@link AppComponent} 接口中声明的方法所返回的实例, 在 {@link #getAppComponent()} 拿到对象后都可以直接使用 83 | * 84 | * @return AppComponent 85 | * @see ArmsUtils#obtainAppComponentFromContext(Context) 可直接获取 {@link AppComponent} 86 | */ 87 | @NonNull 88 | @Override 89 | public AppComponent getAppComponent() { 90 | Preconditions.checkNotNull(mAppDelegate, "%s cannot be null", AppDelegate.class.getName()); 91 | Preconditions.checkState(mAppDelegate instanceof App, "%s must be implements %s", mAppDelegate.getClass().getName(), App.class.getName()); 92 | return ((App) mAppDelegate).getAppComponent(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/BaseHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base; 17 | 18 | import android.view.View; 19 | 20 | import androidx.annotation.NonNull; 21 | import androidx.recyclerview.widget.RecyclerView; 22 | 23 | import com.jess.arms.utils.ThirdViewUtil; 24 | import com.zhy.autolayout.utils.AutoUtils; 25 | 26 | /** 27 | * ================================================ 28 | * 基类 {@link RecyclerView.ViewHolder} 29 | *

30 | * Created by JessYan on 2015/11/24. 31 | * Contact me 32 | * Follow me 33 | * ================================================ 34 | */ 35 | public abstract class BaseHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 36 | protected final String TAG = this.getClass().getSimpleName(); 37 | protected OnViewClickListener mOnViewClickListener = null; 38 | 39 | public BaseHolder(View itemView) { 40 | super(itemView); 41 | //点击事件 42 | itemView.setOnClickListener(this); 43 | //屏幕适配 44 | if (ThirdViewUtil.isUseAutolayout()) { 45 | AutoUtils.autoSize(itemView); 46 | } 47 | //绑定 ButterKnife 48 | ThirdViewUtil.bindTarget(this, itemView); 49 | } 50 | 51 | /** 52 | * 设置数据 53 | * 54 | * @param data 数据 55 | * @param position 在 RecyclerView 中的位置 56 | */ 57 | public abstract void setData(@NonNull T data, int position); 58 | 59 | /** 60 | * 在 Activity 的 onDestroy 中使用 {@link DefaultAdapter#releaseAllHolder(RecyclerView)} 方法 (super.onDestroy() 之前) 61 | * {@link BaseHolder#onRelease()} 才会被调用, 可以在此方法中释放一些资源 62 | */ 63 | protected void onRelease() { 64 | 65 | } 66 | 67 | @Override 68 | public void onClick(View view) { 69 | if (mOnViewClickListener != null) { 70 | mOnViewClickListener.onViewClick(view, this.getPosition()); 71 | } 72 | } 73 | 74 | public void setOnItemClickListener(OnViewClickListener listener) { 75 | this.mOnViewClickListener = listener; 76 | } 77 | 78 | /** 79 | * item 点击事件 80 | */ 81 | public interface OnViewClickListener { 82 | 83 | /** 84 | * item 被点击 85 | * 86 | * @param view 被点击的 {@link View} 87 | * @param position 在 RecyclerView 中的位置 88 | */ 89 | void onViewClick(View view, int position); 90 | } 91 | } -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/BaseLazyLoadFragment.java: -------------------------------------------------------------------------------- 1 | package com.jess.arms.base; 2 | 3 | import androidx.fragment.app.Fragment; 4 | import androidx.fragment.app.FragmentManager; 5 | 6 | import com.jess.arms.mvp.IPresenter; 7 | 8 | import java.util.List; 9 | 10 | import javax.inject.Inject; 11 | 12 | /** 13 | * 子类覆写{@link BaseLazyLoadFragment}lazyLoadData可快速实现Fragment懒加载 14 | */ 15 | public abstract class BaseLazyLoadFragment

extends BaseFragment

{ 16 | 17 | @Inject 18 | Unused mUnused; 19 | 20 | private boolean isViewCreated; // 界面是否已创建完成 21 | private boolean isVisibleToUser; // 是否对用户可见 22 | private boolean isDataLoaded; // 数据是否已请求 23 | 24 | /** 25 | * 第一次可见时触发调用,此处实现具体的数据请求逻辑 26 | */ 27 | protected abstract void lazyLoadData(); 28 | 29 | @Override 30 | public void setUserVisibleHint(boolean isVisibleToUser) { 31 | super.setUserVisibleHint(isVisibleToUser); 32 | this.isVisibleToUser = isVisibleToUser; 33 | tryLoadData(); 34 | } 35 | 36 | /** 37 | * 保证在initData后触发 38 | */ 39 | @Override 40 | public void onResume() { 41 | super.onResume(); 42 | isViewCreated = true; 43 | tryLoadData(); 44 | } 45 | 46 | /** 47 | * ViewPager场景下,判断父fragment是否可见 48 | */ 49 | private boolean isParentVisible() { 50 | Fragment fragment = getParentFragment(); 51 | return fragment == null || (fragment instanceof BaseLazyLoadFragment && ((BaseLazyLoadFragment) fragment).isVisibleToUser); 52 | } 53 | 54 | /** 55 | * ViewPager场景下,当前fragment可见时,如果其子fragment也可见,则让子fragment请求数据 56 | */ 57 | private void dispatchParentVisibleState() { 58 | FragmentManager fragmentManager = getChildFragmentManager(); 59 | List fragments = fragmentManager.getFragments(); 60 | if (fragments.isEmpty()) { 61 | return; 62 | } 63 | for (Fragment child : fragments) { 64 | if (child instanceof BaseLazyLoadFragment && ((BaseLazyLoadFragment) child).isVisibleToUser) { 65 | ((BaseLazyLoadFragment) child).tryLoadData(); 66 | } 67 | } 68 | } 69 | 70 | public void tryLoadData() { 71 | if (isViewCreated && isVisibleToUser && isParentVisible() && !isDataLoaded) { 72 | lazyLoadData(); 73 | isDataLoaded = true; 74 | //通知子Fragment请求数据 75 | dispatchParentVisibleState(); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/BaseService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base; 17 | 18 | import android.app.Service; 19 | import android.content.Intent; 20 | import android.os.IBinder; 21 | 22 | import androidx.annotation.Nullable; 23 | 24 | import com.jess.arms.integration.EventBusManager; 25 | 26 | import io.reactivex.disposables.CompositeDisposable; 27 | import io.reactivex.disposables.Disposable; 28 | 29 | /** 30 | * ================================================ 31 | * 基类 {@link Service} 32 | *

33 | * Created by jess on 2016/5/6. 34 | * Contact me 35 | * Follow me 36 | * ================================================ 37 | */ 38 | public abstract class BaseService extends Service { 39 | protected final String TAG = this.getClass().getSimpleName(); 40 | protected CompositeDisposable mCompositeDisposable; 41 | 42 | @Nullable 43 | @Override 44 | public IBinder onBind(Intent intent) { 45 | return null; 46 | } 47 | 48 | @Override 49 | public void onCreate() { 50 | super.onCreate(); 51 | if (useEventBus()) { 52 | EventBusManager.getInstance().register(this); 53 | } 54 | init(); 55 | } 56 | 57 | @Override 58 | public void onDestroy() { 59 | super.onDestroy(); 60 | if (useEventBus()) { 61 | EventBusManager.getInstance().unregister(this); 62 | } 63 | unDispose();//解除订阅 64 | this.mCompositeDisposable = null; 65 | } 66 | 67 | /** 68 | * 是否使用 EventBus 69 | * Arms 核心库现在并不会依赖某个 EventBus, 要想使用 EventBus, 还请在项目中自行依赖对应的 EventBus 70 | * 现在支持两种 EventBus, greenrobot 的 EventBus 和畅销书 《Android源码设计模式解析与实战》的作者 何红辉 所作的 AndroidEventBus 71 | * 确保依赖后, 将此方法返回 true, Arms 会自动检测您依赖的 EventBus, 并自动注册 72 | * 这种做法可以让使用者有自行选择三方库的权利, 并且还可以减轻 Arms 的体积 73 | * 74 | * @return 返回 {@code true} (默认为 {@code true}), Arms 会自动注册 EventBus 75 | */ 76 | public boolean useEventBus() { 77 | return true; 78 | } 79 | 80 | protected void addDispose(Disposable disposable) { 81 | if (mCompositeDisposable == null) { 82 | mCompositeDisposable = new CompositeDisposable(); 83 | } 84 | mCompositeDisposable.add(disposable);//将所有 Disposable 放入容器集中处理 85 | } 86 | 87 | protected void unDispose() { 88 | if (mCompositeDisposable != null) { 89 | mCompositeDisposable.clear();//保证 Activity 结束时取消所有正在执行的订阅 90 | } 91 | } 92 | 93 | /** 94 | * 初始化 95 | */ 96 | abstract public void init(); 97 | } 98 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/Platform.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 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 com.jess.arms.base; 17 | 18 | /** 19 | * ================================================ 20 | * Created by JessYan on 2018/7/27 15:32 21 | * Contact me 22 | * Follow me 23 | * ================================================ 24 | */ 25 | public class Platform { 26 | public static final boolean DEPENDENCY_AUTO_LAYOUT; 27 | public static final boolean DEPENDENCY_SUPPORT_DESIGN; 28 | public static final boolean DEPENDENCY_GLIDE; 29 | public static final boolean DEPENDENCY_ANDROID_EVENTBUS; 30 | public static final boolean DEPENDENCY_EVENTBUS; 31 | 32 | static { 33 | DEPENDENCY_AUTO_LAYOUT = findClassByClassName("com.zhy.autolayout.AutoLayoutInfo"); 34 | DEPENDENCY_SUPPORT_DESIGN = findClassByClassName("com.google.android.material.snackbar.Snackbar"); 35 | DEPENDENCY_GLIDE = findClassByClassName("com.bumptech.glide.Glide"); 36 | DEPENDENCY_ANDROID_EVENTBUS = findClassByClassName("org.simple.eventbus.EventBus"); 37 | DEPENDENCY_EVENTBUS = findClassByClassName("org.greenrobot.eventbus.EventBus"); 38 | } 39 | 40 | private static boolean findClassByClassName(String className) { 41 | boolean hasDependency; 42 | try { 43 | Class.forName(className); 44 | hasDependency = true; 45 | } catch (ClassNotFoundException e) { 46 | hasDependency = false; 47 | } 48 | return hasDependency; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/Unused.java: -------------------------------------------------------------------------------- 1 | package com.jess.arms.base; 2 | 3 | import javax.inject.Inject; 4 | 5 | /** 6 | * Created by yexiaokang on 2019/11/12. 7 | */ 8 | public class Unused { 9 | 10 | @Inject 11 | public Unused() { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/delegate/ActivityDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base.delegate; 17 | 18 | import android.app.Activity; 19 | import android.os.Bundle; 20 | 21 | import androidx.annotation.NonNull; 22 | import androidx.annotation.Nullable; 23 | 24 | /** 25 | * ================================================ 26 | * {@link Activity} 代理类,用于框架内部在每个 {@link Activity} 的对应生命周期中插入需要的逻辑 27 | * 28 | * @see ActivityDelegateImpl 29 | * @see ActivityDelegate wiki 官方文档 30 | * Created by JessYan on 26/04/2017 20:23 31 | * Contact me 32 | * Follow me 33 | * ================================================ 34 | */ 35 | public interface ActivityDelegate { 36 | String LAYOUT_LINEARLAYOUT = "LinearLayout"; 37 | String LAYOUT_FRAMELAYOUT = "FrameLayout"; 38 | String LAYOUT_RELATIVELAYOUT = "RelativeLayout"; 39 | String ACTIVITY_DELEGATE = "ACTIVITY_DELEGATE"; 40 | 41 | void onCreate(@Nullable Bundle savedInstanceState); 42 | 43 | void onStart(); 44 | 45 | void onResume(); 46 | 47 | void onPause(); 48 | 49 | void onStop(); 50 | 51 | void onSaveInstanceState(@NonNull Bundle outState); 52 | 53 | void onDestroy(); 54 | } 55 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/delegate/ActivityDelegateImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base.delegate; 17 | 18 | import android.app.Activity; 19 | import android.os.Bundle; 20 | 21 | import androidx.annotation.NonNull; 22 | import androidx.annotation.Nullable; 23 | 24 | import com.jess.arms.integration.EventBusManager; 25 | import com.jess.arms.utils.ArmsUtils; 26 | 27 | /** 28 | * ================================================ 29 | * {@link ActivityDelegate} 默认实现类 30 | *

31 | * Created by JessYan on 26/04/2017 20:23 32 | * Contact me 33 | * Follow me 34 | * ================================================ 35 | */ 36 | public class ActivityDelegateImpl implements ActivityDelegate { 37 | private Activity mActivity; 38 | private IActivity iActivity; 39 | 40 | public ActivityDelegateImpl(@NonNull Activity activity) { 41 | this.mActivity = activity; 42 | this.iActivity = (IActivity) activity; 43 | } 44 | 45 | @Override 46 | public void onCreate(@Nullable Bundle savedInstanceState) { 47 | //如果要使用 EventBus 请将此方法返回 true 48 | if (iActivity.useEventBus()) { 49 | //注册到事件主线 50 | EventBusManager.getInstance().register(mActivity); 51 | } 52 | 53 | //这里提供 AppComponent 对象给 BaseActivity 的子类, 用于 Dagger2 的依赖注入 54 | iActivity.setupActivityComponent(ArmsUtils.obtainAppComponentFromContext(mActivity)); 55 | } 56 | 57 | @Override 58 | public void onStart() { 59 | 60 | } 61 | 62 | @Override 63 | public void onResume() { 64 | 65 | } 66 | 67 | @Override 68 | public void onPause() { 69 | 70 | } 71 | 72 | @Override 73 | public void onStop() { 74 | 75 | } 76 | 77 | @Override 78 | public void onSaveInstanceState(@NonNull Bundle outState) { 79 | 80 | } 81 | 82 | @Override 83 | public void onDestroy() { 84 | //如果要使用 EventBus 请将此方法返回 true 85 | if (iActivity != null && iActivity.useEventBus()) { 86 | EventBusManager.getInstance().unregister(mActivity); 87 | } 88 | this.iActivity = null; 89 | this.mActivity = null; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/delegate/AppLifecycles.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base.delegate; 17 | 18 | import android.app.Application; 19 | import android.content.Context; 20 | 21 | import androidx.annotation.NonNull; 22 | 23 | /** 24 | * ================================================ 25 | * 用于代理 {@link Application} 的生命周期 26 | * 27 | * @see AppDelegate 28 | * Created by JessYan on 18/07/2017 17:43 29 | * Contact me 30 | * Follow me 31 | * ================================================ 32 | */ 33 | public interface AppLifecycles { 34 | void attachBaseContext(@NonNull Context base); 35 | 36 | void onCreate(@NonNull Application application); 37 | 38 | void onTerminate(@NonNull Application application); 39 | } 40 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/delegate/FragmentDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base.delegate; 17 | 18 | import android.content.Context; 19 | import android.os.Bundle; 20 | import android.view.View; 21 | 22 | import androidx.annotation.NonNull; 23 | import androidx.annotation.Nullable; 24 | import androidx.fragment.app.Fragment; 25 | 26 | /** 27 | * ================================================ 28 | * {@link Fragment} 代理类,用于框架内部在每个 {@link Fragment} 的对应生命周期中插入需要的逻辑 29 | * 30 | * @see FragmentDelegateImpl 31 | * @see FragmentDelegate wiki 官方文档 32 | * Created by JessYan on 29/04/2017 14:30 33 | * Contact me 34 | * Follow me 35 | * ================================================ 36 | */ 37 | public interface FragmentDelegate { 38 | String FRAGMENT_DELEGATE = "FRAGMENT_DELEGATE"; 39 | 40 | void onAttach(@NonNull Context context); 41 | 42 | void onCreate(@Nullable Bundle savedInstanceState); 43 | 44 | void onCreateView(@Nullable View view, @Nullable Bundle savedInstanceState); 45 | 46 | void onActivityCreate(@Nullable Bundle savedInstanceState); 47 | 48 | void onStart(); 49 | 50 | void onResume(); 51 | 52 | void onPause(); 53 | 54 | void onStop(); 55 | 56 | void onSaveInstanceState(@NonNull Bundle outState); 57 | 58 | void onDestroyView(); 59 | 60 | void onDestroy(); 61 | 62 | void onDetach(); 63 | 64 | /** 65 | * Return true if the fragment is currently added to its activity. 66 | */ 67 | boolean isAdded(); 68 | } 69 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/base/delegate/IActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.base.delegate; 17 | 18 | 19 | import android.app.Activity; 20 | import android.os.Bundle; 21 | 22 | import androidx.annotation.NonNull; 23 | import androidx.annotation.Nullable; 24 | import androidx.fragment.app.FragmentManager; 25 | 26 | import com.jess.arms.base.BaseActivity; 27 | import com.jess.arms.base.BaseFragment; 28 | import com.jess.arms.di.component.AppComponent; 29 | import com.jess.arms.integration.ActivityLifecycle; 30 | import com.jess.arms.integration.cache.Cache; 31 | import com.jess.arms.integration.cache.LruCache; 32 | 33 | /** 34 | * ================================================ 35 | * 框架要求框架中的每个 {@link Activity} 都需要实现此类,以满足规范 36 | * 37 | * @see BaseActivity 38 | * Created by JessYan on 26/04/2017 21:42 39 | * Contact me 40 | * Follow me 41 | * ================================================ 42 | */ 43 | public interface IActivity { 44 | 45 | /** 46 | * 提供在 {@link Activity} 生命周期内的缓存容器, 可向此 {@link Activity} 存取一些必要的数据 47 | * 此缓存容器和 {@link Activity} 的生命周期绑定, 如果 {@link Activity} 在屏幕旋转或者配置更改的情况下 48 | * 重新创建, 那此缓存容器中的数据也会被清空, 如果你想避免此种情况请使用 LifecycleModel 49 | * 50 | * @return like {@link LruCache} 51 | */ 52 | @NonNull 53 | Cache provideCache(); 54 | 55 | /** 56 | * 提供 AppComponent (提供所有的单例对象) 给实现类, 进行 Component 依赖 57 | * 58 | * @param appComponent 59 | */ 60 | void setupActivityComponent(@NonNull AppComponent appComponent); 61 | 62 | /** 63 | * 是否使用 EventBus 64 | * Arms 核心库现在并不会依赖某个 EventBus, 要想使用 EventBus, 还请在项目中自行依赖对应的 EventBus 65 | * 现在支持两种 EventBus, greenrobot 的 EventBus 和畅销书 《Android源码设计模式解析与实战》的作者 何红辉 所作的 AndroidEventBus 66 | * 确保依赖后, 将此方法返回 true, Arms 会自动检测您依赖的 EventBus, 并自动注册 67 | * 这种做法可以让使用者有自行选择三方库的权利, 并且还可以减轻 Arms 的体积 68 | * 69 | * @return 返回 {@code true}, Arms 会自动注册 EventBus 70 | */ 71 | boolean useEventBus(); 72 | 73 | /** 74 | * 初始化 View, 如果 {@link #initView(Bundle)} 返回 0, 框架则不会调用 {@link Activity#setContentView(int)} 75 | * 76 | * @param savedInstanceState 77 | * @return 78 | */ 79 | int initView(@Nullable Bundle savedInstanceState); 80 | 81 | /** 82 | * 初始化数据 83 | * 84 | * @param savedInstanceState 85 | */ 86 | void initData(@Nullable Bundle savedInstanceState); 87 | 88 | /** 89 | * 这个 Activity 是否会使用 Fragment,框架会根据这个属性判断是否注册 {@link FragmentManager.FragmentLifecycleCallbacks} 90 | * 如果返回{@code false},那意味着这个 Activity 不需要绑定 Fragment,那你再在这个 Activity 中绑定继承于 {@link BaseFragment} 的 Fragment 将不起任何作用 91 | * 92 | * @return 93 | * @see ActivityLifecycle#registerFragmentCallbacks (Fragment 的注册过程) 94 | */ 95 | boolean useFragment(); 96 | } 97 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/di/module/AppModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.di.module; 17 | 18 | import android.app.Application; 19 | import android.content.Context; 20 | 21 | import androidx.annotation.NonNull; 22 | import androidx.annotation.Nullable; 23 | import androidx.fragment.app.FragmentManager; 24 | 25 | import com.google.gson.Gson; 26 | import com.google.gson.GsonBuilder; 27 | import com.jess.arms.di.component.AppComponent; 28 | import com.jess.arms.integration.ActivityLifecycle; 29 | import com.jess.arms.integration.AppManager; 30 | import com.jess.arms.integration.FragmentLifecycle; 31 | import com.jess.arms.integration.IRepositoryManager; 32 | import com.jess.arms.integration.RepositoryManager; 33 | import com.jess.arms.integration.cache.Cache; 34 | import com.jess.arms.integration.cache.CacheType; 35 | import com.jess.arms.integration.lifecycle.ActivityLifecycleForRxLifecycle; 36 | 37 | import java.util.ArrayList; 38 | import java.util.List; 39 | 40 | import javax.inject.Named; 41 | import javax.inject.Singleton; 42 | 43 | import dagger.Binds; 44 | import dagger.Module; 45 | import dagger.Provides; 46 | 47 | /** 48 | * ================================================ 49 | * 提供一些框架必须的实例的 {@link Module} 50 | *

51 | * Created by JessYan on 8/4/2016. 52 | * Contact me 53 | * Follow me 54 | * ================================================ 55 | */ 56 | @Module 57 | public abstract class AppModule { 58 | 59 | @Singleton 60 | @Provides 61 | static Gson provideGson(Application application, @Nullable GsonConfiguration configuration) { 62 | GsonBuilder builder = new GsonBuilder(); 63 | if (configuration != null) { 64 | configuration.configGson(application, builder); 65 | } 66 | return builder.create(); 67 | } 68 | 69 | /** 70 | * 之前 {@link AppManager} 使用 Dagger 保证单例, 只能使用 {@link AppComponent#appManager()} 访问 71 | * 现在直接将 AppManager 独立为单例类, 可以直接通过静态方法 {@link AppManager#getAppManager()} 访问, 更加方便 72 | * 但为了不影响之前使用 {@link AppComponent#appManager()} 获取 {@link AppManager} 的项目, 所以暂时保留这种访问方式 73 | * 74 | * @param application 75 | * @return 76 | */ 77 | @Singleton 78 | @Provides 79 | static AppManager provideAppManager(Application application) { 80 | return AppManager.getAppManager().init(application); 81 | } 82 | 83 | @Singleton 84 | @Provides 85 | static Cache provideExtras(Cache.Factory cacheFactory) { 86 | //noinspection unchecked 87 | return cacheFactory.build(CacheType.EXTRAS); 88 | } 89 | 90 | @Singleton 91 | @Provides 92 | static List provideFragmentLifecycles() { 93 | return new ArrayList<>(); 94 | } 95 | 96 | @Binds 97 | abstract IRepositoryManager bindRepositoryManager(RepositoryManager repositoryManager); 98 | 99 | @Binds 100 | @Named("ActivityLifecycle") 101 | abstract Application.ActivityLifecycleCallbacks bindActivityLifecycle(ActivityLifecycle activityLifecycle); 102 | 103 | @Binds 104 | @Named("ActivityLifecycleForRxLifecycle") 105 | abstract Application.ActivityLifecycleCallbacks bindActivityLifecycleForRxLifecycle(ActivityLifecycleForRxLifecycle activityLifecycleForRxLifecycle); 106 | 107 | @Binds 108 | abstract FragmentManager.FragmentLifecycleCallbacks bindFragmentLifecycle(FragmentLifecycle fragmentLifecycle); 109 | 110 | public interface GsonConfiguration { 111 | void configGson(@NonNull Context context, @NonNull GsonBuilder builder); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/di/scope/ActivityScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.di.scope; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.Retention; 20 | 21 | import javax.inject.Scope; 22 | 23 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 24 | 25 | /** 26 | * A scoping annotation to permit objects whose lifetime should 27 | * conform to the life of the activity to be memorized in the 28 | * correct component. 29 | */ 30 | @Scope 31 | @Documented 32 | @Retention(RUNTIME) 33 | public @interface ActivityScope { 34 | } 35 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/di/scope/FragmentScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.di.scope; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.Retention; 20 | 21 | import javax.inject.Scope; 22 | 23 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 24 | 25 | /** 26 | * A scoping annotation to permit objects whose lifetime should 27 | * conform to the life of the fragment to be memorized in the 28 | * correct component. 29 | */ 30 | @Scope 31 | @Documented 32 | @Retention(RUNTIME) 33 | public @interface FragmentScope { 34 | } 35 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/http/BaseUrl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.http; 17 | 18 | import androidx.annotation.NonNull; 19 | 20 | import okhttp3.HttpUrl; 21 | 22 | /** 23 | * ================================================ 24 | * 针对于 BaseUrl 在 App 启动时不能确定,需要请求服务器接口动态获取的应用场景 25 | *

26 | * Created by JessYan on 11/07/2017 14:58 27 | * Contact me 28 | * Follow me 29 | * ================================================ 30 | */ 31 | public interface BaseUrl { 32 | /** 33 | * 在调用 Retrofit API 接口之前,使用 Okhttp 或其他方式,请求到正确的 BaseUrl 并通过此方法返回 34 | * 35 | * @return 36 | */ 37 | @NonNull 38 | HttpUrl url(); 39 | } 40 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/http/GlobalHttpHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.http; 17 | 18 | import androidx.annotation.NonNull; 19 | import androidx.annotation.Nullable; 20 | 21 | import com.jess.arms.di.module.GlobalConfigModule; 22 | 23 | import okhttp3.Interceptor; 24 | import okhttp3.Request; 25 | import okhttp3.Response; 26 | 27 | /** 28 | * ================================================ 29 | * 处理 Http 请求和响应结果的处理类 30 | * 使用 {@link GlobalConfigModule.Builder#globalHttpHandler(GlobalHttpHandler)} 方法配置 31 | * 32 | * @see GlobalHttpHandler Wiki 官方文档 33 | * Created by JessYan on 8/30/16 17:47 34 | * Contact me 35 | * Follow me 36 | * ================================================ 37 | */ 38 | public interface GlobalHttpHandler { 39 | 40 | /** 41 | * 空实现 42 | */ 43 | GlobalHttpHandler EMPTY = new GlobalHttpHandler() { 44 | 45 | @NonNull 46 | @Override 47 | public Response onHttpResultResponse(@Nullable String httpResult, @NonNull Interceptor.Chain chain, @NonNull Response response) { 48 | //不管是否处理, 都必须将 response 返回出去 49 | return response; 50 | } 51 | 52 | @NonNull 53 | @Override 54 | public Request onHttpRequestBefore(@NonNull Interceptor.Chain chain, @NonNull Request request) { 55 | //不管是否处理, 都必须将 request 返回出去 56 | return request; 57 | } 58 | }; 59 | 60 | /** 61 | * 这里可以先客户端一步拿到每一次 Http 请求的结果, 可以先解析成 Json, 再做一些操作, 如检测到 token 过期后 62 | * 重新请求 token, 并重新执行请求 63 | * 64 | * @param httpResult 服务器返回的结果 (已被框架自动转换为字符串) 65 | * @param chain {@link okhttp3.Interceptor.Chain} 66 | * @param response {@link Response} 67 | * @return {@link Response} 68 | */ 69 | @NonNull 70 | Response onHttpResultResponse(@Nullable String httpResult, @NonNull Interceptor.Chain chain, @NonNull Response response); 71 | 72 | /** 73 | * 这里可以在请求服务器之前拿到 {@link Request}, 做一些操作比如给 {@link Request} 统一添加 token 或者 header 以及参数加密等操作 74 | * 75 | * @param chain {@link okhttp3.Interceptor.Chain} 76 | * @param request {@link Request} 77 | * @return {@link Request} 78 | */ 79 | @NonNull 80 | Request onHttpRequestBefore(@NonNull Interceptor.Chain chain, @NonNull Request request); 81 | } 82 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/http/OkHttpUrlLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.http; 17 | 18 | import androidx.annotation.NonNull; 19 | 20 | import com.bumptech.glide.load.Options; 21 | import com.bumptech.glide.load.model.GlideUrl; 22 | import com.bumptech.glide.load.model.ModelLoader; 23 | import com.bumptech.glide.load.model.ModelLoaderFactory; 24 | import com.bumptech.glide.load.model.MultiModelLoaderFactory; 25 | 26 | import org.jetbrains.annotations.NotNull; 27 | 28 | import java.io.InputStream; 29 | 30 | import okhttp3.Call; 31 | import okhttp3.OkHttpClient; 32 | 33 | /** 34 | * A simple model loader for fetching media over http/https using OkHttp. 35 | */ 36 | public class OkHttpUrlLoader implements ModelLoader { 37 | 38 | private final Call.Factory client; 39 | 40 | // Public API. 41 | @SuppressWarnings("WeakerAccess") 42 | public OkHttpUrlLoader(@NonNull Call.Factory client) { 43 | this.client = client; 44 | } 45 | 46 | @Override 47 | public boolean handles(@NonNull GlideUrl url) { 48 | return true; 49 | } 50 | 51 | @Override 52 | public LoadData buildLoadData(@NonNull GlideUrl model, int width, int height, 53 | @NonNull Options options) { 54 | return new LoadData<>(model, new OkHttpStreamFetcher(client, model)); 55 | } 56 | 57 | /** 58 | * The default factory for {@link OkHttpUrlLoader}s. 59 | */ 60 | // Public API. 61 | @SuppressWarnings("WeakerAccess") 62 | public static class Factory implements ModelLoaderFactory { 63 | private static volatile Call.Factory internalClient; 64 | private final Call.Factory client; 65 | 66 | /** 67 | * Constructor for a new Factory that runs requests using a static singleton client. 68 | */ 69 | public Factory() { 70 | this(getInternalClient()); 71 | } 72 | 73 | /** 74 | * Constructor for a new Factory that runs requests using given client. 75 | * 76 | * @param client this is typically an instance of {@code OkHttpClient}. 77 | */ 78 | public Factory(@NonNull Call.Factory client) { 79 | this.client = client; 80 | } 81 | 82 | private static Call.Factory getInternalClient() { 83 | if (internalClient == null) { 84 | synchronized (Factory.class) { 85 | if (internalClient == null) { 86 | internalClient = new OkHttpClient(); 87 | } 88 | } 89 | } 90 | return internalClient; 91 | } 92 | 93 | @NonNull 94 | @Override 95 | public ModelLoader build(@NotNull MultiModelLoaderFactory multiFactory) { 96 | return new OkHttpUrlLoader(client); 97 | } 98 | 99 | @Override 100 | public void teardown() { 101 | // Do nothing, this instance doesn't own the client. 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/http/imageloader/BaseImageLoaderStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.http.imageloader; 17 | 18 | import android.content.Context; 19 | 20 | import androidx.annotation.Nullable; 21 | 22 | /** 23 | * ================================================ 24 | * 图片加载策略,实现 {@link BaseImageLoaderStrategy} 25 | * 并通过 {@link ImageLoader#setLoadImgStrategy(BaseImageLoaderStrategy)} 配置后,才可进行图片请求 26 | *

27 | * Created by JessYan on 8/5/2016 15:50 28 | * Contact me 29 | * Follow me 30 | * ================================================ 31 | */ 32 | public interface BaseImageLoaderStrategy { 33 | 34 | /** 35 | * 加载图片 36 | * 37 | * @param ctx {@link Context} 38 | * @param config 图片加载配置信息 39 | */ 40 | void loadImage(@Nullable Context ctx, @Nullable T config); 41 | 42 | /** 43 | * 停止加载 44 | * 45 | * @param ctx {@link Context} 46 | * @param config 图片加载配置信息 47 | */ 48 | void clear(@Nullable Context ctx, @Nullable T config); 49 | } 50 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/http/imageloader/ImageConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.http.imageloader; 17 | 18 | import android.widget.ImageView; 19 | 20 | /** 21 | * ================================================ 22 | * 这里是图片加载配置信息的基类,定义一些所有图片加载框架都可以用的通用参数 23 | * 每个 {@link BaseImageLoaderStrategy} 应该对应一个 {@link ImageConfig} 实现类 24 | *

25 | * Created by JessYan on 8/5/16 15:19 26 | * Contact me 27 | * Follow me 28 | * ================================================ 29 | */ 30 | public class ImageConfig { 31 | protected String url; 32 | protected ImageView imageView; 33 | protected int placeholder;//占位符 34 | protected int errorPic;//错误占位符 35 | 36 | public String getUrl() { 37 | return url; 38 | } 39 | 40 | public ImageView getImageView() { 41 | return imageView; 42 | } 43 | 44 | public int getPlaceholder() { 45 | return placeholder; 46 | } 47 | 48 | public int getErrorPic() { 49 | return errorPic; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/http/imageloader/ImageLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.http.imageloader; 17 | 18 | import android.content.Context; 19 | 20 | import androidx.annotation.Nullable; 21 | 22 | import com.jess.arms.utils.Preconditions; 23 | 24 | import javax.inject.Inject; 25 | import javax.inject.Singleton; 26 | 27 | /** 28 | * ================================================ 29 | * {@link ImageLoader} 使用策略模式和建造者模式,可以动态切换图片请求框架(比如说切换成 Picasso ) 30 | * 当需要切换图片请求框架或图片请求框架升级后变更了 Api 时 31 | * 这里可以将影响范围降到最低,所以封装 {@link ImageLoader} 是为了屏蔽这个风险 32 | * 33 | * @see ImageLoader wiki 文档 34 | * Created by JessYan on 8/5/16 15:57 35 | * Contact me 36 | * Follow me 37 | * ================================================ 38 | */ 39 | @Singleton 40 | public final class ImageLoader { 41 | @Inject 42 | @Nullable 43 | BaseImageLoaderStrategy mStrategy; 44 | 45 | @Inject 46 | public ImageLoader() { 47 | } 48 | 49 | /** 50 | * 加载图片 51 | * 52 | * @param context 53 | * @param config 54 | * @param 55 | */ 56 | public void loadImage(Context context, T config) { 57 | Preconditions.checkNotNull(mStrategy, "Please implement BaseImageLoaderStrategy and call GlobalConfigModule.Builder#imageLoaderStrategy(BaseImageLoaderStrategy) in the applyOptions method of ConfigModule"); 58 | //noinspection unchecked 59 | this.mStrategy.loadImage(context, config); 60 | } 61 | 62 | /** 63 | * 停止加载或清理缓存 64 | * 65 | * @param context 66 | * @param config 67 | * @param 68 | */ 69 | public void clear(Context context, T config) { 70 | Preconditions.checkNotNull(mStrategy, "Please implement BaseImageLoaderStrategy and call GlobalConfigModule.Builder#imageLoaderStrategy(BaseImageLoaderStrategy) in the applyOptions method of ConfigModule"); 71 | //noinspection unchecked 72 | this.mStrategy.clear(context, config); 73 | } 74 | 75 | @Nullable 76 | public BaseImageLoaderStrategy getLoadImgStrategy() { 77 | return mStrategy; 78 | } 79 | 80 | /** 81 | * 可在运行时随意切换 {@link BaseImageLoaderStrategy} 82 | * 83 | * @param strategy 84 | */ 85 | public void setLoadImgStrategy(BaseImageLoaderStrategy strategy) { 86 | Preconditions.checkNotNull(strategy, "strategy == null"); 87 | this.mStrategy = strategy; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/http/imageloader/glide/GlideAppliesOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.http.imageloader.glide; 17 | 18 | import android.content.Context; 19 | 20 | import androidx.annotation.NonNull; 21 | 22 | import com.bumptech.glide.Glide; 23 | import com.bumptech.glide.GlideBuilder; 24 | import com.bumptech.glide.Registry; 25 | import com.jess.arms.http.imageloader.BaseImageLoaderStrategy; 26 | 27 | /** 28 | * ================================================ 29 | * 如果你想具有配置 @{@link Glide} 的权利,则需要让 {@link BaseImageLoaderStrategy} 30 | * 的实现类也必须实现 {@link GlideAppliesOptions} 31 | *

32 | * Created by JessYan on 13/08/2017 22:02 33 | * Contact me 34 | * Follow me 35 | * ================================================ 36 | */ 37 | public interface GlideAppliesOptions { 38 | 39 | /** 40 | * 配置 @{@link Glide} 的自定义参数,此方法在 @{@link Glide} 初始化时执行(@{@link Glide} 在第一次被调用时初始化),只会执行一次 41 | * 42 | * @param context 43 | * @param builder {@link GlideBuilder} 此类被用来创建 Glide 44 | */ 45 | void applyGlideOptions(@NonNull Context context, @NonNull GlideBuilder builder); 46 | 47 | /** 48 | * 注册{@link Glide}的组件,参考{@link com.bumptech.glide.module.LibraryGlideModule} 49 | * 50 | * @param context Android context 51 | * @param glide {@link Glide} 52 | * @param registry {@link Registry} 53 | */ 54 | void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry); 55 | } 56 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/http/log/FormatPrinter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 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 com.jess.arms.http.log; 17 | 18 | import androidx.annotation.NonNull; 19 | import androidx.annotation.Nullable; 20 | 21 | import com.jess.arms.di.module.GlobalConfigModule; 22 | 23 | import java.util.List; 24 | 25 | import okhttp3.MediaType; 26 | import okhttp3.Request; 27 | 28 | /** 29 | * ================================================ 30 | * 对 OkHttp 的请求和响应信息进行更规范和清晰的打印, 开发者可更根据自己的需求自行扩展打印格式 31 | * 32 | * @see DefaultFormatPrinter 33 | * @see GlobalConfigModule.Builder#formatPrinter(FormatPrinter) 34 | * Created by JessYan on 31/01/2018 17:36 35 | * Contact me 36 | * Follow me 37 | * ================================================ 38 | */ 39 | 40 | public interface FormatPrinter { 41 | 42 | /** 43 | * 打印网络请求信息, 当网络请求时 {{@link okhttp3.RequestBody}} 可以解析的情况 44 | * 45 | * @param request 46 | * @param bodyString 发送给服务器的请求体中的数据(已解析) 47 | */ 48 | void printJsonRequest(@NonNull Request request, @NonNull String bodyString); 49 | 50 | /** 51 | * 打印网络请求信息, 当网络请求时 {{@link okhttp3.RequestBody}} 为 {@code null} 或不可解析的情况 52 | * 53 | * @param request 54 | */ 55 | void printFileRequest(@NonNull Request request); 56 | 57 | /** 58 | * 打印网络响应信息, 当网络响应时 {{@link okhttp3.ResponseBody}} 可以解析的情况 59 | * 60 | * @param chainMs 服务器响应耗时(单位毫秒) 61 | * @param isSuccessful 请求是否成功 62 | * @param code 响应码 63 | * @param headers 请求头 64 | * @param contentType 服务器返回数据的数据类型 65 | * @param bodyString 服务器返回的数据(已解析) 66 | * @param segments 域名后面的资源地址 67 | * @param message 响应信息 68 | * @param responseUrl 请求地址 69 | */ 70 | void printJsonResponse(long chainMs, boolean isSuccessful, int code, @NonNull String headers, @Nullable MediaType contentType, 71 | @Nullable String bodyString, @NonNull List segments, @NonNull String message, @NonNull String responseUrl); 72 | 73 | /** 74 | * 打印网络响应信息, 当网络响应时 {{@link okhttp3.ResponseBody}} 为 {@code null} 或不可解析的情况 75 | * 76 | * @param chainMs 服务器响应耗时(单位毫秒) 77 | * @param isSuccessful 请求是否成功 78 | * @param code 响应码 79 | * @param headers 请求头 80 | * @param segments 域名后面的资源地址 81 | * @param message 响应信息 82 | * @param responseUrl 请求地址 83 | */ 84 | void printFileResponse(long chainMs, boolean isSuccessful, int code, @NonNull String headers, 85 | @NonNull List segments, @NonNull String message, @NonNull String responseUrl); 86 | } 87 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/integration/ConfigModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.integration; 17 | 18 | import android.app.Activity; 19 | import android.app.Application; 20 | import android.content.Context; 21 | 22 | import androidx.annotation.NonNull; 23 | import androidx.fragment.app.Fragment; 24 | import androidx.fragment.app.FragmentManager; 25 | 26 | import com.jess.arms.base.delegate.AppLifecycles; 27 | import com.jess.arms.di.module.GlobalConfigModule; 28 | 29 | import java.util.List; 30 | 31 | /** 32 | * ================================================ 33 | * {@link ConfigModule} 可以给框架配置一些参数,需要实现 {@link ConfigModule} 后,在 AndroidManifest 中声明该实现类 34 | * 35 | * @see ConfigModule wiki 官方文档 36 | * Created by JessYan on 12/04/2017 11:37 37 | * Contact me 38 | * Follow me 39 | * ================================================ 40 | */ 41 | public interface ConfigModule { 42 | /** 43 | * 使用 {@link GlobalConfigModule.Builder} 给框架配置一些配置参数 44 | * 45 | * @param context {@link Context} 46 | * @param builder {@link GlobalConfigModule.Builder} 47 | */ 48 | void applyOptions(@NonNull Context context, @NonNull GlobalConfigModule.Builder builder); 49 | 50 | /** 51 | * 使用 {@link AppLifecycles} 在 {@link Application} 的生命周期中注入一些操作 52 | * 53 | * @param context {@link Context} 54 | * @param lifecycles {@link Application} 的生命周期容器, 可向框架中添加多个 {@link Application} 的生命周期类 55 | */ 56 | void injectAppLifecycle(@NonNull Context context, @NonNull List lifecycles); 57 | 58 | /** 59 | * 使用 {@link Application.ActivityLifecycleCallbacks} 在 {@link Activity} 的生命周期中注入一些操作 60 | * 61 | * @param context {@link Context} 62 | * @param lifecycles {@link Activity} 的生命周期容器, 可向框架中添加多个 {@link Activity} 的生命周期类 63 | */ 64 | void injectActivityLifecycle(@NonNull Context context, @NonNull List lifecycles); 65 | 66 | /** 67 | * 使用 {@link FragmentManager.FragmentLifecycleCallbacks} 在 {@link Fragment} 的生命周期中注入一些操作 68 | * 69 | * @param context {@link Context} 70 | * @param lifecycles {@link Fragment} 的生命周期容器, 可向框架中添加多个 {@link Fragment} 的生命周期类 71 | */ 72 | void injectFragmentLifecycle(@NonNull Context context, @NonNull List lifecycles); 73 | } 74 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/integration/IRepositoryManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.integration; 17 | 18 | import android.content.Context; 19 | 20 | import androidx.annotation.NonNull; 21 | import androidx.annotation.Nullable; 22 | 23 | import com.jess.arms.mvp.IModel; 24 | 25 | import retrofit2.Retrofit; 26 | 27 | /** 28 | * ================================================ 29 | * 用来管理网络请求层,以及数据缓存层,以后可能添加数据库请求层 30 | * 提供给 {@link IModel} 必要的 Api 做数据处理 31 | * 32 | * @see RepositoryManager wiki 官方文档 33 | * Created by JessYan on 17/03/2017 11:15 34 | * Contact me 35 | * Follow me 36 | * ================================================ 37 | */ 38 | public interface IRepositoryManager { 39 | 40 | /** 41 | * 根据传入的 Class 获取对应的 Retrofit service 42 | * 43 | * @param service Retrofit service class 44 | * @param Retrofit service 类型 45 | * @return Retrofit service 46 | */ 47 | @NonNull 48 | T obtainRetrofitService(@NonNull Class service); 49 | 50 | 51 | /** 52 | * 根据传入的 Class 获取对应的 RxCache service 53 | * 54 | * @param cache RxCache service class 55 | * @param RxCache service 类型 56 | * @return RxCache service 57 | */ 58 | @NonNull 59 | T obtainCacheService(@NonNull Class cache); 60 | 61 | /** 62 | * 清理所有缓存 63 | */ 64 | void clearAllCache(); 65 | 66 | /** 67 | * 获取 {@link Context} 68 | * 69 | * @return {@link Context} 70 | */ 71 | @NonNull 72 | Context getContext(); 73 | 74 | interface ObtainServiceDelegate { 75 | 76 | @Nullable 77 | T createRetrofitService(Retrofit retrofit, Class serviceClass); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/integration/ManifestParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.integration; 17 | 18 | import android.content.Context; 19 | import android.content.pm.ApplicationInfo; 20 | import android.content.pm.PackageManager; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | /** 26 | * ================================================ 27 | * 用于解析 AndroidManifest 中的 Meta 属性 28 | * 配合 {@link ConfigModule} 使用 29 | *

30 | * Created by JessYan on 12/04/2017 14:41 31 | * Contact me 32 | * Follow me 33 | * ================================================ 34 | */ 35 | public final class ManifestParser { 36 | private static final String MODULE_VALUE = "ConfigModule"; 37 | private final Context context; 38 | 39 | public ManifestParser(Context context) { 40 | this.context = context; 41 | } 42 | 43 | private static ConfigModule parseModule(String className) { 44 | Class clazz; 45 | try { 46 | clazz = Class.forName(className); 47 | } catch (ClassNotFoundException e) { 48 | throw new IllegalArgumentException("Unable to find ConfigModule implementation", e); 49 | } 50 | 51 | Object module; 52 | try { 53 | module = clazz.newInstance(); 54 | } catch (InstantiationException e) { 55 | throw new RuntimeException("Unable to instantiate ConfigModule implementation for " + clazz, e); 56 | } catch (IllegalAccessException e) { 57 | throw new RuntimeException("Unable to instantiate ConfigModule implementation for " + clazz, e); 58 | } 59 | 60 | if (!(module instanceof ConfigModule)) { 61 | throw new RuntimeException("Expected instanceof ConfigModule, but found: " + module); 62 | } 63 | return (ConfigModule) module; 64 | } 65 | 66 | public List parse() { 67 | List modules = new ArrayList<>(); 68 | try { 69 | ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( 70 | context.getPackageName(), PackageManager.GET_META_DATA); 71 | if (appInfo.metaData != null) { 72 | for (String key : appInfo.metaData.keySet()) { 73 | if (MODULE_VALUE.equals(appInfo.metaData.get(key))) { 74 | modules.add(parseModule(key)); 75 | } 76 | } 77 | } 78 | } catch (PackageManager.NameNotFoundException e) { 79 | throw new RuntimeException("Unable to find metadata to parse ConfigModule", e); 80 | } 81 | 82 | return modules; 83 | } 84 | } -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/integration/RetrofitServiceProxyHandler.java: -------------------------------------------------------------------------------- 1 | package com.jess.arms.integration; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | import java.lang.reflect.InvocationHandler; 6 | import java.lang.reflect.Method; 7 | 8 | import io.reactivex.Observable; 9 | import io.reactivex.Single; 10 | import retrofit2.Retrofit; 11 | 12 | 13 | public class RetrofitServiceProxyHandler implements InvocationHandler { 14 | 15 | private Retrofit mRetrofit; 16 | private Class mServiceClass; 17 | private Object mRetrofitService; 18 | 19 | public RetrofitServiceProxyHandler(Retrofit retrofit, Class serviceClass) { 20 | mRetrofit = retrofit; 21 | mServiceClass = serviceClass; 22 | } 23 | 24 | @Override 25 | public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { 26 | 27 | // 根据 https://zhuanlan.zhihu.com/p/40097338 对 Retrofit 进行的优化 28 | 29 | if (method.getReturnType() == Observable.class) { 30 | // 如果方法返回值是 Observable 的话,则包一层再返回, 31 | // 只包一层 defer 由外部去控制耗时方法以及网络请求所处线程, 32 | // 如此对原项目的影响为 0,且更可控。 33 | return Observable.defer(() -> { 34 | // 执行真正的 Retrofit 动态代理的方法 35 | return (Observable) method.invoke(getRetrofitService(), args); 36 | }); 37 | } else if (method.getReturnType() == Single.class) { 38 | // 如果方法返回值是 Single 的话,则包一层再返回。 39 | return Single.defer(() -> { 40 | // 执行真正的 Retrofit 动态代理的方法 41 | return (Single) method.invoke(getRetrofitService(), args); 42 | }); 43 | } 44 | 45 | // 返回值不是 Observable 或 Single 的话不处理。 46 | return method.invoke(getRetrofitService(), args); 47 | } 48 | 49 | private Object getRetrofitService() { 50 | if (mRetrofitService == null) { 51 | mRetrofitService = mRetrofit.create(mServiceClass); 52 | } 53 | return mRetrofitService; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/integration/cache/Cache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.integration.cache; 17 | 18 | import android.app.Application; 19 | 20 | import androidx.annotation.NonNull; 21 | import androidx.annotation.Nullable; 22 | 23 | import com.jess.arms.di.module.GlobalConfigModule; 24 | 25 | import java.util.Set; 26 | 27 | 28 | /** 29 | * ================================================ 30 | * 用于缓存框架中所必需的组件,开发者可通过 {@link GlobalConfigModule.Builder#cacheFactory(Factory)} 为框架提供缓存策略 31 | * 开发者也可以用于自己日常中的使用 32 | * 33 | * @see GlobalConfigModule#provideCacheFactory(Application) 34 | * @see LruCache 35 | * Created by JessYan on 25/09/2017 16:36 36 | * Contact me 37 | * Follow me 38 | * ================================================ 39 | */ 40 | public interface Cache { 41 | 42 | /** 43 | * 返回当前缓存已占用的总 size 44 | * 45 | * @return {@code size} 46 | */ 47 | int size(); 48 | 49 | /** 50 | * 返回当前缓存所能允许的最大 size 51 | * 52 | * @return {@code maxSize} 53 | */ 54 | int getMaxSize(); 55 | 56 | /** 57 | * 返回这个 {@code key} 在缓存中对应的 {@code value}, 如果返回 {@code null} 说明这个 {@code key} 没有对应的 {@code value} 58 | * 59 | * @param key {@code key} 60 | * @return {@code value} 61 | */ 62 | @Nullable 63 | V get(K key); 64 | 65 | /** 66 | * 将 {@code key} 和 {@code value} 以条目的形式加入缓存,如果这个 {@code key} 在缓存中已经有对应的 {@code value} 67 | * 则此 {@code value} 被新的 {@code value} 替换并返回,如果为 {@code null} 说明是一个新条目 68 | * 69 | * @param key {@code key} 70 | * @param value {@code value} 71 | * @return 如果这个 {@code key} 在容器中已经储存有 {@code value}, 则返回之前的 {@code value} 否则返回 {@code null} 72 | */ 73 | @Nullable 74 | V put(K key, V value); 75 | 76 | /** 77 | * 移除缓存中这个 {@code key} 所对应的条目,并返回所移除条目的 value 78 | * 如果返回为 {@code null} 则有可能时因为这个 {@code key} 对应的 value 为 {@code null} 或条目不存在 79 | * 80 | * @param key {@code key} 81 | * @return 如果这个 {@code key} 在容器中已经储存有 {@code value} 并且删除成功则返回删除的 {@code value}, 否则返回 {@code null} 82 | */ 83 | @Nullable 84 | V remove(K key); 85 | 86 | /** 87 | * 如果这个 {@code key} 在缓存中有对应的 value 并且不为 {@code null}, 则返回 {@code true} 88 | * 89 | * @param key {@code key} 90 | * @return {@code true} 为在容器中含有这个 {@code key}, 否则为 {@code false} 91 | */ 92 | boolean containsKey(K key); 93 | 94 | /** 95 | * 返回当前缓存中含有的所有 {@code key} 96 | * 97 | * @return {@code keySet} 98 | */ 99 | Set keySet(); 100 | 101 | /** 102 | * 清除缓存中所有的内容 103 | */ 104 | void clear(); 105 | 106 | interface Factory { 107 | 108 | /** 109 | * Returns a new cache 110 | * 111 | * @param type 框架中需要缓存的模块类型 112 | * @return {@link Cache} 113 | */ 114 | @NonNull 115 | Cache build(CacheType type); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/integration/lifecycle/ActivityLifecycleForRxLifecycle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.integration.lifecycle; 17 | 18 | import android.app.Activity; 19 | import android.app.Application; 20 | import android.os.Bundle; 21 | 22 | import androidx.fragment.app.FragmentActivity; 23 | 24 | import com.trello.rxlifecycle2.RxLifecycle; 25 | import com.trello.rxlifecycle2.android.ActivityEvent; 26 | 27 | import javax.inject.Inject; 28 | import javax.inject.Singleton; 29 | 30 | import dagger.Lazy; 31 | import io.reactivex.subjects.Subject; 32 | 33 | /** 34 | * ================================================ 35 | * 配合 {@link ActivityLifecycleable} 使用,使 {@link Activity} 具有 {@link RxLifecycle} 的特性 36 | *

37 | * Created by JessYan on 25/08/2017 18:56 38 | * Contact me 39 | * Follow me 40 | * ================================================ 41 | */ 42 | @Singleton 43 | public class ActivityLifecycleForRxLifecycle implements Application.ActivityLifecycleCallbacks { 44 | @Inject 45 | Lazy mFragmentLifecycle; 46 | 47 | @Inject 48 | public ActivityLifecycleForRxLifecycle() { 49 | } 50 | 51 | /** 52 | * 通过桥梁对象 {@code BehaviorSubject mLifecycleSubject} 53 | * 在每个 Activity 的生命周期中发出对应的生命周期事件 54 | */ 55 | @Override 56 | public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 57 | if (activity instanceof ActivityLifecycleable) { 58 | obtainSubject(activity).onNext(ActivityEvent.CREATE); 59 | if (activity instanceof FragmentActivity) { 60 | ((FragmentActivity) activity).getSupportFragmentManager().registerFragmentLifecycleCallbacks(mFragmentLifecycle.get(), true); 61 | } 62 | } 63 | } 64 | 65 | @Override 66 | public void onActivityStarted(Activity activity) { 67 | if (activity instanceof ActivityLifecycleable) { 68 | obtainSubject(activity).onNext(ActivityEvent.START); 69 | } 70 | } 71 | 72 | @Override 73 | public void onActivityResumed(Activity activity) { 74 | if (activity instanceof ActivityLifecycleable) { 75 | obtainSubject(activity).onNext(ActivityEvent.RESUME); 76 | } 77 | } 78 | 79 | @Override 80 | public void onActivityPaused(Activity activity) { 81 | if (activity instanceof ActivityLifecycleable) { 82 | obtainSubject(activity).onNext(ActivityEvent.PAUSE); 83 | } 84 | } 85 | 86 | @Override 87 | public void onActivityStopped(Activity activity) { 88 | if (activity instanceof ActivityLifecycleable) { 89 | obtainSubject(activity).onNext(ActivityEvent.STOP); 90 | } 91 | } 92 | 93 | @Override 94 | public void onActivitySaveInstanceState(Activity activity, Bundle outState) { 95 | 96 | } 97 | 98 | @Override 99 | public void onActivityDestroyed(Activity activity) { 100 | if (activity instanceof ActivityLifecycleable) { 101 | obtainSubject(activity).onNext(ActivityEvent.DESTROY); 102 | } 103 | } 104 | 105 | /** 106 | * 从 {@link com.jess.arms.base.BaseActivity} 中获得桥梁对象 {@code BehaviorSubject mLifecycleSubject} 107 | * 108 | * @see BehaviorSubject 官方中文文档 109 | */ 110 | private Subject obtainSubject(Activity activity) { 111 | return ((ActivityLifecycleable) activity).provideLifecycleSubject(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/integration/lifecycle/ActivityLifecycleable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.integration.lifecycle; 17 | 18 | import android.app.Activity; 19 | 20 | import com.trello.rxlifecycle2.RxLifecycle; 21 | import com.trello.rxlifecycle2.android.ActivityEvent; 22 | 23 | /** 24 | * ================================================ 25 | * 让 {@link Activity} 实现此接口,即可正常使用 {@link RxLifecycle} 26 | *

27 | * Created by JessYan on 26/08/2017 17:14 28 | * Contact me 29 | * Follow me 30 | * ================================================ 31 | */ 32 | public interface ActivityLifecycleable extends Lifecycleable { 33 | } 34 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/integration/lifecycle/FragmentLifecycleable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.integration.lifecycle; 17 | 18 | import androidx.fragment.app.Fragment; 19 | 20 | import com.trello.rxlifecycle2.RxLifecycle; 21 | import com.trello.rxlifecycle2.android.FragmentEvent; 22 | 23 | /** 24 | * ================================================ 25 | * 让 {@link Fragment} 实现此接口,即可正常使用 {@link RxLifecycle} 26 | *

27 | * Created by JessYan on 26/08/2017 17:14 28 | * Contact me 29 | * Follow me 30 | * ================================================ 31 | */ 32 | public interface FragmentLifecycleable extends Lifecycleable { 33 | } 34 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/integration/lifecycle/Lifecycleable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.integration.lifecycle; 17 | 18 | import android.app.Activity; 19 | 20 | import androidx.annotation.NonNull; 21 | import androidx.fragment.app.Fragment; 22 | 23 | import com.jess.arms.utils.RxLifecycleUtils; 24 | import com.trello.rxlifecycle2.RxLifecycle; 25 | 26 | import io.reactivex.subjects.Subject; 27 | 28 | /** 29 | * ================================================ 30 | * 让 {@link Activity}/{@link Fragment} 实现此接口,即可正常使用 {@link RxLifecycle} 31 | * 无需再继承 {@link RxLifecycle} 提供的 Activity/Fragment ,扩展性极强 32 | * 33 | * @see RxLifecycleUtils 详细用法请查看此类 34 | * Created by JessYan on 25/08/2017 18:39 35 | * Contact me 36 | * Follow me 37 | * ================================================ 38 | */ 39 | public interface Lifecycleable { 40 | @NonNull 41 | Subject provideLifecycleSubject(); 42 | } 43 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/mvp/BaseModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.mvp; 17 | 18 | import androidx.lifecycle.Lifecycle; 19 | import androidx.lifecycle.LifecycleObserver; 20 | import androidx.lifecycle.LifecycleOwner; 21 | import androidx.lifecycle.OnLifecycleEvent; 22 | 23 | import com.jess.arms.integration.IRepositoryManager; 24 | 25 | /** 26 | * ================================================ 27 | * 基类 Model 28 | * 29 | * @see Model wiki 官方文档 30 | * Created by JessYan on 08/05/2016 12:55 31 | * Contact me 32 | * Follow me 33 | * ================================================ 34 | */ 35 | public class BaseModel implements IModel, LifecycleObserver { 36 | protected IRepositoryManager mRepositoryManager;//用于管理网络请求层, 以及数据缓存层 37 | 38 | public BaseModel(IRepositoryManager repositoryManager) { 39 | this.mRepositoryManager = repositoryManager; 40 | } 41 | 42 | /** 43 | * 在框架中 {@link BasePresenter#onDestroy()} 时会默认调用 {@link IModel#onDestroy()} 44 | */ 45 | @Override 46 | public void onDestroy() { 47 | mRepositoryManager = null; 48 | } 49 | 50 | @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 51 | void onDestroy(LifecycleOwner owner) { 52 | owner.getLifecycle().removeObserver(this); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/mvp/IModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.mvp; 17 | 18 | /** 19 | * ================================================ 20 | * 框架要求框架中的每个 Model 都需要实现此类,以满足规范 21 | * 22 | * @see BaseModel 23 | * @see Model wiki 官方文档 24 | * Created by JessYan on 15/12/2016 10:45 25 | * Contact me 26 | * Follow me 27 | * ================================================ 28 | */ 29 | public interface IModel { 30 | 31 | /** 32 | * 在框架中 {@link BasePresenter#onDestroy()} 时会默认调用 {@link IModel#onDestroy()} 33 | */ 34 | void onDestroy(); 35 | } 36 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/mvp/IPresenter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.mvp; 17 | 18 | import android.app.Activity; 19 | 20 | /** 21 | * ================================================ 22 | * 框架要求框架中的每个 Presenter 都需要实现此类,以满足规范 23 | * 24 | * @see BasePresenter 25 | * @see Presenter wiki 官方文档 26 | * Created by JessYan on 4/28/2016 27 | * Contact me 28 | * Follow me 29 | * ================================================ 30 | */ 31 | public interface IPresenter { 32 | 33 | /** 34 | * 做一些初始化操作 35 | */ 36 | void onStart(); 37 | 38 | /** 39 | * 在框架中 {@link Activity#onDestroy()} 时会默认调用 {@link IPresenter#onDestroy()} 40 | */ 41 | void onDestroy(); 42 | } 43 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/mvp/IView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.mvp; 17 | 18 | import android.app.Activity; 19 | import android.content.Intent; 20 | 21 | import androidx.annotation.NonNull; 22 | 23 | import com.jess.arms.utils.ArmsUtils; 24 | 25 | import static com.jess.arms.utils.Preconditions.checkNotNull; 26 | 27 | /** 28 | * ================================================ 29 | * 框架要求框架中的每个 View 都需要实现此类, 以满足规范 30 | *

31 | * 为了满足部分人的诉求以及向下兼容, {@link IView} 中的部分方法使用 JAVA 1.8 的默认方法实现, 这样实现类可以按实际需求选择是否实现某些方法 32 | * 不实现则使用默认方法中的逻辑, 不清楚默认方法的请自行学习 33 | * 34 | * @see View wiki 官方文档 35 | * Created by JessYan on 4/22/2016 36 | * Contact me 37 | * Follow me 38 | * ================================================ 39 | */ 40 | public interface IView { 41 | 42 | /** 43 | * 显示加载 44 | */ 45 | default void showLoading() { 46 | 47 | } 48 | 49 | /** 50 | * 隐藏加载 51 | */ 52 | default void hideLoading() { 53 | 54 | } 55 | 56 | /** 57 | * 显示信息 58 | * 59 | * @param message 消息内容, 不能为 {@code null} 60 | */ 61 | void showMessage(@NonNull String message); 62 | 63 | /** 64 | * 跳转 {@link Activity} 65 | * 66 | * @param intent {@code intent} 不能为 {@code null} 67 | */ 68 | default void launchActivity(@NonNull Intent intent) { 69 | checkNotNull(intent); 70 | ArmsUtils.startActivity(intent); 71 | } 72 | 73 | /** 74 | * 杀死自己 75 | */ 76 | default void killMyself() { 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/utils/LogUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 com.jess.arms.utils; 17 | 18 | import android.text.TextUtils; 19 | import android.util.Log; 20 | 21 | /** 22 | * ================================================ 23 | * 日志工具类 24 | *

25 | * Created by JessYan on 2015/11/23. 26 | * Contact me 27 | * Follow me 28 | * ================================================ 29 | */ 30 | public class LogUtils { 31 | private static final String DEFAULT_TAG = "MVPArms"; 32 | private static boolean isLog = true; 33 | 34 | private LogUtils() { 35 | throw new IllegalStateException("you can't instantiate me!"); 36 | } 37 | 38 | public static boolean isLog() { 39 | return isLog; 40 | } 41 | 42 | public static void setLog(boolean isLog) { 43 | LogUtils.isLog = isLog; 44 | } 45 | 46 | public static void debugInfo(String tag, String msg) { 47 | if (!isLog || TextUtils.isEmpty(msg)) { 48 | return; 49 | } 50 | Log.d(tag, msg); 51 | 52 | } 53 | 54 | public static void debugInfo(String msg) { 55 | debugInfo(DEFAULT_TAG, msg); 56 | } 57 | 58 | public static void warnInfo(String tag, String msg) { 59 | if (!isLog || TextUtils.isEmpty(msg)) { 60 | return; 61 | } 62 | Log.w(tag, msg); 63 | 64 | } 65 | 66 | public static void warnInfo(String msg) { 67 | warnInfo(DEFAULT_TAG, msg); 68 | } 69 | 70 | /** 71 | * 这里使用自己分节的方式来输出足够长度的 message 72 | * 73 | * @param tag 标签 74 | * @param msg 日志内容 75 | */ 76 | public static void debugLongInfo(String tag, String msg) { 77 | if (!isLog || TextUtils.isEmpty(msg)) { 78 | return; 79 | } 80 | msg = msg.trim(); 81 | int index = 0; 82 | int maxLength = 3500; 83 | String sub; 84 | while (index < msg.length()) { 85 | if (msg.length() <= index + maxLength) { 86 | sub = msg.substring(index); 87 | } else { 88 | sub = msg.substring(index, index + maxLength); 89 | } 90 | 91 | index += maxLength; 92 | Log.d(tag, sub.trim()); 93 | } 94 | } 95 | 96 | public static void debugLongInfo(String msg) { 97 | debugLongInfo(DEFAULT_TAG, msg); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /arms/src/main/java/com/jess/arms/utils/UrlEncoderUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 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 com.jess.arms.utils; 17 | 18 | /** 19 | * ================================================ 20 | * Created by JessYan on 2018/9/14 14:10 21 | * Contact me 22 | * Follow me 23 | * ================================================ 24 | */ 25 | public class UrlEncoderUtils { 26 | 27 | private UrlEncoderUtils() { 28 | throw new IllegalStateException("you can't instantiate me!"); 29 | } 30 | 31 | /** 32 | * 判断 str 是否已经 URLEncoder.encode() 过 33 | * 经常遇到这样的情况, 拿到一个 URL, 但是搞不清楚到底要不要 URLEncoder.encode() 34 | * 不做 URLEncoder.encode() 吧, 担心出错, 做 URLEncoder.encode() 吧, 又怕重复了 35 | * 36 | * @param str 需要判断的内容 37 | * @return 返回 {@code true} 为被 URLEncoder.encode() 过 38 | */ 39 | public static boolean hasUrlEncoded(String str) { 40 | boolean encode = false; 41 | for (int i = 0; i < str.length(); i++) { 42 | char c = str.charAt(i); 43 | if (c == '%' && (i + 2) < str.length()) { 44 | // 判断是否符合urlEncode规范 45 | char c1 = str.charAt(i + 1); 46 | char c2 = str.charAt(i + 2); 47 | if (isValidHexChar(c1) && isValidHexChar(c2)) { 48 | encode = true; 49 | break; 50 | } else { 51 | break; 52 | } 53 | } 54 | } 55 | return encode; 56 | } 57 | 58 | /** 59 | * 判断 c 是否是 16 进制的字符 60 | * 61 | * @param c 需要判断的字符 62 | * @return 返回 {@code true} 为 16 进制的字符 63 | */ 64 | private static boolean isValidHexChar(char c) { 65 | return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /arms/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | arms 3 | 4 | -------------------------------------------------------------------------------- /bintray.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.jfrog.bintray' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | 4 | Properties properties = new Properties() 5 | boolean isHasFile = false 6 | if (project.rootProject.findProject('local.properties') != null) { 7 | isHasFile = true 8 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 9 | } 10 | 11 | def gitUrl = 'https://github.com/JessYanCoding/MVPArms.git' // Git仓库的url 12 | def siteUrl = 'https://github.com/JessYanCoding/MVPArms' // 项目的主页 13 | 14 | version = rootProject.ext.android["versionName"] 15 | group = "me.jessyan" 16 | 17 | 18 | bintray { 19 | user = isHasFile ? properties.getProperty("bintray.user") : System.getenv("bintray_user") 20 | key = isHasFile ? properties.getProperty("bintray.apikey") : System.getenv("bintray_apikey") 21 | 22 | pkg { 23 | repo = 'maven' 24 | name = POM_NAME 25 | licenses = ["Apache-2.0"] 26 | websiteUrl = siteUrl 27 | vcsUrl = gitUrl 28 | publish = true // 是否是公开项目。 29 | 30 | version { 31 | name = rootProject.ext.android["versionName"] 32 | desc = 'A common Architecture for Android Applications developing based on MVP,integrates many Open Source Projects( like Dagger2,RxJava,Retrofit... ),to make your developing quicker and easier.' 33 | released = new Date() 34 | vcsTag = 'v' + rootProject.ext.android["versionName"] 35 | attributes = ['gradle-plugin': 'com.use.less:com.use.less.gradle:gradle-useless-plugin'] 36 | } 37 | } 38 | configurations = ['archives'] 39 | } 40 | 41 | 42 | install { 43 | repositories.mavenInstaller { 44 | // This generates POM.xml with proper parameters 45 | pom { 46 | project { 47 | packaging 'aar' 48 | // Add your description here 49 | name POM_NAME 50 | description 'A common Architecture for Android Applications developing based on MVP,integrates many Open Source Projects( like Dagger2,RxJava,Retrofit... ),to make your developing quicker and easier.' 51 | url siteUrl 52 | // Set your license 53 | licenses { 54 | license { 55 | name 'The Apache Software License, Version 2.0' 56 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 57 | } 58 | } 59 | developers { 60 | developer { 61 | id 'JessYanCoding' //填写bintray或者github的用户名 62 | name 'jessyan' //姓名,可以是中文 63 | email 'jess.yan.effort@gmail.com' 64 | } 65 | } 66 | scm { 67 | connection gitUrl 68 | developerConnection gitUrl 69 | url siteUrl 70 | } 71 | } 72 | } 73 | } 74 | } 75 | 76 | task sourcesJar(type: Jar) { 77 | from android.sourceSets.main.java.srcDirs 78 | classifier = 'sources' 79 | } 80 | task javadoc(type: Javadoc) { 81 | failOnError false 82 | source = android.sourceSets.main.java.srcDirs 83 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 84 | } 85 | task javadocJar(type: Jar, dependsOn: javadoc) { 86 | classifier = 'javadoc' 87 | from javadoc.destinationDir 88 | } 89 | artifacts { 90 | archives javadocJar 91 | archives sourcesJar 92 | } 93 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | apply from: "config.gradle" 3 | buildscript { 4 | repositories { 5 | google() 6 | maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' } 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.6.0' 10 | //Gradle Android Maven plugin 11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' 12 | //Gradle Bintray Plugin 13 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0' 14 | } 15 | } 16 | 17 | allprojects { 18 | tasks.withType(Test).configureEach { 19 | maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 20 | if (!project.hasProperty("createReports")) { 21 | reports.html.required = false 22 | reports.junitXml.required = false 23 | } 24 | } 25 | 26 | repositories { 27 | google() 28 | maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' } 29 | maven { url "https://jitpack.io" } 30 | } 31 | } 32 | 33 | task clean(type: Delete) { 34 | delete rootProject.buildDir 35 | } 36 | 37 | configurations.all { 38 | resolutionStrategy { 39 | eachDependency { details -> 40 | // Force all of the primary libraries to use the same version. 41 | if (details.requested.name == 'appcompat' 42 | && details.requested.name == 'annotation' 43 | && details.requested.name == 'recyclerview') { 44 | details.useVersion rootProject.ext.version["androidXSdkVersion"] 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.android["compileSdkVersion"] 5 | buildToolsVersion rootProject.ext.android["buildToolsVersion"] 6 | useLibrary 'org.apache.http.legacy' 7 | 8 | compileOptions { 9 | targetCompatibility JavaVersion.VERSION_1_8 10 | sourceCompatibility JavaVersion.VERSION_1_8 11 | } 12 | 13 | defaultConfig { 14 | applicationId "me.jessyan.mvparms.demo" 15 | minSdkVersion rootProject.ext.android["minSdkVersion"] 16 | targetSdkVersion rootProject.ext.android["targetSdkVersion"] 17 | versionCode rootProject.ext.android["versionCode"] 18 | versionName rootProject.ext.android["versionName"] 19 | testInstrumentationRunner rootProject.ext.dependencies["androidJUnitRunner"] 20 | } 21 | 22 | buildTypes { 23 | debug { 24 | buildConfigField "boolean", "LOG_DEBUG", "true" 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 27 | } 28 | 29 | release { 30 | buildConfigField "boolean", "LOG_DEBUG", "false" 31 | minifyEnabled true 32 | shrinkResources true 33 | zipAlignEnabled true 34 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 35 | } 36 | } 37 | 38 | lintOptions { 39 | disable 'InvalidPackage' 40 | disable "ResourceType" 41 | abortOnError false 42 | } 43 | } 44 | 45 | dependencies { 46 | implementation fileTree(include: ['*.jar'], dir: 'libs') 47 | 48 | //androidx 49 | implementation rootProject.ext.dependencies["cardview"] 50 | 51 | //tools 52 | //注意 Arms 核心库现在并不会依赖某个 EventBus, 要想使用 EventBus, 还请在项目中自行依赖对应的 EventBus 53 | //现在支持两种 EventBus, greenrobot 的 EventBus 和畅销书 《Android源码设计模式解析与实战》的作者 何红辉 所作的 AndroidEventBus 54 | //依赖后 Arms 会自动检测您依赖的 EventBus 并自动注册 55 | //建议使用 AndroidEventBus, 特别是组件化项目, 原因请看 https://github.com/hehonghui/AndroidEventBus/issues/49 56 | //这种做法可以让使用者有自行选择三方库的权利, 并且还可以减轻 Arms 的体积 57 | implementation rootProject.ext.dependencies["androideventbus"] 58 | // implementation rootProject.ext.dependencies["eventbus"] 59 | 60 | annotationProcessor rootProject.ext.dependencies["dagger2-compiler"] 61 | implementation rootProject.ext.dependencies["progressmanager"] 62 | implementation rootProject.ext.dependencies["retrofit-url-manager"] 63 | implementation rootProject.ext.dependencies["lifecyclemodel"] 64 | 65 | //view 66 | annotationProcessor(rootProject.ext.dependencies["butterknife-compiler"]) { 67 | exclude module: 'annotation' 68 | } 69 | implementation(rootProject.ext.dependencies["paginate"]) { 70 | exclude module: 'recyclerview' 71 | } 72 | 73 | //arms 74 | implementation project(':arms') 75 | // implementation 'me.jessyan:arms:2.5.2' 76 | 77 | //Arms 核心库不再包含 AndroidAutoLayout, 现在可自行选择屏幕适配方案, 不想使用 AndroidAutoLayout 就不要依赖 arms-autolayout 78 | // implementation 'me.jessyan:arms-autolayout:2.5.2' 79 | 80 | //现在已经将 Demo 中的屏幕适配框架从 AndroidAutoLayout 替换为 AndroidAutoSize, AndroidAutoLayout 和 AndroidAutoSize 可以在项目中共存 81 | //所以旧项目只要依赖 arms-autolayout 即可兼容之前的旧页面, 新页面可以使用 AndroidAutoSize 进行适配, 等有时间了再将旧页面全部替换为 AndroidAutoSize 82 | implementation rootProject.ext.dependencies["autosize"] 83 | 84 | //Arms 核心库不再包含 Glide, 想使用其他图片加载框架或者想自行扩展 ImageLoaderStrategy 就不要依赖 arms-imageloader-glide 85 | //依赖 arms-imageloader-glide 后还需要在 GlobalConfiguration 中手动注册 GlideImageLoaderStrategy 86 | // implementation 'me.jessyan:arms-imageloader-glide:2.5.2' 87 | implementation project(':arms-imageloader-glide') 88 | 89 | //test 90 | testImplementation rootProject.ext.dependencies["junit"] 91 | debugImplementation rootProject.ext.dependencies["canary-debug"] 92 | } 93 | -------------------------------------------------------------------------------- /demo/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 /Users/jess/Library/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 | # 混淆规则在 arms moudule 下的 proguard-rules.pro 中, 混淆前先参阅 https://github.com/JessYanCoding/MVPArms/wiki#1.5 -------------------------------------------------------------------------------- /demo/src/androidTest/java/me/jessyan/mvparms/demo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package me.jessyan.mvparms.demo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /demo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 37 | 40 | 41 | 42 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/app/ActivityLifecycleCallbacksImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.app; 17 | 18 | import android.app.Activity; 19 | import android.app.Application; 20 | import android.os.Build; 21 | import android.os.Bundle; 22 | import android.widget.TextView; 23 | 24 | import androidx.appcompat.app.AppCompatActivity; 25 | 26 | import java.util.Objects; 27 | 28 | import me.jessyan.mvparms.demo.R; 29 | import timber.log.Timber; 30 | 31 | /** 32 | * ================================================ 33 | * 展示 {@link Application.ActivityLifecycleCallbacks} 的用法 34 | *

35 | * Created by JessYan on 04/09/2017 17:14 36 | * Contact me 37 | * Follow me 38 | * ================================================ 39 | */ 40 | public class ActivityLifecycleCallbacksImpl implements Application.ActivityLifecycleCallbacks { 41 | 42 | @Override 43 | public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 44 | Timber.i("%s - onActivityCreated", activity); 45 | } 46 | 47 | @Override 48 | public void onActivityStarted(Activity activity) { 49 | Timber.i("%s - onActivityStarted", activity); 50 | if (!activity.getIntent().getBooleanExtra("isInitToolbar", false)) { 51 | //由于加强框架的兼容性,故将 setContentView 放到 onActivityCreated 之后,onActivityStarted 之前执行 52 | //而 findViewById 必须在 Activity setContentView() 后才有效,所以将以下代码从之前的 onActivityCreated 中移动到 onActivityStarted 中执行 53 | activity.getIntent().putExtra("isInitToolbar", true); 54 | //这里全局给Activity设置toolbar和title,你想象力有多丰富,这里就有多强大,以前放到BaseActivity的操作都可以放到这里 55 | if (activity.findViewById(R.id.toolbar) != null) { 56 | if (activity instanceof AppCompatActivity) { 57 | ((AppCompatActivity) activity).setSupportActionBar(activity.findViewById(R.id.toolbar)); 58 | Objects.requireNonNull(((AppCompatActivity) activity).getSupportActionBar()).setDisplayShowTitleEnabled(false); 59 | } else { 60 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 61 | activity.setActionBar(activity.findViewById(R.id.toolbar)); 62 | Objects.requireNonNull(activity.getActionBar()).setDisplayShowTitleEnabled(false); 63 | } 64 | } 65 | } 66 | if (activity.findViewById(R.id.toolbar_title) != null) { 67 | ((TextView) activity.findViewById(R.id.toolbar_title)).setText(activity.getTitle()); 68 | } 69 | if (activity.findViewById(R.id.toolbar_back) != null) { 70 | activity.findViewById(R.id.toolbar_back).setOnClickListener(v -> activity.onBackPressed()); 71 | } 72 | } 73 | } 74 | 75 | @Override 76 | public void onActivityResumed(Activity activity) { 77 | Timber.i("%s - onActivityResumed", activity); 78 | } 79 | 80 | @Override 81 | public void onActivityPaused(Activity activity) { 82 | Timber.i("%s - onActivityPaused", activity); 83 | } 84 | 85 | @Override 86 | public void onActivityStopped(Activity activity) { 87 | Timber.i("%s - onActivityStopped", activity); 88 | } 89 | 90 | @Override 91 | public void onActivitySaveInstanceState(Activity activity, Bundle outState) { 92 | Timber.i("%s - onActivitySaveInstanceState", activity); 93 | } 94 | 95 | @Override 96 | public void onActivityDestroyed(Activity activity) { 97 | Timber.i("%s - onActivityDestroyed", activity); 98 | //横竖屏切换或配置改变时, Activity 会被重新创建实例, 但 Bundle 中的基础数据会被保存下来,移除该数据是为了保证重新创建的实例可以正常工作 99 | activity.getIntent().removeExtra("isInitToolbar"); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/app/AppLifecyclesImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.app; 17 | 18 | import android.app.Application; 19 | import android.content.Context; 20 | 21 | import com.jess.arms.base.delegate.AppLifecycles; 22 | 23 | import androidx.annotation.NonNull; 24 | import butterknife.ButterKnife; 25 | import me.jessyan.mvparms.demo.BuildConfig; 26 | import timber.log.Timber; 27 | 28 | /** 29 | * ================================================ 30 | * 展示 {@link AppLifecycles} 的用法 31 | *

32 | * Created by JessYan on 04/09/2017 17:12 33 | * Contact me 34 | * Follow me 35 | * ================================================ 36 | */ 37 | public class AppLifecyclesImpl implements AppLifecycles { 38 | 39 | @Override 40 | public void attachBaseContext(@NonNull Context base) { 41 | // MultiDex.install(base); //这里比 onCreate 先执行,常用于 MultiDex 初始化,插件化框架的初始化 42 | } 43 | 44 | @Override 45 | public void onCreate(@NonNull Application application) { 46 | if (BuildConfig.LOG_DEBUG) {//Timber初始化 47 | //Timber 是一个日志框架容器,外部使用统一的Api,内部可以动态的切换成任何日志框架(打印策略)进行日志打印 48 | //并且支持添加多个日志框架(打印策略),做到外部调用一次 Api,内部却可以做到同时使用多个策略 49 | //比如添加三个策略,一个打印日志,一个将日志保存本地,一个将日志上传服务器 50 | Timber.plant(new Timber.DebugTree()); 51 | // 如果你想将框架切换为 Logger 来打印日志,请使用下面的代码,如想切换为其他日志框架请根据下面的方式扩展 52 | // Logger.addLogAdapter(new AndroidLogAdapter()); 53 | // Timber.plant(new Timber.DebugTree() { 54 | // @Override 55 | // protected void log(int priority, String tag, String message, Throwable t) { 56 | // Logger.log(priority, tag, message, t); 57 | // } 58 | // }); 59 | ButterKnife.setDebug(true); 60 | } 61 | //LeakCanary v2.0+ 版本会自动完成框架的初始化, 以及对 Activity#onDestroy、Fragment#onDestroy、Fragment#onDestroyView 的监听 62 | //原理和 AndroidAutoSize 一致, 所以注释掉下面 v1.0 的初始化代码 63 | //使用 IntelligentCache.KEY_KEEP 作为 key 的前缀, 可以使储存的数据永久存储在内存中 64 | //否则存储在 LRU 算法的存储空间中, 前提是 extras 使用的是 IntelligentCache (框架默认使用) 65 | // ArmsUtils.obtainAppComponentFromContext(application).extras() 66 | // .put(IntelligentCache.getKeyOfKeep(RefWatcher.class.getName()) 67 | // , BuildConfig.USE_CANARY ? LeakCanary.install(application) : RefWatcher.DISABLED); 68 | } 69 | 70 | @Override 71 | public void onTerminate(@NonNull Application application) { 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/app/EventBusTags.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.app; 17 | 18 | /** 19 | * ================================================ 20 | * 放置 AndroidEventBus 的 Tag, 便于检索 21 | * Arms 核心库现在并不会依赖某个 EventBus, 要想使用 EventBus, 还请在项目中自行依赖对应的 EventBus 22 | * 现在支持两种 EventBus, greenrobot 的 EventBus 和畅销书 《Android源码设计模式解析与实战》的作者 何红辉 所作的 AndroidEventBus 23 | * 24 | * @see EventBusTags wiki 官方文档 25 | * Created by JessYan on 8/30/2016 16:39 26 | * Contact me 27 | * Follow me 28 | * ================================================ 29 | */ 30 | public interface EventBusTags { 31 | 32 | } 33 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/app/FragmentLifecycleCallbacksImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 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 me.jessyan.mvparms.demo.app; 17 | 18 | import android.content.Context; 19 | import android.os.Bundle; 20 | import android.view.View; 21 | 22 | import org.jetbrains.annotations.NotNull; 23 | 24 | import androidx.annotation.NonNull; 25 | import androidx.fragment.app.Fragment; 26 | import androidx.fragment.app.FragmentManager; 27 | import timber.log.Timber; 28 | 29 | /** 30 | * ================================================ 31 | * 展示 {@link FragmentManager.FragmentLifecycleCallbacks} 的用法 32 | *

33 | * Created by JessYan on 23/08/2018 17:14 34 | * Contact me 35 | * Follow me 36 | * ================================================ 37 | */ 38 | public class FragmentLifecycleCallbacksImpl extends FragmentManager.FragmentLifecycleCallbacks { 39 | 40 | @Override 41 | public void onFragmentAttached(@NotNull @NonNull FragmentManager fm, Fragment f, @NotNull Context context) { 42 | Timber.i("%s - onFragmentAttached", f.toString()); 43 | } 44 | 45 | @Override 46 | public void onFragmentCreated(@NotNull FragmentManager fm, Fragment f, Bundle savedInstanceState) { 47 | Timber.i("%s - onFragmentCreated", f.toString()); 48 | // 在配置变化的时候将这个 Fragment 保存下来,在 Activity 由于配置变化重建时重复利用已经创建的 Fragment。 49 | // https://developer.android.com/reference/android/app/Fragment.html?hl=zh-cn#setRetainInstance(boolean) 50 | // 如果在 XML 中使用 标签,的方式创建 Fragment 请务必在标签中加上 android:id 或者 android:tag 属性,否则 setRetainInstance(true) 无效 51 | // 在 Activity 中绑定少量的 Fragment 建议这样做,如果需要绑定较多的 Fragment 不建议设置此参数,如 ViewPager 需要展示较多 Fragment 52 | f.setRetainInstance(true); 53 | } 54 | 55 | @Override 56 | public void onFragmentViewCreated(@NotNull FragmentManager fm, Fragment f, @NotNull View v, Bundle savedInstanceState) { 57 | Timber.i("%s - onFragmentViewCreated", f.toString()); 58 | } 59 | 60 | @Override 61 | public void onFragmentActivityCreated(@NotNull FragmentManager fm, Fragment f, Bundle savedInstanceState) { 62 | Timber.i("%s - onFragmentActivityCreated", f.toString()); 63 | } 64 | 65 | @Override 66 | public void onFragmentStarted(@NotNull FragmentManager fm, Fragment f) { 67 | Timber.i("%s - onFragmentStarted", f.toString()); 68 | } 69 | 70 | @Override 71 | public void onFragmentResumed(@NotNull FragmentManager fm, Fragment f) { 72 | Timber.i("%s - onFragmentResumed", f.toString()); 73 | } 74 | 75 | @Override 76 | public void onFragmentPaused(@NotNull FragmentManager fm, Fragment f) { 77 | Timber.i("%s - onFragmentPaused", f.toString()); 78 | } 79 | 80 | @Override 81 | public void onFragmentStopped(@NotNull FragmentManager fm, Fragment f) { 82 | Timber.i("%s - onFragmentStopped", f.toString()); 83 | } 84 | 85 | @Override 86 | public void onFragmentSaveInstanceState(@NotNull FragmentManager fm, Fragment f, @NotNull Bundle outState) { 87 | Timber.i("%s - onFragmentSaveInstanceState", f.toString()); 88 | } 89 | 90 | @Override 91 | public void onFragmentViewDestroyed(@NotNull FragmentManager fm, Fragment f) { 92 | Timber.i("%s - onFragmentViewDestroyed", f.toString()); 93 | } 94 | 95 | @Override 96 | public void onFragmentDestroyed(@NotNull FragmentManager fm, Fragment f) { 97 | Timber.i("%s - onFragmentDestroyed", f.toString()); 98 | } 99 | 100 | @Override 101 | public void onFragmentDetached(@NotNull FragmentManager fm, Fragment f) { 102 | Timber.i("%s - onFragmentDetached", f.toString()); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/app/GlobalHttpHandlerImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.app; 17 | 18 | import android.content.Context; 19 | import android.text.TextUtils; 20 | 21 | import androidx.annotation.NonNull; 22 | import androidx.annotation.Nullable; 23 | 24 | import com.google.gson.reflect.TypeToken; 25 | import com.jess.arms.http.GlobalHttpHandler; 26 | import com.jess.arms.http.log.RequestInterceptor; 27 | import com.jess.arms.utils.ArmsUtils; 28 | 29 | import java.util.List; 30 | 31 | import me.jessyan.mvparms.demo.mvp.model.entity.User; 32 | import okhttp3.Interceptor; 33 | import okhttp3.Request; 34 | import okhttp3.Response; 35 | import timber.log.Timber; 36 | 37 | /** 38 | * ================================================ 39 | * 展示 {@link GlobalHttpHandler} 的用法 40 | *

41 | * Created by JessYan on 04/09/2017 17:06 42 | * Contact me 43 | * Follow me 44 | * ================================================ 45 | */ 46 | public class GlobalHttpHandlerImpl implements GlobalHttpHandler { 47 | private Context context; 48 | 49 | public GlobalHttpHandlerImpl(Context context) { 50 | this.context = context; 51 | } 52 | 53 | /** 54 | * 这里可以先客户端一步拿到每一次 Http 请求的结果, 可以先解析成 Json, 再做一些操作, 如检测到 token 过期后 55 | * 重新请求 token, 并重新执行请求 56 | * 57 | * @param httpResult 服务器返回的结果 (已被框架自动转换为字符串) 58 | * @param chain {@link okhttp3.Interceptor.Chain} 59 | * @param response {@link Response} 60 | * @return {@link Response} 61 | */ 62 | @NonNull 63 | @Override 64 | public Response onHttpResultResponse(@Nullable String httpResult, @NonNull Interceptor.Chain chain, @NonNull Response response) { 65 | if (!TextUtils.isEmpty(httpResult) && RequestInterceptor.isJson(response.body().contentType())) { 66 | try { 67 | List list = ArmsUtils.obtainAppComponentFromContext(context).gson().fromJson(httpResult, new TypeToken>() { 68 | }.getType()); 69 | User user = list.get(0); 70 | Timber.w("Result ------> " + user.getLogin() + " || Avatar_url------> " + user.getAvatarUrl()); 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | return response; 74 | } 75 | } 76 | 77 | /* 这里如果发现 token 过期, 可以先请求最新的 token, 然后在拿新的 token 放入 Request 里去重新请求 78 | 注意在这个回调之前已经调用过 proceed(), 所以这里必须自己去建立网络请求, 如使用 Okhttp 使用新的 Request 去请求 79 | create a new request and modify it accordingly using the new token 80 | Request newRequest = chain.request().newBuilder().header("token", newToken) 81 | .build(); 82 | 83 | retry the request 84 | 85 | response.body().close(); 86 | 如果使用 Okhttp 将新的请求, 请求成功后, 再将 Okhttp 返回的 Response return 出去即可 87 | 如果不需要返回新的结果, 则直接把参数 response 返回出去即可*/ 88 | return response; 89 | } 90 | 91 | /** 92 | * 这里可以在请求服务器之前拿到 {@link Request}, 做一些操作比如给 {@link Request} 统一添加 token 或者 header 以及参数加密等操作 93 | * 94 | * @param chain {@link okhttp3.Interceptor.Chain} 95 | * @param request {@link Request} 96 | * @return {@link Request} 97 | */ 98 | @NonNull 99 | @Override 100 | public Request onHttpRequestBefore(@NonNull Interceptor.Chain chain, @NonNull Request request) { 101 | /* 如果需要在请求服务器之前做一些操作, 则重新构建一个做过操作的 Request 并 return, 如增加 Header、Params 等请求信息, 不做操作则直接返回参数 request 102 | return chain.request().newBuilder().header("token", tokenId) 103 | .build(); */ 104 | return request; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/app/ResponseErrorListenerImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.app; 17 | 18 | import android.content.Context; 19 | import android.net.ParseException; 20 | 21 | import com.google.gson.JsonIOException; 22 | import com.google.gson.JsonParseException; 23 | import com.jess.arms.utils.ArmsUtils; 24 | 25 | import org.json.JSONException; 26 | 27 | import java.net.SocketTimeoutException; 28 | import java.net.UnknownHostException; 29 | 30 | import me.jessyan.rxerrorhandler.handler.listener.ResponseErrorListener; 31 | import retrofit2.HttpException; 32 | import timber.log.Timber; 33 | 34 | /** 35 | * ================================================ 36 | * 展示 {@link ResponseErrorListener} 的用法 37 | *

38 | * Created by JessYan on 04/09/2017 17:18 39 | * Contact me 40 | * Follow me 41 | * ================================================ 42 | */ 43 | public class ResponseErrorListenerImpl implements ResponseErrorListener { 44 | 45 | @Override 46 | public void handleResponseError(Context context, Throwable t) { 47 | Timber.tag("Catch-Error").w(t); 48 | //这里不光只能打印错误, 还可以根据不同的错误做出不同的逻辑处理 49 | //这里只是对几个常用错误进行简单的处理, 展示这个类的用法, 在实际开发中请您自行对更多错误进行更严谨的处理 50 | String msg = "未知错误"; 51 | if (t instanceof UnknownHostException) { 52 | msg = "网络不可用"; 53 | } else if (t instanceof SocketTimeoutException) { 54 | msg = "请求网络超时"; 55 | } else if (t instanceof HttpException) { 56 | HttpException httpException = (HttpException) t; 57 | msg = convertStatusCode(httpException); 58 | } else if (t instanceof JsonParseException || t instanceof ParseException || t instanceof JSONException || t instanceof JsonIOException) { 59 | msg = "数据解析错误"; 60 | } 61 | ArmsUtils.snackbarText(msg); 62 | } 63 | 64 | private String convertStatusCode(HttpException httpException) { 65 | String msg; 66 | if (httpException.code() == 500) { 67 | msg = "服务器发生错误"; 68 | } else if (httpException.code() == 404) { 69 | msg = "请求地址不存在"; 70 | } else if (httpException.code() == 403) { 71 | msg = "请求被服务器拒绝"; 72 | } else if (httpException.code() == 307) { 73 | msg = "请求被重定向到其他页面"; 74 | } else { 75 | msg = httpException.message(); 76 | } 77 | return msg; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/app/service/DemoService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.app.service; 17 | 18 | import com.jess.arms.base.BaseService; 19 | 20 | /** 21 | * ================================================ 22 | * 展示 {@link BaseService} 的用法 23 | *

24 | * Created by JessYan on 09/07/2016 16:59 25 | * Contact me 26 | * Follow me 27 | * ================================================ 28 | */ 29 | public class DemoService extends BaseService { 30 | @Override 31 | public void init() { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/app/utils/RxUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.app.utils; 17 | 18 | import com.jess.arms.mvp.IView; 19 | import com.jess.arms.utils.RxLifecycleUtils; 20 | import com.trello.rxlifecycle2.LifecycleTransformer; 21 | import com.trello.rxlifecycle2.RxLifecycle; 22 | 23 | import io.reactivex.ObservableTransformer; 24 | import io.reactivex.android.schedulers.AndroidSchedulers; 25 | import io.reactivex.schedulers.Schedulers; 26 | 27 | /** 28 | * ================================================ 29 | * 放置便于使用 RxJava 的一些工具方法 30 | *

31 | * Created by JessYan on 11/10/2016 16:39 32 | * Contact me 33 | * Follow me 34 | * ================================================ 35 | */ 36 | public class RxUtils { 37 | 38 | private RxUtils() { 39 | } 40 | 41 | public static ObservableTransformer applySchedulers(final IView view) { 42 | return observable -> observable.subscribeOn(Schedulers.io()) 43 | .doOnSubscribe(disposable -> { 44 | view.showLoading();//显示进度条 45 | }) 46 | .subscribeOn(AndroidSchedulers.mainThread()) 47 | .observeOn(AndroidSchedulers.mainThread()) 48 | .doFinally(() -> { 49 | view.hideLoading();//隐藏进度条 50 | }).compose(RxLifecycleUtils.bindToLifecycle(view)); 51 | } 52 | 53 | /** 54 | * 此方法已废弃 55 | * 56 | * @param view 57 | * @param 58 | * @return 59 | * @see RxLifecycleUtils 此类可以实现 {@link RxLifecycle} 的所有功能, 使用方法和之前一致 60 | * @deprecated Use {@link RxLifecycleUtils#bindToLifecycle(IView)} instead 61 | */ 62 | @Deprecated 63 | public static LifecycleTransformer bindToLifecycle(IView view) { 64 | return RxLifecycleUtils.bindToLifecycle(view); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/di/component/UserComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.di.component; 17 | 18 | import com.jess.arms.di.component.AppComponent; 19 | import com.jess.arms.di.scope.ActivityScope; 20 | 21 | import dagger.BindsInstance; 22 | import dagger.Component; 23 | import me.jessyan.mvparms.demo.di.module.UserModule; 24 | import me.jessyan.mvparms.demo.mvp.contract.UserContract; 25 | import me.jessyan.mvparms.demo.mvp.ui.activity.UserActivity; 26 | 27 | /** 28 | * ================================================ 29 | * 展示 Component 的用法 30 | * 31 | * @see Component wiki 官方文档 32 | * Created by JessYan on 09/04/2016 11:17 33 | * Contact me 34 | * Follow me 35 | * ================================================ 36 | */ 37 | @ActivityScope 38 | @Component(modules = UserModule.class, dependencies = AppComponent.class) 39 | public interface UserComponent { 40 | void inject(UserActivity activity); 41 | 42 | @Component.Builder 43 | interface Builder { 44 | @BindsInstance 45 | UserComponent.Builder view(UserContract.View view); 46 | 47 | UserComponent.Builder appComponent(AppComponent appComponent); 48 | 49 | UserComponent build(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/di/module/UserModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.di.module; 17 | 18 | import androidx.fragment.app.FragmentActivity; 19 | import androidx.recyclerview.widget.GridLayoutManager; 20 | import androidx.recyclerview.widget.RecyclerView; 21 | 22 | import com.jess.arms.di.scope.ActivityScope; 23 | import com.tbruyelle.rxpermissions2.RxPermissions; 24 | 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | 28 | import dagger.Binds; 29 | import dagger.Module; 30 | import dagger.Provides; 31 | import me.jessyan.mvparms.demo.mvp.contract.UserContract; 32 | import me.jessyan.mvparms.demo.mvp.model.UserModel; 33 | import me.jessyan.mvparms.demo.mvp.model.entity.User; 34 | import me.jessyan.mvparms.demo.mvp.ui.adapter.UserAdapter; 35 | 36 | /** 37 | * ================================================ 38 | * 展示 Module 的用法 39 | * 40 | * @see Module wiki 官方文档 41 | * Created by JessYan on 09/04/2016 11:10 42 | * Contact me 43 | * Follow me 44 | * ================================================ 45 | */ 46 | @Module 47 | public abstract class UserModule { 48 | 49 | @ActivityScope 50 | @Provides 51 | static RxPermissions provideRxPermissions(UserContract.View view) { 52 | return new RxPermissions((FragmentActivity) view.getActivity()); 53 | } 54 | 55 | @ActivityScope 56 | @Provides 57 | static RecyclerView.LayoutManager provideLayoutManager(UserContract.View view) { 58 | return new GridLayoutManager(view.getActivity(), 2); 59 | } 60 | 61 | @ActivityScope 62 | @Provides 63 | static List provideUserList() { 64 | return new ArrayList<>(); 65 | } 66 | 67 | @ActivityScope 68 | @Provides 69 | static RecyclerView.Adapter provideUserAdapter(List list) { 70 | return new UserAdapter(list); 71 | } 72 | 73 | @Binds 74 | abstract UserContract.Model bindUserModel(UserModel model); 75 | } 76 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/contract/UserContract.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.contract; 17 | 18 | import android.app.Activity; 19 | 20 | import com.jess.arms.mvp.IModel; 21 | import com.jess.arms.mvp.IView; 22 | import com.tbruyelle.rxpermissions2.RxPermissions; 23 | 24 | import java.util.List; 25 | 26 | import io.reactivex.Observable; 27 | import me.jessyan.mvparms.demo.mvp.model.entity.User; 28 | 29 | /** 30 | * ================================================ 31 | * 展示 Contract 的用法 32 | * 33 | * @see Contract wiki 官方文档 34 | * Created by JessYan on 09/04/2016 10:47 35 | * Contact me 36 | * Follow me 37 | * ================================================ 38 | */ 39 | public interface UserContract { 40 | //对于经常使用的关于UI的方法可以定义到IView中,如显示隐藏进度条,和显示文字消息 41 | interface View extends IView { 42 | void startLoadMore(); 43 | 44 | void endLoadMore(); 45 | 46 | Activity getActivity(); 47 | 48 | //申请权限 49 | RxPermissions getRxPermissions(); 50 | } 51 | 52 | //Model层定义接口,外部只需关心Model返回的数据,无需关心内部细节,如是否使用缓存 53 | interface Model extends IModel { 54 | Observable> getUsers(int lastIdQueried, boolean update); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/model/UserModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.model; 17 | 18 | import androidx.lifecycle.Lifecycle; 19 | import androidx.lifecycle.OnLifecycleEvent; 20 | 21 | import com.jess.arms.di.scope.ActivityScope; 22 | import com.jess.arms.integration.IRepositoryManager; 23 | import com.jess.arms.mvp.BaseModel; 24 | 25 | import java.util.List; 26 | 27 | import javax.inject.Inject; 28 | 29 | import io.reactivex.Observable; 30 | import io.reactivex.ObservableSource; 31 | import io.reactivex.functions.Function; 32 | import io.rx_cache2.DynamicKey; 33 | import io.rx_cache2.EvictDynamicKey; 34 | import me.jessyan.mvparms.demo.mvp.contract.UserContract; 35 | import me.jessyan.mvparms.demo.mvp.model.api.cache.CommonCache; 36 | import me.jessyan.mvparms.demo.mvp.model.api.service.UserService; 37 | import me.jessyan.mvparms.demo.mvp.model.entity.User; 38 | import timber.log.Timber; 39 | 40 | /** 41 | * ================================================ 42 | * 展示 Model 的用法 43 | * 44 | * @see Model wiki 官方文档 45 | * Created by JessYan on 09/04/2016 10:56 46 | * Contact me 47 | * Follow me 48 | * ================================================ 49 | */ 50 | @ActivityScope 51 | public class UserModel extends BaseModel implements UserContract.Model { 52 | public static final int USERS_PER_PAGE = 10; 53 | 54 | @Inject 55 | public UserModel(IRepositoryManager repositoryManager) { 56 | super(repositoryManager); 57 | } 58 | 59 | @Override 60 | public Observable> getUsers(int lastIdQueried, boolean update) { 61 | //使用rxcache缓存,上拉刷新则不读取缓存,加载更多读取缓存 62 | return Observable.just(mRepositoryManager 63 | .obtainRetrofitService(UserService.class) 64 | .getUsers(lastIdQueried, USERS_PER_PAGE)) 65 | .flatMap((Function>, ObservableSource>>) listObservable -> mRepositoryManager.obtainCacheService(CommonCache.class) 66 | .getUsers(listObservable 67 | , new DynamicKey(lastIdQueried) 68 | , new EvictDynamicKey(update)) 69 | .map(listReply -> listReply.getData())); 70 | 71 | } 72 | 73 | @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) 74 | void onPause() { 75 | Timber.d("Release Resource"); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/model/api/Api.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.model.api; 17 | 18 | /** 19 | * ================================================ 20 | * 存放一些与 API 有关的东西,如请求地址,请求码等 21 | *

22 | * Created by JessYan on 08/05/2016 11:25 23 | * Contact me 24 | * Follow me 25 | * ================================================ 26 | */ 27 | public interface Api { 28 | String APP_DOMAIN = "https://api.github.com"; 29 | String REQUEST_SUCCESS = "0"; 30 | } 31 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/model/api/cache/CommonCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.model.api.cache; 17 | 18 | import java.util.List; 19 | import java.util.concurrent.TimeUnit; 20 | 21 | import io.reactivex.Observable; 22 | import io.rx_cache2.DynamicKey; 23 | import io.rx_cache2.EvictProvider; 24 | import io.rx_cache2.LifeCache; 25 | import io.rx_cache2.Reply; 26 | import io.rx_cache2.internal.RxCache; 27 | import me.jessyan.mvparms.demo.mvp.model.entity.User; 28 | 29 | /** 30 | * ================================================ 31 | * 展示 {@link RxCache#using(Class)} 中需要传入的 Providers 的使用方式 32 | *

33 | * Created by JessYan on 08/30/2016 13:53 34 | * Contact me 35 | * Follow me 36 | * ================================================ 37 | */ 38 | public interface CommonCache { 39 | 40 | @LifeCache(duration = 2, timeUnit = TimeUnit.MINUTES) 41 | Observable>> getUsers(Observable> users, DynamicKey idLastUserQueried, EvictProvider evictProvider); 42 | } 43 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/model/api/service/CommonService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.model.api.service; 17 | 18 | /** 19 | * ================================================ 20 | * 存放通用的一些 API 21 | *

22 | * Created by JessYan on 08/05/2016 12:05 23 | * Contact me 24 | * Follow me 25 | * ================================================ 26 | */ 27 | public interface CommonService { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/model/api/service/UserService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.model.api.service; 17 | 18 | import java.util.List; 19 | 20 | import io.reactivex.Observable; 21 | import me.jessyan.mvparms.demo.mvp.model.entity.User; 22 | import retrofit2.Retrofit; 23 | import retrofit2.http.GET; 24 | import retrofit2.http.Headers; 25 | import retrofit2.http.Query; 26 | 27 | /** 28 | * ================================================ 29 | * 展示 {@link Retrofit#create(Class)} 中需要传入的 ApiService 的使用方式 30 | * 存放关于用户的一些 API 31 | *

32 | * Created by JessYan on 08/05/2016 12:05 33 | * Contact me 34 | * Follow me 35 | * ================================================ 36 | */ 37 | public interface UserService { 38 | String HEADER_API_VERSION = "Accept: application/vnd.github.v3+json"; 39 | 40 | @Headers({HEADER_API_VERSION}) 41 | @GET("/users") 42 | Observable> getUsers(@Query("since") int lastIdQueried, @Query("per_page") int perPage); 43 | } 44 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/model/entity/BaseResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.model.entity; 17 | 18 | import java.io.Serializable; 19 | 20 | import me.jessyan.mvparms.demo.mvp.model.api.Api; 21 | 22 | /** 23 | * ================================================ 24 | * 如果你服务器返回的数据格式固定为这种方式(这里只提供思想,服务器返回的数据格式可能不一致,可根据自家服务器返回的格式作更改) 25 | * 指定范型即可改变 {@code data} 字段的类型, 达到重用 {@link BaseResponse}, 如果你实在看不懂, 请忽略 26 | *

27 | * Created by JessYan on 26/09/2016 15:19 28 | * Contact me 29 | * Follow me 30 | * ================================================ 31 | */ 32 | public class BaseResponse implements Serializable { 33 | private T data; 34 | private String code; 35 | private String msg; 36 | 37 | public T getData() { 38 | return data; 39 | } 40 | 41 | public String getCode() { 42 | return code; 43 | } 44 | 45 | public String getMsg() { 46 | return msg; 47 | } 48 | 49 | /** 50 | * 请求是否成功 51 | * 52 | * @return 53 | */ 54 | public boolean isSuccess() { 55 | return code.equals(Api.REQUEST_SUCCESS); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/model/entity/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.model.entity; 17 | 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | /** 21 | * ================================================ 22 | * User 实体类 23 | *

24 | * Created by JessYan on 04/09/2016 17:14 25 | * Contact me 26 | * Follow me 27 | * ================================================ 28 | */ 29 | public class User { 30 | private final int id; 31 | private final String login; 32 | private final String avatar_url; 33 | 34 | public User(int id, String login, String avatarUrl) { 35 | this.id = id; 36 | this.login = login; 37 | this.avatar_url = avatarUrl; 38 | } 39 | 40 | public String getAvatarUrl() { 41 | if (avatar_url.isEmpty()) { 42 | return avatar_url; 43 | } 44 | return avatar_url.split("\\?")[0]; 45 | } 46 | 47 | 48 | public int getId() { 49 | return id; 50 | } 51 | 52 | public String getLogin() { 53 | return login; 54 | } 55 | 56 | @NotNull 57 | @Override 58 | public String toString() { 59 | return "id -> " + id + " login -> " + login; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/ui/adapter/UserAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.ui.adapter; 17 | 18 | import android.view.View; 19 | 20 | import androidx.annotation.NonNull; 21 | 22 | import com.jess.arms.base.BaseHolder; 23 | import com.jess.arms.base.DefaultAdapter; 24 | 25 | import java.util.List; 26 | 27 | import me.jessyan.mvparms.demo.R; 28 | import me.jessyan.mvparms.demo.mvp.model.entity.User; 29 | import me.jessyan.mvparms.demo.mvp.ui.holder.UserItemHolder; 30 | 31 | /** 32 | * ================================================ 33 | * 展示 {@link DefaultAdapter} 的用法 34 | *

35 | * Created by JessYan on 09/04/2016 12:57 36 | * Contact me 37 | * Follow me 38 | * ================================================ 39 | */ 40 | public class UserAdapter extends DefaultAdapter { 41 | 42 | public UserAdapter(List infos) { 43 | super(infos); 44 | } 45 | 46 | @NonNull 47 | @Override 48 | public BaseHolder getHolder(@NonNull View v, int viewType) { 49 | return new UserItemHolder(v); 50 | } 51 | 52 | @Override 53 | public int getLayoutId(int viewType) { 54 | return R.layout.recycle_list; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /demo/src/main/java/me/jessyan/mvparms/demo/mvp/ui/holder/UserItemHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 JessYan 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 me.jessyan.mvparms.demo.mvp.ui.holder; 17 | 18 | import android.view.View; 19 | import android.widget.ImageView; 20 | import android.widget.TextView; 21 | 22 | import androidx.annotation.NonNull; 23 | import androidx.recyclerview.widget.RecyclerView; 24 | 25 | import com.jess.arms.base.BaseHolder; 26 | import com.jess.arms.base.DefaultAdapter; 27 | import com.jess.arms.di.component.AppComponent; 28 | import com.jess.arms.http.imageloader.ImageLoader; 29 | import com.jess.arms.http.imageloader.glide.ImageConfigImpl; 30 | import com.jess.arms.utils.ArmsUtils; 31 | 32 | import butterknife.BindView; 33 | import me.jessyan.mvparms.demo.R; 34 | import me.jessyan.mvparms.demo.mvp.model.entity.User; 35 | 36 | /** 37 | * ================================================ 38 | * 展示 {@link BaseHolder} 的用法 39 | *

40 | * Created by JessYan on 9/4/16 12:56 41 | * Contact me 42 | * Follow me 43 | * ================================================ 44 | */ 45 | public class UserItemHolder extends BaseHolder { 46 | 47 | @BindView(R.id.iv_avatar) 48 | ImageView mAvatar; 49 | @BindView(R.id.tv_name) 50 | TextView mName; 51 | private AppComponent mAppComponent; 52 | /** 53 | * 用于加载图片的管理类, 默认使用 Glide, 使用策略模式, 可替换框架 54 | */ 55 | private ImageLoader mImageLoader; 56 | 57 | public UserItemHolder(View itemView) { 58 | super(itemView); 59 | //可以在任何可以拿到 Context 的地方, 拿到 AppComponent, 从而得到用 Dagger 管理的单例对象 60 | mAppComponent = ArmsUtils.obtainAppComponentFromContext(itemView.getContext()); 61 | mImageLoader = mAppComponent.imageLoader(); 62 | } 63 | 64 | @Override 65 | public void setData(@NonNull User data, int position) { 66 | mName.setText(data.getLogin()); 67 | 68 | //itemView 的 Context 就是 Activity, Glide 会自动处理并和该 Activity 的生命周期绑定 69 | mImageLoader.loadImage(itemView.getContext(), 70 | ImageConfigImpl 71 | .builder() 72 | .url(data.getAvatarUrl()) 73 | .imageView(mAvatar) 74 | .build()); 75 | } 76 | 77 | /** 78 | * 在 Activity 的 onDestroy 中使用 {@link DefaultAdapter#releaseAllHolder(RecyclerView)} 方法 (super.onDestroy() 之前) 79 | * {@link BaseHolder#onRelease()} 才会被调用, 可以在此方法中释放一些资源 80 | */ 81 | @Override 82 | protected void onRelease() { 83 | //只要传入的 Context 为 Activity, Glide 就会自己做好生命周期的管理, 其实在上面的代码中传入的 Context 就是 Activity 84 | //所以在 onRelease 方法中不做 clear 也是可以的, 但是在这里想展示一下 clear 的用法 85 | mImageLoader.clear(mAppComponent.application(), ImageConfigImpl.builder() 86 | .imageViews(mAvatar) 87 | .build()); 88 | this.mAvatar = null; 89 | this.mName = null; 90 | this.mAppComponent = null; 91 | this.mImageLoader = null; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /demo/src/main/res/anim/translate_center_to_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/src/main/res/anim/translate_center_to_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/src/main/res/anim/translate_left_to_center.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/src/main/res/anim/translate_right_to_center.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_user.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 16 | 17 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/include_title.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | 18 | 25 | 26 | 27 | 35 | 36 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/recycle_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 18 | 27 | 28 | -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/demo/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/demo/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xhdpi/ic_arrow_back_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/demo/src/main/res/mipmap-xhdpi/ic_arrow_back_white_24dp.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/demo/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xxhdpi/arms_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/demo/src/main/res/mipmap-xxhdpi/arms_logo.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xxhdpi/ic_arrow_back_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/demo/src/main/res/mipmap-xxhdpi/ic_arrow_back_white_24dp.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xxxhdpi/ic_arrow_back_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/demo/src/main/res/mipmap-xxxhdpi/ic_arrow_back_white_24dp.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3FA862 4 | #3FA862 5 | #FF4081 6 | #FFFFFF 7 | 8 | -------------------------------------------------------------------------------- /demo/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | MVPArms 3 | 4 | -------------------------------------------------------------------------------- /demo/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /demo/src/test/java/me/jessyan/mvparms/demo/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package me.jessyan.mvparms.demo; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ## Project-wide Gradle settings. 2 | # 3 | # For more details on how to configure your build environment visit 4 | # http://www.gradle.org/docs/current/userguide/build_environment.html 5 | # 6 | # Specifies the JVM arguments used for the daemon process. 7 | # The setting is particularly useful for tweaking memory settings. 8 | # Default value: -Xmx1024m -XX:MaxPermSize=256m 9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 10 | # 11 | # When configured, Gradle will run in incubating parallel mode. 12 | # This option should only be used with decoupled projects. More details, visit 13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 14 | # org.gradle.parallel=true 15 | #Thu May 25 20:59:18 CST 2017 16 | org.gradle.jvmargs=-Xmx1536m 17 | android.enableBuildCache=true 18 | android.useAndroidX=true 19 | android.enableJetifier=true 20 | android.injected.testOnly=false 21 | android.databinding.incremental=true 22 | android.lifecycleProcessor.incremental=true 23 | kapt.incremental.apt=true 24 | kapt.use.worker.api=true 25 | kapt.include.compile.classpath=false 26 | org.gradle.parallel=true 27 | org.gradle.caching=true 28 | org.gradle.configureondemand=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Feb 26 13:45:30 CST 2020 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-5.6.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /image/ApplicationArchitecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/ApplicationArchitecture.jpg -------------------------------------------------------------------------------- /image/Architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/Architecture.png -------------------------------------------------------------------------------- /image/android_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/android_logo.png -------------------------------------------------------------------------------- /image/arms_banner_v1.0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/arms_banner_v1.0.jpg -------------------------------------------------------------------------------- /image/hui_cai_fu_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/hui_cai_fu_logo.png -------------------------------------------------------------------------------- /image/mi_lu_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/mi_lu_logo.png -------------------------------------------------------------------------------- /image/mi_wo_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/mi_wo_logo.png -------------------------------------------------------------------------------- /image/official.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/official.jpeg -------------------------------------------------------------------------------- /image/package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/package.png -------------------------------------------------------------------------------- /image/shaimobao_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/shaimobao_logo.png -------------------------------------------------------------------------------- /image/step_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/step_1.png -------------------------------------------------------------------------------- /image/step_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/step_2.png -------------------------------------------------------------------------------- /image/tianfutong_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/tianfutong_logo.png -------------------------------------------------------------------------------- /image/tiantian_live_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/tiantian_live_logo.png -------------------------------------------------------------------------------- /image/tiantian_video_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/tiantian_video_logo.png -------------------------------------------------------------------------------- /image/tong_hang_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/tong_hang_logo.png -------------------------------------------------------------------------------- /image/top_net_work_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/top_net_work_logo.png -------------------------------------------------------------------------------- /image/xiang_yun_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/xiang_yun_logo.png -------------------------------------------------------------------------------- /image/xiaoding_foreman_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/xiaoding_foreman_logo.png -------------------------------------------------------------------------------- /image/xiaoding_material_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/xiaoding_material_logo.png -------------------------------------------------------------------------------- /image/xiaoding_worker_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/xiaoding_worker_logo.png -------------------------------------------------------------------------------- /image/zhibo_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/MVPArms/8adc86be91eaef3b384f72a7bb0ae6b43a393046/image/zhibo_logo.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':demo', ':arms', ':arms-autolayout', ':arms-imageloader-glide' 2 | --------------------------------------------------------------------------------