├── .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 |
--------------------------------------------------------------------------------