张波

提交代码

Showing 81 changed files with 5607 additions and 0 deletions
*.iml
.gradle
/local.properties
/.idea
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EclipseCodeFormatterProjectSettings">
<option name="projectSpecificProfile">
<ProjectSpecificProfile>
<option name="formatter" value="ECLIPSE" />
<option name="importOrder" value="java;javax;org;android;androidx;com;" />
<option name="pathToConfigFileJava" value="$PROJECT_DIR$/config/CodeQuality/WonderTek_CodeFormatter_Convention_v1.0.xml" />
<option name="selectedJavaProfile" value="WonderTek_CodeFormatter_Convention_v1.0" />
</ProjectSpecificProfile>
</option>
</component>
</project>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
... ...
/build
\ No newline at end of file
... ...
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
android {
compileSdkVersion var.compileSdkVersion
buildToolsVersion var.buildToolsVersion
defaultConfig {
applicationId "com.example.myapplication"
minSdkVersion var.minSdkVersion
targetSdkVersion var.targetSdkVersion
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
// noinspection ChromeOsAbiSupport
abiFilters "armeabi-v7a", "arm64-v8a", "x86"
}
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
compileOptions {
// Java兼容性设置为Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
// implementation 'androidx.appcompat:appcompat:1.6.1'
implementation "com.google.android.material:material:1.4.0"
// implementation project(path: ':wdstartup')
implementation 'com.wd:startup:1.0.0'
}
\ No newline at end of file
... ...
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.myapplication">
<!-- 请求网络 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature
android:name="android.software.leanback"
android:required="false" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
<activity
android:name="com.example.myapplication.MainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
... ...
package com.example.myapplication;
import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.Nullable;
/**
* @ProjectName: PeopleDailyVideo
* @Package: com.people.displayui.main
* @ClassName: WelcomeActivity
* @Description: 启动APP过渡页面
* @Author: wd
* @CreateDate: 2022/10/28 17:36
* @UpdateUser: wd
* @UpdateDate: 2022/10/28 17:36
* @UpdateRemark: 更新说明:
* @Version: 1.0
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 直接进入首页
}
}
... ...
package com.example.myapplication;
import android.app.Application;
import android.util.Log;
/**
* @author devel
* @time 2024/8/28 星期三 16:23
*/
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Log.e("zzzz","MyApplication onCreate");
// test
}
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
... ...
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" />
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
... ...
No preview for this file type
No preview for this file type
No preview for this file type
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
\ No newline at end of file
... ...
<resources>
<string name="app_name">My Application</string>
</resources>
\ No newline at end of file
... ...
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>
\ No newline at end of file
... ...
apply plugin: 'maven'
buildscript {
ext.kotlin_version = "1.4.32"
repositories {
mavenLocal()
mavenCentral()
// 以下四行代码为阿里gradle源,需要的人自己放開使用
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases' }
//阿里云 maven
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/repository/releases' }
google()
maven { url "https://jitpack.io" }
//华为
maven { url 'https://developer.huawei.com/repo/' }
//阿里云QuickTracking
maven { url 'https://repo1.maven.org/maven2/' }
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/google/'
name 'aliyun-google'
}
// TingYun
maven { url "https://nexus2.tingyun.com/nexus/content/repositories/snapshots/" }
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.billy.android:autoregister:1.4.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
mavenCentral()
// 以下四行代码为阿里gradle源,需要的人自己放開使用
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases' }
//阿里云 maven
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/repository/releases' }
google()
maven { url "https://jitpack.io" }
//华为
maven { url 'https://developer.huawei.com/repo/' }
//阿里云QuickTracking
maven { url 'https://repo1.maven.org/maven2/' }
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/google/'
name 'aliyun-google'
}
flatDir { dirs 'src/main/libs' }
// 快马私库
maven {
credentials {
username '6708d1cf6f4c940bd257c88d'
password 'Wm51gc4rARyr'
}
url 'https://packages.aliyun.com/6708d221eef79c23d7b02189/maven/repo-higom'
}
}
project.configurations.configureEach {
resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'com.android.android.support' && !details.requested.name.contains('multidex')) {
details.useVersion "28.0.0"
}
}
}
// 强制依赖
configurations.configureEach {
exclude group: 'com.alipay.android.phone.thirdparty', module: 'securityguard-build'
resolutionStrategy {
force 'androidx.activity:activity:1.2.1'
force 'androidx.annotation:annotation:1.1.0'
force 'androidx.appcompat:appcompat:1.2.0'
force 'androidx.arch.core:core-common:2.1.0'
force 'androidx.arch.core:core-runtime:2.1.0'
force 'androidx.core:core-ktx:1.6.0'
force 'androidx.core:core:1.5.0'
force 'androidx.collection:collection:1.1.0'
force 'androidx.constraintlayout:constraintlayout:2.0.4'
force 'androidx.constraintlayout:constraintlayout-solver:2.0.4'
force 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
force 'androidx.fragment:fragment:1.3.1'
force 'androidx.lifecycle:lifecycle-common:2.3.0'
force 'androidx.multidex:multidex:2.0.1'
force 'androidx.recyclerview:recyclerview:1.2.0'
force 'androidx.vectordrawable:vectordrawable:1.1.0'
force 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
force 'com.squareup.okhttp3:okhttp:4.9.1'
force 'com.squareup.okio:okio:2.7.0'
force 'org.jetbrains.kotlin:kotlin-stdlib:1.4.32'
force 'org.jetbrains.kotlin:kotilin-stdlib-jdk8:1.4.32'
force 'org.jetbrains:annotations:15.0'
force 'net.sf.proguard:proguard-base:6.1.0'
}
}
}
ext {
var = [
// SDK And Tools
applicationId : "com.wondertek.dss",
minSdkVersion : 25,
targetSdkVersion : 30,
compileSdkVersion: 30,
buildToolsVersion: "30.0.3",
// 版本号,正式版本 1.0.0 1000080 后两位,80即标识为发布版本
// 测试版本 1.0.0_TF1 1000001 后两位,01即为测试版本号,01-79
// 升级版本 1.0.0_RC1 1000081 后两位,81即为升级版本号,81-99
versionName : "1.0.0", // release正式
debugVnName : "", // debug开发模式 用于区分debug模式下上报的日志
versionCode : 100,
//此版本号是SDK版本,不能随便改
aar_version : "1.0.0",
]
}
... ...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="12">
<profile kind="CodeFormatterProfile" name="WonderTek_CodeFormatter_Convention_v1.0"
version="12">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation"
value="common_lines" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true" />
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off" />
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="1" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="49" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true" />
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration"
value="20" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations"
value="1" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column"
value="false" />
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120" />
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration"
value="end_of_line" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch"
value="16" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body"
value="0" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause"
value="common_lines" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration"
value="20" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration"
value="20" />
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error" />
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer"
value="20" />
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="20" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration"
value="16" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration"
value="0" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case"
value="end_of_line" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while"
value="insert" />
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="16" />
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines"
value="2147483647" />
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="16" />
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation"
value="80" />
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column"
value="false" />
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer"
value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement"
value="do not insert" />
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16" />
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation"
value="16" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch"
value="do not insert" />
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration"
value="common_lines" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header"
value="16" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="false" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1" />
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch"
value="insert" />
</profile>
</profiles>
\ No newline at end of file
... ...
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
#org.gradle.jvmargs=-Xmx2048m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
android.enableResourceOptimizations=false
#建议您关闭 R8 后再进行混淆
android.enableR8=false
android.enableR8.libraries=false
# 如果使用最新稳定版本 Android Studio 3.5 或以上,那么您需要在 gradle.properties 里面新增
android.buildOnlyTargetAbi=false
#网络请求接口版本 202204151851
requestVersion=107
#设置组件是否作为app还是lib,true是lib ,false 是app
#分享
isShareModule=true
#播放器
isPlayerModule=true
#是否直播模块运行 false可以单独运行
isLiveModule=true
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
#android.nonTransitiveRClass=true
... ...
No preview for this file type
#Fri Oct 23 14:37:25 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-6.8-all.zip
... ...
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
... ...
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
... ...
rootProject.name = "wdnetwork"
include ':app'
include ':wdnetwork'
\ No newline at end of file
... ...
/build
\ No newline at end of file
... ...
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'maven'
}
android {
compileSdkVersion var.compileSdkVersion
defaultConfig {
minSdkVersion var.minSdkVersion
targetSdkVersion var.targetSdkVersion
versionCode var.versionCode
versionName var.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
buildConfigField "String", "API_VERSION", "\"${requestVersion}\""
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// 自定义AAR包名
android.libraryVariants.all { variant ->
variant.outputs.all {
if (outputFileName != null && outputFileName.endsWith(".aar")) {
def fileName = "${project.name}-${buildType.name}-v${var.aar_version}.aar"
outputFileName = fileName
}
}
}
}
dependencies {
api 'com.squareup.okhttp3:okhttp:4.8.0'
api 'com.squareup.retrofit2:retrofit:2.9.0'
api 'com.squareup.retrofit2:converter-gson:2.9.0'
api 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
//rxjava
api 'io.reactivex.rxjava2:rxjava:2.2.8'
api 'io.reactivex.rxjava2:rxandroid:2.1.0'
//解析bean
api 'com.alibaba:fastjson:1.2.62'
implementation 'com.wd:log:1.0.0'
implementation 'com.wd:wdkitcore:1.0.5'
// implementation 'com.wd:servicekit:1.0.3'
implementation 'com.wd:wdinterface:1.0.3'
api 'com.alibaba:arouter-api:1.5.2'
// //依赖工程
// compileOnly project(path: ':lib_utils')
// compileOnly project(path: ':lib_livedatabus')
}
uploadArchives {
repositories {
mavenDeployer {
repository(url: "https://packages.aliyun.com/6708d221eef79c23d7b02189/maven/repo-higom/") {
authentication(userName: '6708d1cf6f4c940bd257c88d', password: 'Wm51gc4rARyr')
}
pom.project {
artifactId 'wdnetwork'
version '1.0.0'
groupId 'com.wd'
packaging 'aar'
}
}
}
}
\ No newline at end of file
... ...
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wd.capability.network">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
\ No newline at end of file
... ...
package com.wd.capability.network;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import com.wd.base.log.Logger;
import com.wd.capability.network.bean.MetaBean;
import com.wd.capability.network.response.BaseResponse;
import com.wd.capability.network.response.ExceptionHandle;
import com.wd.capability.network.response.ResponseException;
import com.wd.capability.network.utils.HostUtil;
import com.wd.foundation.wdinterface.toast.IToast;
import com.wd.foundation.wdkitcore.router.ArouterServiceManager;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
/**
* 网络数据返回处理类
*
* @author shishuangxi_wd
* @date 2022/6/24 15:24
*/
public abstract class BaseObserver<T> implements Observer<BaseResponse<T>> {
private final int SUCCESS_CODE_0 = 0;
private final int SUCCESS_CODE = 200;
private final int UNAUTHORIZED_CODE = 401;
private final int BAD_REQUEST_CODE = 400;
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onComplete() {
}
// @Override
// public void onNext(BaseResponse<T> value) {
// /** 根据code返回值处理业务 */
// if (value != null && (0 == value.getCode() || 200 == value.getCode())) {
// // 记录服务器时间
// HostUtil.serverTime = value.getTimestamp();
// onSuccess(value.getData());
// //携带上其他数据,比如MD5,特殊需要出来的用这个,带上msg,带上code
// onSuccess(value.getData(), value.getMeta(), value.getMessage(), value.getCode());
// } else if (401 == value.getCode()) {
// // 统一处理的业务逻辑
// delealCode(value.getCode());
// }else if (400 == value.getCode()) {
// dealSpecialCode(value.getCode(), value.getMessage());
// } else {
// // 返回其他code交给子类处理
// dealSpecialCode(value.getCode(), value.getMessage());
// }
// }
@Override
public void onNext(BaseResponse<T> value) {
if (value == null) {
IToast toaster = ArouterServiceManager.provide(IToast.class);
// handle null value
if (toaster != null) {
toaster.showShort("网络请求,出现异常");
}
return;
}
int code = value.getCode();
switch (code) {
case SUCCESS_CODE_0:
case SUCCESS_CODE:
handleSuccess(value);
break;
case UNAUTHORIZED_CODE:
handleUnauthorized(value);
break;
case BAD_REQUEST_CODE:
handleBadRequest(value);
break;
default:
handleOtherCode(value);
break;
}
}
private void handleSuccess(@NonNull BaseResponse<T> value) {
// 记录服务器时间
HostUtil.serverTime = value.getTimestamp();
onSuccess(value.getData());
// 携带上其他数据,比如MD5,特殊需要出来的用这个,带上msg,带上code
onSuccess(value.getData(), value.getMeta(), value.getMessage(), value.getCode());
}
private void handleUnauthorized(@NonNull BaseResponse<T> value) {
// 统一处理的业务逻辑
delealCode(value.getCode());
}
private void handleBadRequest(@NonNull BaseResponse<T> value) {
// 返回其他code交给子类处理
dealSpecialCode(value.getCode(), value.getMessage());
}
private void handleOtherCode(@NonNull BaseResponse<T> value) {
// 返回其他code交给子类处理
dealSpecialCode(value.getCode(), value.getMessage());
}
/** 处理一些特殊的返回值 */
protected abstract void dealSpecialCode(int code, String message);
/**
* 异常处理 网络异常、解析异常
*/
@Override
public void onError(Throwable e) {
if (e == null) {
_onError(ExceptionHandle.NET_ERROR_TIPS_IN_PAGE);
return;
}
// 真实错误信息
String realMessage = e.getMessage();
if (!TextUtils.isEmpty(realMessage)) {
Logger.e("---接口异常---" + realMessage);
}
ResponseException responseException = ExceptionHandle.handleException(e);
// 上报用
int errorCode = responseException.code;
_onErrorWithCode(errorCode, realMessage);
// Toast提示的错误信息
String toastMessage;
if (ExceptionHandle.showErrorTips(responseException)) {
toastMessage = ExceptionHandle.NET_ERROR_TIPS_IN_PAGE;
} else {
toastMessage = "";
}
_onError(toastMessage);
}
/**
* 返回的数据
*
* @param t
*/
protected abstract void onSuccess(T t);
/**
* 返回的数据
*
* @param t
* @param metaBean
* @param msg
* @param code
*/
protected void onSuccess(T t, MetaBean metaBean, String msg, int code) {
}
/**
* 统一code 处理 比如单点登录 与后台统一确定
*/
private void delealCode(int resultCode) {
switch (resultCode) {
case 400:
break;
default:
break;
}
}
protected void _onError(String message) {
}
protected void _onErrorWithCode(int errorCode, String message) {
}
}
... ...
/*
* Copyright 2016 jeasonlzy(廖子尧)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wd.capability.network;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
/**
* @author qts
*/
public class HttpsUtils {
public static class SslParams {
public SSLSocketFactory sslSocketFactory;
public X509TrustManager trustManager;
}
public static SslParams getSslSocketFactory() {
return getSslSocketFactoryBase(null, null, null);
}
/**
* https单向认证
* 可以额外配置信任服务端的证书策略,否则默认是按CA证书去验证的,若不是CA可信任的证书,则无法通过验证
*/
public static SslParams getSslSocketFactory(X509TrustManager trustManager) {
return getSslSocketFactoryBase(trustManager, null, null);
}
/**
* https单向认证
* 用含有服务端公钥的证书校验服务端证书
*/
public static SslParams getSslSocketFactory(InputStream... certificates) {
return getSslSocketFactoryBase(null, null, null, certificates);
}
/**
* https双向认证
* bksFile 和 password -> 客户端使用bks证书校验服务端证书
* certificates -> 用含有服务端公钥的证书校验服务端证书
*/
public static SslParams getSslSocketFactory(InputStream bksFile, String password, InputStream... certificates) {
return getSslSocketFactoryBase(null, bksFile, password, certificates);
}
/**
* https双向认证
* bksFile 和 password -> 客户端使用bks证书校验服务端证书
* X509TrustManager -> 如果需要自己校验,那么可以自己实现相关校验,如果不需要自己校验,那么传null即可
*/
public static SslParams getSslSocketFactory(InputStream bksFile, String password, X509TrustManager trustManager) {
return getSslSocketFactoryBase(trustManager, bksFile, password);
}
private static SslParams getSslSocketFactoryBase(X509TrustManager trustManager, InputStream bksFile,
String password, InputStream... certificates) {
SslParams sslParams = new SslParams();
try {
KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
TrustManager[] trustManagers = prepareTrustManager(certificates);
X509TrustManager manager;
if (trustManager != null) {
// 优先使用用户自定义的TrustManager
manager = trustManager;
} else if (trustManagers != null) {
// 然后使用默认的TrustManager
manager = chooseTrustManager(trustManagers);
} else {
// 否则使用不安全的TrustManager
manager = UnSafeTrustManager;
}
// 创建TLS类型的SSLContext对象, that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
// 用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书
// 第一个参数是授权的密钥管理器,用来授权验证,比如授权自签名的证书验证。第二个是被授权的证书管理器,用来验证服务器端的证书
sslContext.init(keyManagers, new TrustManager[] {manager}, null);
// 通过sslContext获取SSLSocketFactory对象
sslParams.sslSocketFactory = sslContext.getSocketFactory();
sslParams.trustManager = manager;
return sslParams;
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
} catch (KeyManagementException e) {
throw new AssertionError(e);
}
}
private static KeyManager[] prepareKeyManager(InputStream bksFile, String password) {
try {
if (bksFile == null || password == null) {
return null;
}
KeyStore clientKeyStore = KeyStore.getInstance("BKS");
clientKeyStore.load(bksFile, password.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientKeyStore, password.toCharArray());
return kmf.getKeyManagers();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static TrustManager[] prepareTrustManager(InputStream... certificates) {
if (certificates == null || certificates.length <= 0) {
return null;
}
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
// 创建一个默认类型的KeyStore,存储我们信任的证书
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
int index = 0;
for (InputStream certStream : certificates) {
String certificateAlias = Integer.toString(index++);
// 证书工厂根据证书文件的流生成证书 cert
Certificate cert = certificateFactory.generateCertificate(certStream);
// 将 cert 作为可信证书放入到keyStore中
keyStore.setCertificateEntry(certificateAlias, cert);
try {
if (certStream != null) {
certStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 我们创建一个默认类型的TrustManagerFactory
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// 用我们之前的keyStore实例初始化TrustManagerFactory,这样tmf就会信任keyStore中的证书
tmf.init(keyStore);
// 通过tmf获取TrustManager数组,TrustManager也会信任keyStore中的证书
return tmf.getTrustManagers();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) {
for (TrustManager trustManager : trustManagers) {
if (trustManager instanceof X509TrustManager) {
return (X509TrustManager) trustManager;
}
}
return null;
}
/**
* 为了解决客户端不信任服务器数字证书的问题,网络上大部分的解决方案都是让客户端不对证书做任何检查,
* 这是一种有很大安全漏洞的办法
*/
public static X509TrustManager UnSafeTrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
};
/**
* 此类是用于主机名验证的基接口。 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,
* 则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。策略可以是基于证书的或依赖于其他验证方案。
* 当验证 URL 主机名使用的默认规则失败时使用这些回调。如果主机名是可接受的,则返回 true
*/
public static HostnameVerifier UnSafeHostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
}
... ...
package com.wd.capability.network;
import java.util.HashMap;
import java.util.Map;
import android.text.TextUtils;
import com.wd.foundation.wdkitcore.tools.SpUtils;
import okhttp3.Interceptor;
/**
* 网络管理类
*
* @author shishuangxi_wd
* @date 2022/7/4 14:17
*/
public class NetManager {
/**
* 默认环境设置
*/
public static final String BASE_URL_DEFAULT = "2";
/**
* 可选择的环境
*/
public static final String BASE_URL_SIT = "1";
public static final String BASE_URL_UAT = "2";
public static final String BASE_URL_REL = "3";
public static final String BASE_URL_DEV = "4";
private static NetManager instance;
/**
* 中文端sit环境
*/
public static String baseUrlSit = "https://pd-apis-sit.pdnews.cn/";
/**
* uat环境url
*/
public static String baseUrlUat = "https://pd-apis-uat.pdnews.cn/";
/**
* 正式环境url
*/
public static String baseUrlRel = "https://pdapis.pdnews.cn/";
/**
* dev环境url
*/
public static String baseUrlDev = "https://pd-apis-dev.pdnews.cn/";
private String baseUrl;
private String mToken;
private String mVersionCode;
public Builder builder;
private Map<String, String> mHeaderMap = new HashMap<>();
private NetManager() {
builder = new Builder();
}
public static NetManager getNetManager() {
if (instance == null) {
synchronized (NetManager.class) {
if (instance == null) {
instance = new NetManager();
}
}
}
return instance;
}
public void setToken(String token) {
mToken = token;
}
public String getToken() {
return mToken;
}
public void setBaseUrl(String baseUrl) {
if (TextUtils.isEmpty(baseUrl)) {
return;
}
}
public String getBaseUrl() {
if (TextUtils.isEmpty(baseUrl)) {
baseUrl = baseUrlRel;
}
return baseUrl;
}
public void setVersionCode(String versionCode) {
mVersionCode = versionCode;
}
/**
* 添加基础头信息
*/
public void addHeaderParameter(Map<String, String> map) {
if (map != null && map.size() > 0) {
mHeaderMap.putAll(map);
}
}
public static String getUrlTag() {
String tag = SpUtils.getBaseUrlTag();
if (TextUtils.isEmpty(tag)) {
SpUtils.saveBaseUrlTag(NetManager.BASE_URL_DEFAULT);
tag = NetManager.BASE_URL_DEFAULT;
}
return tag;
}
public void addHeaderKey(String key, String value) {
mHeaderMap.put(key, TextUtils.isEmpty(value) ? "" : value);
}
public void clearHeaderParameter() {
mHeaderMap.clear();
}
public Map<String, String> getHeaderParameter() {
return mHeaderMap;
}
public static class Builder {
private long connectTimeout = 10;
private long readTimeout = 10;
private long writeTimeout = 10;
private Interceptor mInterceptor;
private String cacheFile = "api_cache";
private long cacheTime = 60 * 60 * 24 * 3;
public long getConnectTimeout() {
return connectTimeout;
}
public long getReadTimeout() {
return readTimeout;
}
public long getWriteTimeout() {
return writeTimeout;
}
public void setConnectTimeout(long connectTimeout) {
this.connectTimeout = connectTimeout;
}
public void setReadTimeout(long readTimeout) {
this.readTimeout = readTimeout;
}
public void setWriteTimeout(long writeTimeout) {
this.writeTimeout = writeTimeout;
}
public void setCacheFile() {
}
public void setInterceptor(Interceptor interceptor) {
mInterceptor = interceptor;
}
public Interceptor getInterceptor() {
return mInterceptor;
}
public String getCacheFile() {
return cacheFile;
}
public void setCacheFile(String cacheFile) {
this.cacheFile = cacheFile;
}
public long getCacheTime() {
return cacheTime;
}
public void setCacheTime(long cacheTime) {
this.cacheTime = cacheTime;
}
}
}
... ...
package com.wd.capability.network;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.UUID;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;
import com.wd.foundation.wdinterface.toast.IToast;
import com.wd.foundation.wdkitcore.router.ArouterServiceManager;
import com.wd.foundation.wdkitcore.tools.AppContext;
import com.wd.foundation.wdkitcore.tools.ResUtils;
/**
* 网络相关工具类
*
* @author wondertek
* @date 2018/08/24
*/
public class NetworkUtils {
/**
* 检查网络是否连接
*
* @return true 已连接 false 未连接
*/
public static Boolean isNetAvailable() {
try {
ConnectivityManager connectivity =
(ConnectivityManager) AppContext.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo info = connectivity.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
if (info.getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
} catch (Exception e) {
return false;
}
return false;
}
/**
* 判断是否是wifi连接
*
* @return
*/
public static boolean isWifi() {
ConnectivityManager mConnectivityManager =
(ConnectivityManager) AppContext.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (mConnectivityManager == null) {
return false;
}
NetworkInfo mWiFiNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mWiFiNetworkInfo != null) {
return mWiFiNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI;
}
return false;
}
/**
* 判断WIFI网络是否可用
*
* @return
*/
public static boolean isWifiConnected() {
ConnectivityManager mConnectivityManager =
(ConnectivityManager) AppContext.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (mConnectivityManager == null) {
return false;
}
NetworkInfo mWiFiNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWiFiNetworkInfo != null) {
return mWiFiNetworkInfo.isAvailable();
}
return false;
}
/**
* 获取ipv4地址
*
* @param context
* @return IPv4地址
*/
public static String getIpAddress(Context context) {
String ipAdress = "";
// 获取WiFi服务
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 判断WiFi是否开启
if (wifiManager.isWifiEnabled()) {
// 已经开启了WiFi
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
ipAdress = intToIp(ipAddress);
} else {
// 未开启WiFi
ipAdress = getLocalIpAddress();
}
boolean isRightIp = isRightIp(ipAdress);
if (!isRightIp) {
ipAdress = "";
}
return ipAdress;
}
/**
* 获取本机IPv4地址
*
* @return 本机IPv4地址
*/
private static String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return "";
}
private static String intToIp(int ipInt) {
StringBuilder sb = new StringBuilder();
sb.append(ipInt & 0xFF).append(".");
sb.append((ipInt >> 8) & 0xFF).append(".");
sb.append((ipInt >> 16) & 0xFF).append(".");
sb.append((ipInt >> 24) & 0xFF);
return sb.toString();
}
private static boolean isRightIp(String ipAddress) {
try {
String[] ips = ipAddress.split("\\.");
if (ips.length == 4) {
for (String ip : ips) {
if (Integer.parseInt(ip) < 0 || Integer.parseInt(ip) > 255) {
return false;
}
}
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 获取当前的网络状态 :没有网络-0:WIFI网络1:4G网络-4:3G网络-3:2G网络-2
* 自定义
*
* @return
*/
public static int getAPNType() {
int netType = 0;
ConnectivityManager manager =
(ConnectivityManager) AppContext.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
// !!需要修改
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
// NetworkInfo对象为空 则代表没有网络
if (networkInfo == null) {
return netType;
}
int nType = networkInfo.getType();
if (nType == ConnectivityManager.TYPE_WIFI) {
// WIFI
netType = 1;
} else if (nType == ConnectivityManager.TYPE_MOBILE) {
int nSubType = networkInfo.getSubtype();
TelephonyManager telephonyManager =
(TelephonyManager) AppContext.getContext().getSystemService(Context.TELEPHONY_SERVICE);
if (nSubType == TelephonyManager.NETWORK_TYPE_LTE && !telephonyManager.isNetworkRoaming()) {
netType = 4;
// 3G 联通的3G为UMTS或HSDPA 电信的3G为EVDO
} else if (nSubType == TelephonyManager.NETWORK_TYPE_UMTS || nSubType == TelephonyManager.NETWORK_TYPE_HSDPA
|| nSubType == TelephonyManager.NETWORK_TYPE_EVDO_0 && !telephonyManager.isNetworkRoaming()) {
netType = 3;
// 2G 移动和联通的2G为GPRS或EGDE,电信的2G为CDMA
} else if (nSubType == TelephonyManager.NETWORK_TYPE_GPRS || nSubType == TelephonyManager.NETWORK_TYPE_EDGE
|| nSubType == TelephonyManager.NETWORK_TYPE_CDMA && !telephonyManager.isNetworkRoaming()) {
netType = 2;
} else if (nSubType == TelephonyManager.NETWORK_TYPE_NR) {
netType = 5;
} else {
netType = 2;
}
}
return netType;
}
public static void onFailed(Context context, int errorCode, String errorMessage) {
IToast toaster = ArouterServiceManager.provide(IToast.class);
// handle null value
if (toaster != null) {
toaster
.showLong(String.format(ResUtils.getString(R.string.network_request_failed), errorCode, errorMessage));
}
}
/**
* 请求头 TraceID 生成32位随机数
*/
public static String getRandomUUIDForTraceID() {
try {
String randomUuidForTraceId = UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
return randomUuidForTraceId;
} catch (Exception e) {
return "";
}
}
}
... ...
package com.wd.capability.network;
import java.io.File;
import java.util.concurrent.TimeUnit;
import android.content.Context;
import android.text.TextUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.wd.capability.network.adapter.DoubleDefaultAdapter;
import com.wd.capability.network.adapter.IntegerDefaultAdapter;
import com.wd.capability.network.adapter.LongDefaultAdapter;
import com.wd.capability.network.adapter.StringNullAdapter;
import com.wd.capability.network.interceptor.BaseInterceptor;
import com.wd.capability.network.interceptor.LoggingInterceptor;
import com.wd.capability.network.interceptor.MultiDomainInterceptor;
import com.wd.capability.network.interceptor.TokenInterceptor;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Cache;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* @author wonder
* @date 2020/5/10
* RetrofitClient封装单例类, 实现网络请求
*/
public class RetrofitClient {
/**
* 缓存大小
*/
private static final int CACHE_TIMEOUT = 100 * 1024 * 1024;
/**
* 服务端根路径
*/
public static String baseUrl = NetManager.getNetManager().getBaseUrl();
private static Context mContext;
private static OkHttpClient okHttpClient;
private static Retrofit retrofit;
private static Gson gson;
private Cache cache = null;
private File httpCacheDirectory;
public static void init(Context context) {
mContext = context;
}
private static class SingletonHolder {
private static RetrofitClient INSTANCE = new RetrofitClient();
}
public static RetrofitClient getInstance() {
return SingletonHolder.INSTANCE;
}
private RetrofitClient() {
this(baseUrl);
}
private RetrofitClient(String url) {
if (mContext == null) {
return;
}
if (TextUtils.isEmpty(url)) {
url = baseUrl;
}
if (httpCacheDirectory == null) {
httpCacheDirectory = new File(mContext.getCacheDir(), NetManager.getNetManager().builder.getCacheFile());
}
try {
if (cache == null) {
cache = new Cache(httpCacheDirectory, CACHE_TIMEOUT);
}
} catch (Exception e) {
e.printStackTrace();
}
HttpsUtils.SslParams sslParams = HttpsUtils.getSslSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder().cache(cache);
builder.addInterceptor(new MultiDomainInterceptor())
.addInterceptor(new BaseInterceptor(mContext))
.addInterceptor(new TokenInterceptor(mContext));
if (BuildConfig.DEBUG) {
builder.addInterceptor(new LoggingInterceptor());
}
okHttpClient = builder.readTimeout(NetManager.getNetManager().builder.getReadTimeout(), TimeUnit.SECONDS)
.connectTimeout(NetManager.getNetManager().builder.getConnectTimeout(), TimeUnit.SECONDS)
.writeTimeout(NetManager.getNetManager().builder.getWriteTimeout(), TimeUnit.SECONDS)
// 这里你可以根据自己的机型设置同时连接的个数和时间,我这里8个,和每个保持时间为10s
.connectionPool(new ConnectionPool(8, 10, TimeUnit.SECONDS))
.build();
retrofit = new Retrofit.Builder().client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(buildGson()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(url)
.build();
}
/**
* create you ApiService
* Create an implementation of the API endpoints defined by the {@code service} interface.
*/
public <T> T create(final Class<T> service) {
if (service == null) {
throw new RuntimeException("Api service is null!");
}
return retrofit.create(service);
}
/**
* 线程切换
*
* @param observable
* @param subscriber
* @param <T>
* @return
*/
public static <T> T execute(Observable<T> observable, Observer<T> subscriber) {
observable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
return null;
}
/**
* 同步进行
*
* @param observable
* @param subscriber
* @param <T>
* @return
*/
public static <T> T executeSynchronize(Observable<T> observable, Observer<T> subscriber) {
observable.subscribeOn(AndroidSchedulers.mainThread())
.unsubscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
return null;
}
/**
* 增加后台返回""和"null"的处理
* 1.int=>0
* 2.double=>0.00
* 3.long=>0L
*
* @return
*/
public static Gson buildGson() {
if (gson == null) {
gson = new GsonBuilder().registerTypeAdapter(Integer.class, new IntegerDefaultAdapter())
.registerTypeAdapter(int.class, new IntegerDefaultAdapter())
.registerTypeAdapter(Double.class, new DoubleDefaultAdapter())
.registerTypeAdapter(double.class, new DoubleDefaultAdapter())
.registerTypeAdapter(Long.class, new LongDefaultAdapter())
.registerTypeAdapter(long.class, new LongDefaultAdapter())
.registerTypeAdapter(String.class, new StringNullAdapter())
.create();
}
return gson;
}
}
... ...
/*
* Copyright (c) Wondertek Technologies Co., Ltd. 2019-2022. All rights reserved.
*/
package com.wd.capability.network.adapter;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSyntaxException;
import java.lang.reflect.Type;
/**
* 描述:
*
* @author : lvjinhui
* @since: 2022/6/25
*/
public class DoubleDefaultAdapter implements JsonSerializer<Double>, JsonDeserializer<Double> {
@Override
public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
if ("".equals(json.getAsString()) || "null".equals(json.getAsString())) {//定义为double类型,如果后台返回""或者null,则返回0.00
return 0.00;
}
} catch (Exception ignore) {
}
try {
return json.getAsDouble();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
@Override
public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
}
... ...
/*
* Copyright (c) Wondertek Technologies Co., Ltd. 2019-2022. All rights reserved.
*/
package com.wd.capability.network.adapter;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSyntaxException;
import java.lang.reflect.Type;
/**
* 描述:对返回值为空处理
*
* @author : lvjinhui
* @since: 2022/6/25
*/
public class IntegerDefaultAdapter implements JsonSerializer<Integer>, JsonDeserializer<Integer> {
@Override
public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
/**
* 定义为int类型,如果后台返回""或者null,则返回0
*/
if ("".equals(json.getAsString()) || "null".equals(json.getAsString())) {
return 0;
}
} catch (Exception ignore) {
ignore.printStackTrace();
}
try {
return json.getAsInt();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
@Override
public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
}
... ...
/*
* Copyright (c) Wondertek Technologies Co., Ltd. 2019-2022. All rights reserved.
*/
package com.wd.capability.network.adapter;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSyntaxException;
import java.lang.reflect.Type;
/**
* 描述:对返回值为空处理
*
* @author : lvjinhui
* @since: 2022/6/25
*/
public class LongDefaultAdapter implements JsonSerializer<Long>, JsonDeserializer<Long> {
@Override
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
/**
* 定义为long类型,如果后台返回""或者null,则返回0
*/
if ("".equals(json.getAsString()) || "null".equals(json.getAsString())) {
return 0L;
}
} catch (Exception ignore) {
}
try {
return json.getAsLong();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
@Override
public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
}
... ...
/*
* Copyright (c) Wondertek Technologies Co., Ltd. 2019-2022. All rights reserved.
*/
package com.wd.capability.network.adapter;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
/**
* 描述:
*
* @author : lvjinhui
* @since: 2022/6/25
*/
public class StringNullAdapter extends TypeAdapter<String> {
@Override
public String read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return "";//原先是返回Null,这里改为返回空字符串
}
String jsonStr = reader.nextString();
if("null".equals(jsonStr)) {
return "";
}else {
return jsonStr;
}
}
@Override
public void write(JsonWriter writer, String value) throws IOException {
if (value == null) {
writer.nullValue();
return;
}
writer.value(value);
}
}
... ...
package com.wd.capability.network.api;
import com.wd.capability.network.bean.TokenBean;
import com.wd.capability.network.response.BaseResponse;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Header;
import retrofit2.http.POST;
/**
* 描述:接口定义
*
* @author : lvjinhui
* @since: 2022/12/15
*/
public interface IRefreshToken {
@POST("api/rmrb-user-center/auth/zh/c/refreshToken")
Call<BaseResponse<TokenBean>> getJwtToken(@Header("RMRB-X-TOKEN")String token, @Body RequestBody body);
}
... ...
package com.wd.capability.network.bean;
/**
* Time:2022/10/10
* Author:ypf
* Description:
*/
public class FetchAccessTokenBean {
private String access_token;
private String expires_in;
private String scope;
private String token_type;
public FetchAccessTokenBean() {
}
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getToken_type() {
return token_type;
}
public void setToken_type(String token_type) {
this.token_type = token_type;
}
}
... ...
package com.wd.capability.network.bean;
import java.io.Serializable;
/**
* 描述:存放md5值
*
* @author : lvjinhui
* @since: 2022/10/26
*/
public class MetaBean implements Serializable {
/**
* 接口的md5比较
*/
private String md5;
/**
* feed组件配置动态接口,访问到的数据配置的md5值
*/
private String fmd5;
public String getMd5() {
return md5;
}
public void setMd5(String md5) {
this.md5 = md5;
}
public String getFmd5() {
return fmd5;
}
public void setFmd5(String fmd5) {
this.fmd5 = fmd5;
}
}
... ...
package com.wd.capability.network.bean;
public class NetworkEventConstants {
/**
* 强制退出登录,去登录页面
*/
public static final String FORCE_USER_LOGIN_OUT = "force_user_login_out";
/**
* 网络请求流量超标
*/
public static final String FLOW_TOO_LARGE = "flow_toolarge";
}
... ...
package com.wd.capability.network.bean;
import java.io.Serializable;
/**
* 描述:token
*
* @author : lvjinhui
* @since: 2022/9/1
*/
public class TokenBean implements Serializable {
private String jwtToken;
private String refreshToken;
public String getJwtToken() {
return jwtToken;
}
public void setJwtToken(String jwtToken) {
this.jwtToken = jwtToken;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
}
... ...
package com.wd.capability.network.cachedata;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.SystemClock;
import android.text.TextUtils;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.wd.base.log.Logger;
import com.wd.capability.network.NetManager;
import com.wd.foundation.wdkitcore.tools.AssertUtils;
import com.wd.foundation.wdkitcore.tools.JsonUtils;
/**
* 描述:
* TODO 上抛,业务层处理
*
* @author : lvjinhui
* @since: 2022/10/16
*/
public class CacheData {
/**
* 1天的缓存数据(ms)
*/
public static final long oneDayTime = 24 * 60 * 60 * 1000;
/**
* 底部导航栏缓存的数据key
*/
public static final String bottomCacheKey = "bottom_cache_data_key";
/**
* 头部频道缓存的数据key
*/
public static final String channelCacheDataKey = "channel_data_cache_id_";
/**
* 页面page组件的数据key
*/
public static final String comPageInfoCacheKey = "com_pageInfo_cache_id_";
/**
* 页面组件的数据key
*/
public static final String compGroupInfoDataCacheKey = "com_data_info_cache_id_";
/**
* 数据源接口缓存
*/
public static final String dataSourceCacheKey = "data_source_data_cache_type_";
/**
* 我的页面头部信息key
*/
public static final String mineTopInfoCacheKey = "mine_top_info_cache_id_";
/**
* 关注列表头部信息key
*/
public static final String attentionTopInfoCacheKey = "attention_top_info_cache_id_";
private static final String TAG = "CacheData";
@SerializedName("networkData")
@Expose
public Object networkData;
@SerializedName("updateTimeInMillis")
@Expose
public long updateTimeInMillis;
@SerializedName("md5")
@Expose
public String md5;
public static void saveDataToPreference(String cachePreferenceKey, Object data, String responseMd5) {
if (data != null) {
CacheData cacheData = new CacheData();
cacheData.networkData = data;
cacheData.updateTimeInMillis = SystemClock.uptimeMillis();
cacheData.md5 = responseMd5;
CacheDataPreferenceUtil.getInstance()
.setString(cachePreferenceKey, JsonUtils.convertObjectToJson(cacheData));
}
}
public String getNetWorkData() {
if (networkData != null) {
return JsonUtils.convertObjectToJson(networkData);
}
return "";
}
/**
* 比较缓存和接口返回数据是否一致
*
* @param key
* @param resultData
* @return
*/
public static boolean isSameData(String key, Object resultData) {
if (!TextUtils.isEmpty(key) && resultData != null) {
String cacheDataStr = CacheDataPreferenceUtil.getInstance().getString(key);
if (TextUtils.isEmpty(cacheDataStr)) {
return false;
}
// 保存的数据转成CacheData
CacheData cacheData = JsonUtils.convertJsonToObject(cacheDataStr, CacheData.class);
if (cacheData != null) {
// 获取保存的NetWorkData 和 resultData 比较
if (cacheData.getNetWorkData().equals(JsonUtils.convertObjectToJson(resultData))) {
Logger.t(TAG).e("接口返回数据和缓存数据一致");
return true;
}
}
}
return false;
}
/**
* 间隔多久进行刷新
*
* @return
*/
public boolean needRefresh(long refreshTime) {
long currentTimeMillis = SystemClock.uptimeMillis();
// 当前时间减去保存数据的时间 > 刷新间隔时间 就要进行刷新
if (Math.abs(currentTimeMillis - updateTimeInMillis) > refreshTime) {
return true;
}
return false;
}
/**
* 是否需要刷新
*
* @param responseMd5
* @return
*/
public boolean needRefreshByMd5(String responseMd5) {
if (TextUtils.isEmpty(md5) || TextUtils.isEmpty(responseMd5)) {
return false;
}
if (!md5.equals(responseMd5)) {
return true;
}
return false;
}
/**
* 获取到保存的数据
*
* @param key
* @return
*/
public static CacheData getLocalCacheData(String key) {
if (!TextUtils.isEmpty(key)) {
String cacheDataStr = CacheDataPreferenceUtil.getInstance().getString(key);
if (!TextUtils.isEmpty(cacheDataStr)) {
// 保存的数据转成CacheData
CacheData cacheData = JsonUtils.convertJsonToObject(cacheDataStr, CacheData.class);
if (cacheData != null) {
return cacheData;
}
}
}
return null;
}
/**
* 判断关注tab缓存是否存在
*
* @param userId
* @return
*/
// public static boolean haveMyFollowLocalCacheData(String userId) {
// CacheData userFollowCache = CacheData.getLocalCacheData(CacheData.mineFollowCacheKey + userId);
// if (userFollowCache != null && !TextUtils.isEmpty(userFollowCache.getNetWorkData())) {
// return true;
// }
// return false;
// }
/**
* 预置的正式环境 底部预置数据
*
* @return
*/
public static String getBottomPresetsData() {
String tag = NetManager.getUrlTag();
String bottomPresetsData = "";
if (NetManager.BASE_URL_REL.equals(tag)) {
bottomPresetsData = AssertUtils.readJsonFile("bottomPresetsData.json");
}
// else if (NetManager.BASE_URL_SIT.equals(tag)) {
// bottomPresetsData = AssertUtils.readJsonFile("bottomPresetsData_sit.json");
// } else if (NetManager.BASE_URL_UAT.equals(tag)) {
// bottomPresetsData = AssertUtils.readJsonFile("bottomPresetsData_uat.json");
// }
if (bottomPresetsData != null) {
return bottomPresetsData;
}
return "";
}
/**
* 预置的正式环境 频道预置数据
*
* @return
*/
public static String getChannelPresetsData(String id) {
String tag = NetManager.getUrlTag();
String channelPresetsData = "";
if (NetManager.BASE_URL_REL.equals(tag)) {
channelPresetsData = AssertUtils.readJsonFile("channelPresetsData.json");
}
// else if (NetManager.BASE_URL_SIT.equals(tag)){
// channelPresetsData = AssertUtils.readJsonFile("channelPresetsData_sit.json");
// } else if (NetManager.BASE_URL_UAT.equals(tag)){
// channelPresetsData = AssertUtils.readJsonFile("channelPresetsData_uat.json");
// }
try {
JSONObject jsonObject = new JSONObject(channelPresetsData);
if (jsonObject != null) {
JSONArray jsonArray = jsonObject.optJSONArray("presetsData");
if (jsonArray != null && jsonArray.length() > 0) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
String id1 = jsonObject1.optString("id");
if (id.equals(id1)) {
return jsonObject1.toString();
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return "";
}
}
... ...
package com.wd.capability.network.cachedata;
import android.text.TextUtils;
import com.wd.foundation.wdkitcore.tools.SpUtils;
/**
* 描述:保存缓存数据
* TODO 上抛,业务层处理
*
* @author : lvjinhui
* @since: 2022/10/16
*/
public class CacheDataPreferenceUtil {
private static CacheDataPreferenceUtil instance;
private CacheDataPreferenceUtil() {
}
public static CacheDataPreferenceUtil getInstance() {
if (instance == null) {
instance = new CacheDataPreferenceUtil();
}
return instance;
}
/**
* 保存数据
*
* @param key
* @param data
*/
protected void setString(String key, String data) {
if (TextUtils.isEmpty(key)) {
return;
}
SpUtils.saveNetworkDataCache(key, data);
}
/**
* 获取保存的数据
*
* @param key
* @return
*/
protected String getString(String key) {
if (TextUtils.isEmpty(key)) {
return "";
}
String networkDataCache = SpUtils.getNetworkDataCache(key);
return networkDataCache;
}
}
... ...
package com.wd.capability.network.constant;
/**
* 描述:网络相关常量定义
* TODO 待拆,往上抛
*
* @author : lvjinhui
* data: 2022/7/13
*/
public abstract class NetConstant {
/**
* wifi
*/
public static final String NET_WIFI_TYPE = "1";
/**
* 数据网络
*/
public static final String NET_CELL_TYPE = "0";
/**
* 无网络
*/
public static final String NET_ERROR_TYPE = "2";
// ************************网关*****************************
/**
* 中文端的 sit 0af1f9085e484c97b2a44704bae72c07
*/
public static final String APPCODE_VALUE_SIT = "0af1f9085e484c97b2a44704bae72c07";
/**
* 海外的 sit
*/
// public static final String APPCODE_VALUE_SIT = "13454e77e1394ce694df74e0b2e65bb5";
/**
* uat
*/
public static final String APPCODE_VALUE_UTA = "83092caa603a421aa0222308b3f6b27a";
/**
* release
*/
public static final String APPCODE_VALUE_RELEASE = "3d4181bceeb94d9780e10dbb6c67bbf6";
/**
* dev
*/
public static final String APPCODE_VALUE_DEV = "ff33172859e14f9a8299e3bd769e79f9";
/**
* 网关APPCODE
*/
public static final String APPCODE_SIT = "APPCODE " + APPCODE_VALUE_SIT;
public static final String APPCODE_UTA = "APPCODE " + APPCODE_VALUE_UTA;
public static final String APPCODE_RELEASE = "APPCODE " + APPCODE_VALUE_RELEASE;
public static final String APPCODE_DEV = "APPCODE " + APPCODE_VALUE_DEV;
public static final int API_CONNECT_TIME_OUT = 10;
public static final int API_IM_CONNECT_TIME_OUT = 10;
public static final int API_READ_TIME_OUT = 10;
public static final int API_WRITE_TIME_OUT = 10;
public static final String API_SP_NAME_NET = "net";
public static final String API_SP_KEY_NET_COOKIE_SET = "cookie_set";
public static final String API_SP_KEY_NET_HEADER_AUTH = "header_auth";
public static final int REQUEST_SUCCESS_CODE = 200;
}
... ...
package com.wd.capability.network.constant;
/**
* 入参常量类
*
* @author shishuangxi_wd
* @date 2022/6/25 11:29
*/
public class ParameterConstant {
/**
* JSON 格式
*/
public final static String HEADER_JSON_TYPE = "application/json; charset=utf-8";
public final static String CONTENTTYPE = "Content-Type";
public final static String PLAT = "plat";
public final static String TIMESTAMP = "timestamp";
public final static String SYSTEM = "system";
public static final String DEVICE_ID = "device_id";
public final static String VERSIONCODE = "versionCode";
public final static String VERSIONNAME = "version_name";
/**
* app版本-h5协议用
*/
public final static String APP_VERSION = "appVersion";
public final static String BUILDVERSION = "build_version";
/**
* 添加cookie值到header,value形式为
*/
public final static String COOKIE = "cookie";
public final static String USERAGENT = "User-Agent";
public final static String OS_VERSION = "os_version";
public final static String CITY = "city";
public final static String CITY_CODE = "city_dode";
public final static String AD_CODE = "adcode";
public static final String USER_ID = "userId";
public static final String USER_NAME = "userName";
public static final String USER_TYPE = "userType";
public static final String USER_HEADER_URL = "userHeaderUrl";
public static final String REFRESH_TOKEN = "refreshToken";
public static final String DEVICEID = "deviceId";
public static final String RMRB_X_TOKEN = "RMRB-X-TOKEN";
public static final String IMEI = "imei";
public final static String CHANNEL = "channel";
public static final String TIME = "time";
/**
* 语言国际化
*/
public final static String ACCEPT_LANGUAGE = "Accept-Language";
/**
* 端标识-h5协议用
*/
public final static String LANG = "lang";
/**
* 状态栏高度
*/
public final static String SCREEN_STATUS_BAR_HEIGHT = "screenStatusBarHeight";
/**
* 屏幕高度
*/
public final static String SCREEN_HEIGHT = "screenHeight";
/**
* 屏幕宽度
*/
public final static String SCREEN_WIDTH = "screenWidth";
/**
* 环境
*/
public final static String ENVIRONMENT = "environment";
/**
* light (亮色模式)、dark(暗色模式)
*/
public final static String DARK_MODE = "darkMode";
/**
* 经度
*/
public final static String LONGITUDE = "longitude";
/**
* 纬度
*/
public final static String LATITUDE = "latitude";
/**
* 地址信息
*/
public final static String ADDRESS = "address";
/**
* 网络环境:0:无网 1:WiFi 2:2G 3:3G 4:4G 5:5G
*/
public final static String NETWORK_STATUS = "networkStatus";
/**
* App服务协议
*/
public final static String AGREEMENT_URL = "agreementURL";
public static final String CONTENTID = "contentId";
public static final String CONTENT_TYPE = "contentType";
public static final String CONTENTIDS = "contentIds";
public static final String CONTENT_SOURCE = "contentSource";
public static final String RETURN_COUNT = "returnCount";
public static final String ITEMID = "itemId";
public final static String TAG = "tag";
public final static String STRATEGY = "strategy";
public final static String USERID = "userId";
public static final String SEARCH_TYPE = "searchType";
public final static String PAGENUM = "pageNum";
public final static String PAGESIZE = "pageSize";
public static final String KEYWORD = "keyword";
public final static String SERIALS_ID = "serialsId";
public static final String CREATORID = "creatorId";
public static final String NAME = "name";
public static final String INTRODUCTION = "introduction";
public static final String HEADER_PHOTO_URL = "headerPhotoUrl";
public static final String COUNTRY_CODE = "countryCode";
public static final String PROCINCE_CODE = "provinceCode";
public static final String CITYCODE = "cityCode";
public static final String DISTRICT_CODE = "districtCode";
public static final String PERIOD = "period";
public static final String COMMENT_ID = "commentId";
public static final String CREATOR_DIRECTORY_ID = "creatorDirectoryId";
public static final String EXCLUDE_IDS = "excludeIds";
public static final String STATUS = "status";
public static final String TITLE = "title";
public static final String CHANNELID = "channelId";
/**
* 提交评论
*/
public static final String COMMENT_CONTENT = "commentContent";
public static final String COMMENT_TYPE = "commentType";
public static final String COMMENT_PICS = "commentPics";
public static final String TARGET_ID = "targetId";
public static final String TARGET_TYPE = "targetType";
public static final String PARENT_ID = "parentId";
public static final String ROOT_COMMENT_ID = "rootCommentId";
public static final String TARGET_REL_ID ="targetRelId" ;
public static final String TARGET_REL_TYPE ="targetRelType" ;
//绑定关系
public static final String CONTENT_RELLD ="contentRelId" ;
//绑定
public static final String CONTENT_REL_TYPE ="relType" ;
public static final String CONTENT_REL_ID ="relId" ;
public static final String SHARE_OPT ="shareOpt" ;
public static final String REQUEST_TYPE ="type" ;
public static final String REQUEST_TARGET_TITLE ="targetTitle" ;
public static final String REQUEST_KEY_ARTICLE="keyArticle" ;
public static final String REQUEST_TARGET_REL_OBJECT_ID ="targetRelObjectId" ;
/**
* 客户端日志链路追踪traceid生成:在每个请求头加上参数Key:EagleEye-TraceID ,value为32位生成随机值
*/
public final static String EagleEyeTraceID = "EagleEye-TraceID";
}
... ...
package com.wd.capability.network.cookie;
import java.util.List;
import com.wd.capability.network.cookie.store.CookieStore;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
/**
* @author wondertek
* @date 2020/5/13
*/
public class CookieJarImpl implements CookieJar {
private CookieStore cookieStore;
public CookieJarImpl(CookieStore cookieStore) {
if (cookieStore == null) {
throw new IllegalArgumentException("cookieStore can not be null!");
}
this.cookieStore = cookieStore;
}
@Override
public synchronized void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.saveCookie(url, cookies);
}
@Override
public synchronized List<Cookie> loadForRequest(HttpUrl url) {
return cookieStore.loadCookie(url);
}
public CookieStore getCookieStore() {
return cookieStore;
}
}
\ No newline at end of file
... ...
package com.wd.capability.network.cookie.store;
import java.util.List;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
/**
* @author wondertek
* @date 2020/5/13
*/
public interface CookieStore {
/**
* 保存url对应所有cookie
*
* @param url
* @param cookie
*/
void saveCookie(HttpUrl url, List<Cookie> cookie);
/**
* 保存url对应所有cookie
*
* @param url
* @param cookie
*/
void saveCookie(HttpUrl url, Cookie cookie);
/**
* 加载url所有的cookie
*
* @param url
* @return
*/
List<Cookie> loadCookie(HttpUrl url);
/**
* 获取当前所有保存的cookie
*
* @return
*/
List<Cookie> getAllCookie();
/**
* 获取当前url对应的所有的cookie
*
* @param url
* @return
*/
List<Cookie> getCookie(HttpUrl url);
/**
* 根据url和cookie移除对应的cookie
*
* @param url
* @param cookie
* @return
*/
boolean removeCookie(HttpUrl url, Cookie cookie);
/**
* 根据url移除所有的cookie
*
* @param url
* @return
*/
boolean removeCookie(HttpUrl url);
/**
* 移除所有的cookie
*
* @return
*/
boolean removeAllCookie();
}
... ...
package com.wd.capability.network.cookie.store;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
/**
*
* @author wondertek
* @date 2020/5/13
*/
public class MemoryCookieStore implements CookieStore {
private final HashMap<String, List<Cookie>> memoryCookies = new HashMap<>();
@Override
public synchronized void saveCookie(HttpUrl url, List<Cookie> cookies) {
List<Cookie> oldCookies = memoryCookies.get(url.host());
List<Cookie> needRemove = new ArrayList<>();
for (Cookie newCookie : cookies) {
for (Cookie oldCookie : oldCookies) {
if (newCookie.name().equals(oldCookie.name())) {
needRemove.add(oldCookie);
}
}
}
oldCookies.removeAll(needRemove);
oldCookies.addAll(cookies);
}
@Override
public synchronized void saveCookie(HttpUrl url, Cookie cookie) {
List<Cookie> cookies = memoryCookies.get(url.host());
List<Cookie> needRemove = new ArrayList<>();
for (Cookie item : cookies) {
if (cookie.name().equals(item.name())) {
needRemove.add(item);
}
}
cookies.removeAll(needRemove);
cookies.add(cookie);
}
@Override
public synchronized List<Cookie> loadCookie(HttpUrl url) {
List<Cookie> cookies = memoryCookies.get(url.host());
if (cookies == null) {
cookies = new ArrayList<>();
memoryCookies.put(url.host(), cookies);
}
return cookies;
}
@Override
public synchronized List<Cookie> getAllCookie() {
List<Cookie> cookies = new ArrayList<>();
Set<String> httpUrls = memoryCookies.keySet();
for (String url : httpUrls) {
cookies.addAll(memoryCookies.get(url));
}
return cookies;
}
@Override
public List<Cookie> getCookie(HttpUrl url) {
List<Cookie> cookies = new ArrayList<>();
List<Cookie> urlCookies = memoryCookies.get(url.host());
if (urlCookies != null) {
cookies.addAll(urlCookies);
}
return cookies;
}
@Override
public synchronized boolean removeCookie(HttpUrl url, Cookie cookie) {
List<Cookie> cookies = memoryCookies.get(url.host());
return (cookie != null) && cookies.remove(cookie);
}
@Override
public synchronized boolean removeCookie(HttpUrl url) {
return memoryCookies.remove(url.host()) != null;
}
@Override
public synchronized boolean removeAllCookie() {
memoryCookies.clear();
return true;
}
}
... ...
package com.wd.capability.network.cookie.store;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.SystemClock;
import android.text.TextUtils;
import com.wd.base.log.Logger;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
/**
*
* @author wondertek
* @date 2017/5/13
*/
public class PersistentCookieStore implements CookieStore {
private static final String LOG_TAG = "PersistentCookieStore";
/**
* cookie使用prefs保存
*/
private static final String COOKIE_PREFS = "wonder_cookie";
/**
* cookie持久化的统一前缀
*/
private static final String COOKIE_NAME_PREFIX = "cookie_";
private final HashMap<String, ConcurrentHashMap<String, Cookie>> cookies;
private final SharedPreferences cookiePrefs;
public PersistentCookieStore(Context context) {
cookiePrefs = context.getSharedPreferences(COOKIE_PREFS, Context.MODE_PRIVATE);
cookies = new HashMap<>();
//将持久化的cookies缓存到内存中,数据结构为 Map<Url.host, Map<Cookie.name, Cookie>>
Map<String, ?> prefsMap = cookiePrefs.getAll();
for (Map.Entry<String, ?> entry : prefsMap.entrySet()) {
if ((entry.getValue()) != null && !entry.getKey().startsWith(COOKIE_NAME_PREFIX)) {
//获取url对应的所有cookie的key,用","分割
String[] cookieNames = TextUtils.split((String) entry.getValue(), ",");
for (String name : cookieNames) {
//根据对应cookie的Key,从xml中获取cookie的真实值
String encodedCookie = cookiePrefs.getString(COOKIE_NAME_PREFIX + name, null);
if (encodedCookie != null) {
Cookie decodedCookie = decodeCookie(encodedCookie);
if (decodedCookie != null) {
if (!cookies.containsKey(entry.getKey())) {
cookies.put(entry.getKey(), new ConcurrentHashMap<String, Cookie>());
}
cookies.get(entry.getKey()).put(name, decodedCookie);
}
}
}
}
}
}
private String getCookieToken(Cookie cookie) {
return cookie.name() + "@" + cookie.domain();
}
/** 当前cookie是否过期 */
private static boolean isCookieExpired(Cookie cookie) {
return cookie.expiresAt() < SystemClock.uptimeMillis();
}
/** 根据当前url获取所有需要的cookie,只返回没有过期的cookie */
@Override
public List<Cookie> loadCookie(HttpUrl url) {
ArrayList<Cookie> ret = new ArrayList<>();
if (cookies.containsKey(url.host())) {
Collection<Cookie> urlCookies = cookies.get(url.host()).values();
for (Cookie cookie : urlCookies) {
if (isCookieExpired(cookie)) {
removeCookie(url, cookie);
} else {
ret.add(cookie);
}
}
}
return ret;
}
/** 将url的所有Cookie保存在本地 */
@Override
public void saveCookie(HttpUrl url, List<Cookie> urlCookies) {
if (!cookies.containsKey(url.host())) {
cookies.put(url.host(), new ConcurrentHashMap<String, Cookie>(16));
}
for (Cookie cookie : urlCookies) {
//当前cookie是否过期
if (isCookieExpired(cookie)) {
removeCookie(url, cookie);
} else {
saveCookie(url, cookie, getCookieToken(cookie));
}
}
}
@Override
public void saveCookie(HttpUrl url, Cookie cookie) {
if (!cookies.containsKey(url.host())) {
cookies.put(url.host(), new ConcurrentHashMap<String, Cookie>(16));
}
//当前cookie是否过期
if (isCookieExpired(cookie)) {
removeCookie(url, cookie);
} else {
saveCookie(url, cookie, getCookieToken(cookie));
}
}
/**
* 保存cookie,并将cookies持久化到本地,数据结构为
* Url.host -> Cookie1.name,Cookie2.name,Cookie3.name
* cookie_Cookie1.name -> CookieString
* cookie_Cookie2.name -> CookieString
*/
private void saveCookie(HttpUrl url, Cookie cookie, String name) {
//内存缓存
cookies.get(url.host()).put(name, cookie);
//文件缓存
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.putString(url.host(), TextUtils.join(",", cookies.get(url.host()).keySet()));
prefsWriter.putString(COOKIE_NAME_PREFIX + name, encodeCookie(new SerializableHttpCookie(cookie)));
prefsWriter.apply();
}
/** 根据url移除当前的cookie */
@Override
public boolean removeCookie(HttpUrl url, Cookie cookie) {
String name = getCookieToken(cookie);
if (cookies.containsKey(url.host()) && cookies.get(url.host()).containsKey(name)) {
//内存移除
cookies.get(url.host()).remove(name);
//文件移除
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
if (cookiePrefs.contains(COOKIE_NAME_PREFIX + name)) {
prefsWriter.remove(COOKIE_NAME_PREFIX + name);
}
prefsWriter.putString(url.host(), TextUtils.join(",", cookies.get(url.host()).keySet()));
prefsWriter.apply();
return true;
} else {
return false;
}
}
@Override
public boolean removeCookie(HttpUrl url) {
if (cookies.containsKey(url.host())) {
//文件移除
Set<String> cookieNames = cookies.get(url.host()).keySet();
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
for (String cookieName : cookieNames) {
if (cookiePrefs.contains(COOKIE_NAME_PREFIX + cookieName)) {
prefsWriter.remove(COOKIE_NAME_PREFIX + cookieName);
}
}
prefsWriter.remove(url.host()).apply();
//内存移除
cookies.remove(url.host());
return true;
} else {
return false;
}
}
@Override
public boolean removeAllCookie() {
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.clear().apply();
cookies.clear();
return true;
}
/** 获取所有的cookie */
@Override
public List<Cookie> getAllCookie() {
List<Cookie> ret = new ArrayList<>();
for (String key : cookies.keySet()) {
ret.addAll(cookies.get(key).values());
}
return ret;
}
@Override
public List<Cookie> getCookie(HttpUrl url) {
List<Cookie> ret = new ArrayList<>();
Map<String, Cookie> mapCookie = cookies.get(url.host());
if (mapCookie != null) {
ret.addAll(mapCookie.values());
}
return ret;
}
/**
* cookies 序列化成 string
*
* @param cookie 要序列化的cookie
* @return 序列化之后的string
*/
private String encodeCookie(SerializableHttpCookie cookie) {
if (cookie == null) {
return null;
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ObjectOutputStream outputStream = new ObjectOutputStream(os);
outputStream.writeObject(cookie);
} catch (IOException e) {
Logger.t(LOG_TAG).d( "IOException in encodeCookie", e);
return null;
}
return byteArrayToHexString(os.toByteArray());
}
/**
* 将字符串反序列化成cookies
*
* @param cookieString cookies string
* @return cookie object
*/
private Cookie decodeCookie(String cookieString) {
byte[] bytes = hexStringToByteArray(cookieString);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
Cookie cookie = null;
try {
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
cookie = ((SerializableHttpCookie) objectInputStream.readObject()).getCookie();
} catch (IOException e) {
Logger.t(LOG_TAG).d( "IOException in decodeCookie", e);
} catch (ClassNotFoundException e) {
Logger.t(LOG_TAG).d( "ClassNotFoundException in decodeCookie", e);
}
return cookie;
}
/**
* 二进制数组转十六进制字符串
*
* @param bytes byte array to be converted
* @return string containing hex values
*/
private String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte element : bytes) {
int v = element & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase(Locale.US);
}
/**
* 十六进制字符串转二进制数组
*
* @param hexString string of hex-encoded values
* @return decoded byte array
*/
private byte[] hexStringToByteArray(String hexString) {
int len = hexString.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i + 1), 16));
}
return data;
}
}
\ No newline at end of file
... ...
package com.wd.capability.network.cookie.store;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import okhttp3.Cookie;
/**
* @author wondertek
*/
public class SerializableHttpCookie implements Serializable {
private static final long serialVersionUID = 6374381323722046732L;
private transient final Cookie cookie;
private transient Cookie clientCookie;
public SerializableHttpCookie(Cookie cookie) {
this.cookie = cookie;
}
public Cookie getCookie() {
Cookie bestCookie = cookie;
if (clientCookie != null) {
bestCookie = clientCookie;
}
return bestCookie;
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeObject(cookie.name());
out.writeObject(cookie.value());
out.writeLong(cookie.expiresAt());
out.writeObject(cookie.domain());
out.writeObject(cookie.path());
out.writeBoolean(cookie.secure());
out.writeBoolean(cookie.httpOnly());
out.writeBoolean(cookie.hostOnly());
out.writeBoolean(cookie.persistent());
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
String name = (String) in.readObject();
String value = (String) in.readObject();
long expiresAt = in.readLong();
String domain = (String) in.readObject();
String path = (String) in.readObject();
boolean secure = in.readBoolean();
boolean httpOnly = in.readBoolean();
boolean hostOnly = in.readBoolean();
boolean persistent = in.readBoolean();
Cookie.Builder builder = new Cookie.Builder();
builder = builder.name(name);
builder = builder.value(value);
builder = builder.expiresAt(expiresAt);
builder = hostOnly ? builder.hostOnlyDomain(domain) : builder.domain(domain);
builder = builder.path(path);
builder = secure ? builder.secure() : builder;
builder = httpOnly ? builder.httpOnly() : builder;
clientCookie = builder.build();
}
}
\ No newline at end of file
... ...
package com.wd.capability.network.interceptor;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import android.content.Context;
import android.os.SystemClock;
import android.text.TextUtils;
import com.wd.capability.network.NetManager;
import com.wd.capability.network.NetworkUtils;
import com.wd.capability.network.constant.NetConstant;
import com.wd.capability.network.constant.ParameterConstant;
import com.wd.foundation.wdinterface.ILoginService;
import com.wd.foundation.wdinterface.IProvinceService;
import com.wd.foundation.wdinterface.app.IAppInfoService;
import com.wd.foundation.wdkitcore.router.ArouterServiceManager;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
/**
* @author wondertek
* @date 2021/3/5
*/
public class BaseInterceptor implements Interceptor {
private final ConcurrentHashMap<String, String> headers = new ConcurrentHashMap<String, String>();
private Context context;
public BaseInterceptor(Context mContext) {
this.context = mContext;
headers.clear();
}
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
headers.put(ParameterConstant.CONTENTTYPE, ParameterConstant.HEADER_JSON_TYPE);
IAppInfoService appInfoService = ArouterServiceManager.provide(IAppInfoService.class);
headers.put(ParameterConstant.PLAT, appInfoService.getPlat());
headers.put(ParameterConstant.TIMESTAMP, SystemClock.uptimeMillis() + "");
headers.put(ParameterConstant.SYSTEM, appInfoService.getSystem());
headers.put(ParameterConstant.IMEI, appInfoService.getDeviceId());
headers.put(ParameterConstant.DEVICE_ID, appInfoService.getDeviceId());
headers.put(ParameterConstant.VERSIONCODE, appInfoService.getVersionCode());
headers.put(ParameterConstant.VERSIONNAME, appInfoService.getVersionName());
headers.put(ParameterConstant.BUILDVERSION, appInfoService.getBuildVersion());
headers.put(ParameterConstant.USERAGENT, System.getProperty("http.agent"));
/**
* 客户端日志链路追踪traceid生成:在每个请求头加上参数Key:EagleEye-TraceID ,value为32位生成随机值
*/
headers.put(ParameterConstant.EagleEyeTraceID, NetworkUtils.getRandomUUIDForTraceID());
try {
// 获取手机系统版本号
headers.put(ParameterConstant.OS_VERSION, appInfoService.getOsVersion());
IProvinceService provinceService = ArouterServiceManager.provide(IProvinceService.class);
String city = provinceService.getCityName();
String districtCode = provinceService.getProvinceCode();
String cityCode = provinceService.getCityId();
if (!TextUtils.isEmpty(city)) {
headers.put(ParameterConstant.CITY, URLEncoder.encode(city, "UTF-8"));
}
if (!TextUtils.isEmpty(districtCode)) {
headers.put(ParameterConstant.AD_CODE, URLEncoder.encode(districtCode, "UTF-8"));
}
if (!TextUtils.isEmpty(cityCode)) {
headers.put(ParameterConstant.CITY_CODE, URLEncoder.encode(cityCode, "UTF-8"));
}
} catch (Exception e) {
}
ILoginService loginService = ArouterServiceManager.provide(ILoginService.class);
String token = loginService.getUserToken();
if (!TextUtils.isEmpty(token)) {
headers.put(ParameterConstant.RMRB_X_TOKEN, token);
headers.put(ParameterConstant.USER_TYPE, loginService.getUserType() + "");
headers.put(ParameterConstant.COOKIE, "RMRB-X-TOKEN=" + token);
} else {
headers.put(ParameterConstant.RMRB_X_TOKEN, "");
headers.remove(ParameterConstant.USER_TYPE);
headers.put(ParameterConstant.COOKIE, "");
}
String userId = loginService.getUserId();
if (!TextUtils.isEmpty(userId)) {
headers.put(ParameterConstant.USER_ID, userId);
} else {
headers.remove(ParameterConstant.USER_ID);
}
// 添加测试头作为测试
String tag = NetManager.getUrlTag();
if (NetManager.BASE_URL_SIT.equals(tag)) {
// sit环境
headers.put("X-Ca-Stage", "TEST");
headers.put("Authorization", NetConstant.APPCODE_SIT);
headers.put("appCode", NetConstant.APPCODE_VALUE_SIT);
} else if (NetManager.BASE_URL_UAT.equals(tag)) {
// uat环境
headers.put("X-Ca-Stage", "PRE");
headers.put("Authorization", NetConstant.APPCODE_UTA);
headers.put("appCode", NetConstant.APPCODE_VALUE_UTA);
} else if (NetManager.BASE_URL_DEV.equals(tag)) {
// dev环境
headers.put("X-Ca-Stage", "TEST");
headers.put("Authorization", NetConstant.APPCODE_DEV);
headers.put("appCode", NetConstant.APPCODE_VALUE_DEV);
} else {
// 正式环境
headers.put("X-Ca-Stage", "RELEASE");
headers.put("Authorization", NetConstant.APPCODE_RELEASE);
headers.put("appCode", NetConstant.APPCODE_VALUE_RELEASE);
}
// 渠道号
headers.put(ParameterConstant.CHANNEL, appInfoService.getChannelCode());
// 英文端新增-语言国际化
headers.put(ParameterConstant.ACCEPT_LANGUAGE, "zh");
Map<String, String> headerParameter = NetManager.getNetManager().getHeaderParameter();
if (headerParameter != null && headerParameter.size() > 0) {
headers.putAll(headerParameter);
}
Set<String> keys = headers.keySet();
for (String headerKey : keys) {
builder.addHeader(headerKey, TextUtils.isEmpty(headers.get(headerKey)) ? "" : headers.get(headerKey))
.build();
}
return chain.proceed(builder.build());
}
}
\ No newline at end of file
... ...
package com.wd.capability.network.interceptor;
import java.io.IOException;
import android.content.Context;
import com.wd.capability.network.NetManager;
import com.wd.capability.network.NetworkUtils;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
/**
* @author wondertek
* @date 2021/3/5
* 无网络状态下智能读取缓存的拦截器
*/
public class CacheInterceptor implements Interceptor {
private Context context;
public CacheInterceptor(Context context) {
this.context = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (NetworkUtils.isNetAvailable()) {
Response response = chain.proceed(request);
// read from cache for 60 s
int maxAge = 10;
return response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
// 读取缓存信息
request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
Response response = chain.proceed(request);
// set cache times is 3 days
long maxStale = NetManager.getNetManager().builder.getCacheTime();
return response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
}
}
... ...
package com.wd.capability.network.interceptor;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
import android.text.TextUtils;
import io.reactivex.annotations.NonNull;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
/**
* @author wondertek
* @date 2021/3/5
* 网络请求拦截器
*/
public class CommonParamInterceptor implements Interceptor {
private static Map<String, String> commonParams;
public synchronized static void setCommonParam(Map<String, String> commonParams) {
if (commonParams != null) {
if (CommonParamInterceptor.commonParams != null) {
CommonParamInterceptor.commonParams.clear();
} else {
CommonParamInterceptor.commonParams = new HashMap<>(16);
}
for (String paramKey : commonParams.keySet()) {
CommonParamInterceptor.commonParams.put(paramKey, commonParams.get(paramKey));
}
}
}
public synchronized static void updateOrInsertCommonParam(@NonNull String paramKey, @NonNull String paramValue) {
if (commonParams == null) {
commonParams = new HashMap<>(16);
}
commonParams.put(paramKey, paramValue);
}
@Override
public synchronized Response intercept(Chain chain) throws IOException {
Request request = rebuildRequest(chain.request());
Response response = chain.proceed(request);
// 输出返回结果
BufferedReader reader = null;
Reader jsonReader = null;
try {
Charset charset;
charset = Charset.forName("UTF-8");
ResponseBody responseBody = response.peekBody(Long.MAX_VALUE);
jsonReader = new InputStreamReader(responseBody.byteStream(), charset);
reader = new BufferedReader(jsonReader);
StringBuilder sbJson = new StringBuilder();
String line = reader.readLine();
do {
sbJson.append(line);
line = reader.readLine();
} while (line != null);
} catch (Exception e) {
e.printStackTrace();
} finally {
reader.close();
jsonReader.close();
}
return response;
}
public static byte[] toByteArray(RequestBody body) throws IOException {
Buffer buffer = new Buffer();
body.writeTo(buffer);
InputStream inputStream = buffer.inputStream();
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] bufferWrite = new byte[4096];
int n;
while (-1 != (n = inputStream.read(bufferWrite))) {
output.write(bufferWrite, 0, n);
}
return output.toByteArray();
}
private Request rebuildRequest(Request request) throws IOException {
Request newRequest;
if ("POST".equals(request.method())) {
newRequest = rebuildPostRequest(request);
} else if ("GET".equals(request.method())) {
newRequest = rebuildGetRequest(request);
} else {
newRequest = request;
}
return newRequest;
}
/**
* 对post请求添加统一参数
*/
private Request rebuildPostRequest(Request request) {
// if (commonParams == null || commonParams.size() == 0) {
// return request;
// }
Map<String, String> signParams = new HashMap<>(16);
RequestBody originalRequestBody = request.body();
assert originalRequestBody != null;
RequestBody newRequestBody;
if (originalRequestBody instanceof FormBody) {
FormBody.Builder builder = new FormBody.Builder();
FormBody requestBody = (FormBody) request.body();
int fieldSize = requestBody == null ? 0 : requestBody.size();
for (int i = 0; i < fieldSize; i++) {
builder.add(requestBody.name(i), requestBody.value(i));
signParams.put(requestBody.name(i), requestBody.value(i));
}
if (commonParams != null && commonParams.size() > 0) {
signParams.putAll(commonParams);
for (String paramKey : commonParams.keySet()) {
builder.add(paramKey, commonParams.get(paramKey));
}
}
// ToDo 此处可对参数做签名处理 signParams
/**
* String sign = SignUtil.sign(signParams);
* builder.add("sign", sign);
*/
newRequestBody = builder.build();
} else if (originalRequestBody instanceof MultipartBody) {
MultipartBody requestBody = (MultipartBody) request.body();
MultipartBody.Builder multipartBodybuilder = new MultipartBody.Builder();
if (requestBody != null) {
for (int i = 0; i < requestBody.size(); i++) {
MultipartBody.Part part = requestBody.part(i);
multipartBodybuilder.addPart(part);
MediaType mediaType = part.body().contentType();
if (mediaType == null) {
String normalParamKey;
String normalParamValue;
try {
normalParamValue = getParamContent(requestBody.part(i).body());
Headers headers = part.headers();
if (!TextUtils.isEmpty(normalParamValue) && headers != null) {
for (String name : headers.names()) {
String headerContent = headers.get(name);
if (!TextUtils.isEmpty(headerContent)) {
String[] normalParamKeyContainer = headerContent.split("name=\"");
if (normalParamKeyContainer.length == 2) {
normalParamKey = normalParamKeyContainer[1].split("\"")[0];
signParams.put(normalParamKey, normalParamValue);
break;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
if (commonParams != null && commonParams.size() > 0) {
signParams.putAll(commonParams);
for (String paramKey : commonParams.keySet()) {
// 两种方式添加公共参数
// method 1
multipartBodybuilder.addFormDataPart(paramKey, commonParams.get(paramKey));
// method 2
// MultipartBody.Part part = MultipartBody.Part.createFormData(paramKey,
// commonParams.get(paramKey));
// multipartBodybuilder.addPart(part);
}
}
// ToDo 此处可对参数做签名处理 signParams
/**
* String sign = SignUtil.sign(signParams);
* multipartBodybuilder.addFormDataPart("sign", sign);
*/
newRequestBody = multipartBodybuilder.build();
} else {
try {
JSONObject jsonObject;
if (originalRequestBody.contentLength() == 0) {
jsonObject = new JSONObject();
} else {
jsonObject = new JSONObject(getParamContent(originalRequestBody));
}
if (commonParams != null && commonParams.size() > 0) {
for (String commonParamKey : commonParams.keySet()) {
jsonObject.put(commonParamKey, commonParams.get(commonParamKey));
}
}
// ToDo 此处可对参数做签名处理
/**
* String sign = SignUtil.sign(signParams);
* jsonObject.put("sign", sign);
*/
newRequestBody = RequestBody.Companion.create(jsonObject.toString(), originalRequestBody.contentType());
} catch (Exception e) {
newRequestBody = originalRequestBody;
e.printStackTrace();
}
}
return request.newBuilder().method(request.method(), newRequestBody).build();
}
/**
* 获取常规post请求参数
*/
private String getParamContent(RequestBody body) throws IOException {
Buffer buffer = new Buffer();
body.writeTo(buffer);
return buffer.readUtf8();
}
/**
* 对get请求做统一参数处理
*/
private Request rebuildGetRequest(Request request) {
if (commonParams == null || commonParams.size() == 0) {
return request;
}
String url = request.url().toString();
int separatorIndex = url.lastIndexOf("?");
StringBuilder sb = new StringBuilder(url);
if (separatorIndex == -1) {
sb.append("?");
}
for (String commonParamKey : commonParams.keySet()) {
sb.append("&").append(commonParamKey).append("=").append(commonParams.get(commonParamKey));
}
Request.Builder requestBuilder = request.newBuilder();
return requestBuilder.url(sb.toString()).build();
}
}
\ No newline at end of file
... ...
package com.wd.capability.network.interceptor;
import java.io.IOException;
import com.wd.base.log.Logger;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
/**
* @author qts
*/
public class LoggingInterceptor implements Interceptor {
public static final String LOG_TAG = "LoggingInterceptor";
@Override
public Response intercept(Chain chain) throws IOException {
// Chain 里包含了request和response
Request request = chain.request();
long t1 = System.nanoTime();
String format = String.format("发送请求:[%s] %n---headers---%n%s", request.url(), request.headers());
Logger.t(LOG_TAG).d(format);
Response response = chain.proceed(request);
long t2 = System.nanoTime();
ResponseBody responseBody = response.peekBody(1024 * 1024);
String format1 = String.format("接收响应:[%s] %n---返回data---%s 耗时:%.1fms", response.request().url(),
responseBody.string(), (t2 - t1) / 1e6d);
Logger.t(LOG_TAG).d(format1);
return response;
}
}
\ No newline at end of file
... ...
package com.wd.capability.network.interceptor;
import java.io.IOException;
import java.util.List;
import com.wd.base.log.Logger;
import com.wd.capability.network.NetManager;
import io.reactivex.annotations.NonNull;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
/**
* 多域名拦截
* 通过header参数urlname 判断是否走统一域名
* 如果
*/
public class MultiDomainInterceptor implements Interceptor {
@NonNull
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
// 获取原始的originalRequest
Request originalRequest = chain.request();
// 获取老的url
HttpUrl oldUrl = originalRequest.url();
// 获取originalRequest的创建者builder
Request.Builder builder = originalRequest.newBuilder();
// 获取头信息的集合如:manage,mdffx
List<String> urlnameList = originalRequest.headers("urlname");
if (urlnameList != null && urlnameList.size() > 0) {
// 删除原有配置中的值,就是namesAndValues集合里的值
builder.removeHeader("urlname");
// 获取头信息中配置的value,如:manage或者mdffx
String urlname = urlnameList.get(0);
HttpUrl baseURL = null;
baseURL = HttpUrl.parse(urlname);
// 重建新的HttpUrl,需要重新设置的url部分
HttpUrl newHttpUrl = oldUrl.newBuilder()
.scheme(baseURL.scheme())// http协议如:http或者https
.host(baseURL.host())// 主机地址
.port(baseURL.port())// 端口
.build();
Logger.t("MultiDomainInterceptor").d(baseURL.scheme() + "//" + baseURL.host() + "//" + baseURL.port());
// 获取处理后的新newRequest
Request newRequest = builder.url(newHttpUrl).build();
return chain.proceed(newRequest);
} else {
String baseUrl = "";
String tag = NetManager.getUrlTag();
if (NetManager.BASE_URL_SIT.equals(tag)) {
baseUrl = NetManager.baseUrlSit;
} else if (NetManager.BASE_URL_UAT.equals(tag)) {
baseUrl = NetManager.baseUrlUat;
} else if (NetManager.BASE_URL_DEV.equals(tag)) {
baseUrl = NetManager.baseUrlDev;
} else {
baseUrl = NetManager.baseUrlRel;
}
HttpUrl baseURL = HttpUrl.parse(baseUrl);
// 重建新的HttpUrl,需要重新设置的url部分
HttpUrl newHttpUrl = oldUrl.newBuilder()
.scheme(baseURL.scheme())// http协议如:http或者https
.host(baseURL.host())// 主机地址
.port(baseURL.port())// 端口
.build();
Logger.t("MultiDomainInterceptor").d(baseURL.scheme() + "//" + baseURL.host() + "//" + baseURL.port());
// 获取处理后的新newRequest
Request newRequest = builder.url(newHttpUrl).build();
return chain.proceed(newRequest);
}
}
}
... ...
package com.wd.capability.network.interceptor;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
import android.content.Context;
import okhttp3.Interceptor;
import okhttp3.Response;
/**
* 描述:
*
* @author : lvjinhui
* @since: 2022/10/19
*/
public class NetCacheInterceptor implements Interceptor {
private Context context;
public NetCacheInterceptor(Context context) {
this.context = context;
}
@Override
public @NotNull Response intercept(@NotNull Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// read from cache for 60 s
int maxAge = 10;
return response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
}
}
... ...
package com.wd.capability.network.interceptor;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import android.text.TextUtils;
import com.wd.base.log.Logger;
import com.wd.capability.network.constant.ParameterConstant;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
/** 灾备地址切换 */
public class RetryCdnInterceptor implements Interceptor {
private static final String TAG = "Interceptor";
private int maxRetry;// 最大重试次数
private int retryNum = 0;// 假如设置为3次重试的话,则最大可能请求4次(默认1次+3次重试)
private int CONNECT_RETRY_TIMES = 2;
private String SERVER_URL2;
private int SERVER_URL2_PORT;
public RetryCdnInterceptor() {
Logger.t(TAG).d("构造函数" + retryNum);
maxRetry = CONNECT_RETRY_TIMES;
}
@Override
public Response intercept(Chain chain) throws IOException {
return proceMark(chain, chain.request());
}
private Response proceMark(Chain chain, Request mrequest) {
Request request;
if (mrequest == null) {
request = chain.request();
} else {
request = mrequest;
}
Response response = null;
int responseCode = 0;
String msg = "";
int code = 0;
try {
response = chain.proceed(request);
Logger.t(TAG)
.d("intercept:" + response.isSuccessful() + "//" + response.message() + "//" + response.code() + "//"
+ retryNum);
if (!response.isSuccessful() && (response.code() >= 400 && response.code() < 600)) {
if (TextUtils.equals(request.url().host(), SERVER_URL2) && request.url().port() == SERVER_URL2_PORT) {
// todo 备用地址重试
while (!response.isSuccessful() && (response.code() > 400 && response.code() < 600)
&& retryNum < maxRetry) {
Logger.t(TAG).d("备用地址404 重试" + retryNum);
retryNum++;
response = chain.proceed(request);
}
} else {
Request.Builder builder = request.newBuilder();
// ALog.e( request.method());
HttpUrl oldHttpUrl = request.url();
HttpUrl newFullUrl = oldHttpUrl.newBuilder()
.scheme(oldHttpUrl.scheme())
.host(SERVER_URL2)
.port(SERVER_URL2_PORT)
.build();
Logger.t(TAG).d("RetryInterceptor: " + "主地址404异常 调用备用地址" + newFullUrl.host());
// response= chain.proceed(builder.url(newFullUrl).build());
return proceMark(chain, builder.url(newFullUrl).build());
}
responseCode = response.code();
msg = response.message();
}
} catch (SocketTimeoutException timeoutException) {
Logger.t(TAG).d("SocketTimeoutException" + request.url() + "//" + timeoutException.toString());
msg = timeoutException.toString();
code = 408;
} catch (ConnectException connectException) {
msg = connectException.toString();
Logger.t(TAG).d("ConnectException" + request.url() + "//" + connectException.toString());
} catch (IllegalArgumentException argumentException) {
msg = argumentException.toString();
Logger.t(TAG).d("IllegalArgumentException" + request.url() + "//" + argumentException.toString());
} catch (Exception error) {
msg = error.toString();
Logger.t(TAG).d("ExceptionInterceptor" + request.url() + "//" + error.toString());
}
Logger.t(TAG).d("接口状态重试 : " + retryNum);
if (retryNum >= maxRetry) {
Response.Builder responseBuilder = new Response.Builder().code(responseCode)
.message(msg)
.request(chain.request())
.protocol(Protocol.HTTP_1_0)
.addHeader("content-type", ParameterConstant.HEADER_JSON_TYPE);
// String responseString = """{"error":This error is generated by ExceptionInterceptor
// [${status.second}]}""";
Logger.t(TAG).d("结束重试 : " + retryNum);
retryNum = 0;
String responseString = "{}";
responseBuilder
.body(ResponseBody.create(MediaType.parse(ParameterConstant.HEADER_JSON_TYPE), responseString));// 将数据设置到body中
return responseBuilder.build();// builder模式构建response
}
if (code == 408) {
// todo 是否是备用地址
Request request2 = chain.request();
Logger.t(TAG).d("超时408::::" + request2.url().port());
if (TextUtils.equals(request.url().host(), SERVER_URL2) && request.url().port() == SERVER_URL2_PORT) {
retryNum++;
Logger.t(TAG)
.d("RetryInterceptor: " + "主地址超时异常 调用备用地址超时 " + request.url().host() + ":"
+ request.url().port());
Request.Builder builder = request.newBuilder();
// ALog.e( request.method());
HttpUrl oldHttpUrl = request.url();
HttpUrl newFullUrl = oldHttpUrl.newBuilder()
.scheme(oldHttpUrl.scheme())
.host(SERVER_URL2)
.port(SERVER_URL2_PORT)
.build();
return proceMark(chain, builder.url(newFullUrl).build());
} else {
Request.Builder builder = request.newBuilder();
// ALog.e( request.method());
HttpUrl oldHttpUrl = request.url();
HttpUrl newFullUrl = oldHttpUrl.newBuilder()
.scheme(oldHttpUrl.scheme())
.host(SERVER_URL2)
.port(SERVER_URL2_PORT)
.build();
Logger.t(TAG).d("RetryInterceptor: " + "主地址超时异常 调用备用地址" + newFullUrl.host());
return proceMark(chain, builder.url(newFullUrl).build());
}
}
retryNum = 0;
return response;
}
}
\ No newline at end of file
... ...
package com.wd.capability.network.interceptor;
import java.io.IOException;
import java.util.HashMap;
import org.jetbrains.annotations.NotNull;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import com.wd.base.log.Logger;
import com.wd.capability.network.RetrofitClient;
import com.wd.capability.network.api.IRefreshToken;
import com.wd.capability.network.bean.NetworkEventConstants;
import com.wd.capability.network.bean.TokenBean;
import com.wd.capability.network.constant.ParameterConstant;
import com.wd.capability.network.response.BaseResponse;
import com.wd.foundation.wdinterface.app.IAppInfoService;
import com.wd.foundation.wdkitcore.livedata.LiveDataBus;
import com.wd.foundation.wdkitcore.router.ArouterServiceManager;
import com.wd.foundation.wdkitcore.tools.JsonUtils;
import com.wd.foundation.wdkitcore.tools.SpUtils;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import retrofit2.Call;
/**
* 描述:jwtToken 失效
*
* @author : lvjinhui
* @since: 2022/7/18
*/
public class TokenInterceptor implements Interceptor {
/**
* 临时token
*/
private static final int TOKEN_ERROR = 403;
/**
* 强制下线、封禁、清空登录信息还要跳转登录页面
*/
private static final int TOKEN_LOSE = 406;
/**
* refreshToken 失效
*/
private static final int REFRESH_TOKEN_ERROR = 377;
// 流量过大
public static final int FLOW_TOOBIG = 429;
private Context mContext;
// 是否流量超标
private boolean is_flow_big = false;
public TokenInterceptor(Context context) {
mContext = context;
}
@Override
public @NotNull Response intercept(@NotNull Chain chain) throws IOException {
Request originalRequest = chain.request();
Response response = chain.proceed(originalRequest);
try {
int requestCode = response.code();
// 流量超标
if (requestCode == FLOW_TOOBIG) {
handler.sendEmptyMessageDelayed(1, 500);
}
if (requestCode == TOKEN_LOSE) {
SpUtils.saveHttp406(true);
}
if (requestCode == TOKEN_ERROR || requestCode == TOKEN_LOSE) {
String newToken = getNewToken(requestCode);
// 使用新的Token,创建新的请求
Request newRequest = chain.request()
.newBuilder()
.header(ParameterConstant.RMRB_X_TOKEN, newToken)
.header(ParameterConstant.COOKIE, "RMRB-X-TOKEN=" + newToken)
.build();
// 重新请求
return chain.proceed(newRequest);
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
is_flow_big = true;
LiveDataBus.getInstance().with(NetworkEventConstants.FLOW_TOO_LARGE).postValue(true);
}
};
/**
* 同步请求方式,根据RefreshToken获取最新的Token
*
* @return
*/
private synchronized String getNewToken(int code) throws IOException {
// 通过一个特定的接口获取新的token,此处要用到同步的retrofit请求
String newToken = "";
String paramsRefresh = "";
IAppInfoService appInfoService = ArouterServiceManager.provide(IAppInfoService.class);
String deviceId = appInfoService == null ? "" : appInfoService.getDeviceId();
if (!TextUtils.isEmpty(SpUtils.getRefreshToken())) {
paramsRefresh = SpUtils.getRefreshToken();
}
IRefreshToken apiService = RetrofitClient.getInstance().create(IRefreshToken.class);
HashMap<String, Object> map = new HashMap<>();
map.put(ParameterConstant.REFRESH_TOKEN, paramsRefresh);
map.put(ParameterConstant.DEVICEID, deviceId);
Call<BaseResponse<TokenBean>> call = apiService.getJwtToken(SpUtils.getUserToken(), getBody(map));
BaseResponse<TokenBean> responseBean = call.execute().body();
if (responseBean != null) {
if (REFRESH_TOKEN_ERROR == responseBean.getCode()) {
SpUtils.saveHttp377(true);
LiveDataBus.getInstance().with(NetworkEventConstants.FORCE_USER_LOGIN_OUT).postValue(true);
} else if (0 == responseBean.getCode()) {
TokenBean tokenBean = responseBean.getData();
if (tokenBean != null) {
// 获取新的token成功
newToken = tokenBean.getJwtToken();
SpUtils.saveUserToken(newToken);
String refreshToken = tokenBean.getRefreshToken();
SpUtils.saveRefreshToken(refreshToken);
}
}
}
return newToken;
}
private RequestBody getBody(HashMap<String, Object> map) {
String requestJson = JsonUtils.convertObjectToJson(map);
Logger.t(LoggingInterceptor.LOG_TAG).d("---request data---" + requestJson);
RequestBody requestBody = RequestBody.create(MediaType.parse(ParameterConstant.HEADER_JSON_TYPE), requestJson);
return requestBody;
}
}
... ...
package com.wd.capability.network.onekeylogin;
import com.wd.capability.network.bean.FetchAccessTokenBean;
import com.wd.capability.network.response.BaseResponse;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
/**
* 描述:使用refreshToken 请求 jwtToken
*
* @author : lvjinhui
* @since: 2022/7/15
*/
public interface IOneKeyLogin {
/**
* 获取应用授权Token
*/
@POST("api/rmrb-user-center/auth/zh/c/fetchAccessToken")
Call<BaseResponse<FetchAccessTokenBean>> fetchAccessToken(@Body RequestBody body);
}
... ...
package com.wd.capability.network.refreshtoken;
import com.wd.capability.network.bean.TokenBean;
/**
* 描述:提供给js 刷新token
*
* @author : lvjinhui
* @since: 2022/12/7
*/
public interface IRefreshTokenForJsCallBack {
/**
* 成功
*
* @param tokenBean
*/
void onSuccess(TokenBean tokenBean);
/**
* 提供给js 刷新token
*
* @param code
* @param message
*/
void onFailed(int code, String message);
}
... ...
package com.wd.capability.network.response;
import com.wd.capability.network.bean.MetaBean;
/**
* @author wondertek
* @date 2021/3/5
* 该类仅供参考,实际业务返回的固定字段, 根据需求来定义,
*/
public class BaseResponse<T> {
private String code;
private String message;
private T data;
private long timestamp;
private String transNo;
private boolean success;
private MetaBean meta;
public int getCode() {
try {
return Integer.parseInt(code);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getTransNo() {
return transNo;
}
public void setTransNo(String transNo) {
this.transNo = transNo;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public MetaBean getMeta() {
return meta;
}
public void setMeta(MetaBean meta) {
this.meta = meta;
}
public String getMd5() {
if (meta != null) {
return meta.getMd5();
}
return "";
}
}
... ...
package com.wd.capability.network.response;
import java.net.ConnectException;
import java.net.UnknownHostException;
import org.json.JSONException;
import android.net.ParseException;
import com.google.gson.JsonParseException;
import com.wd.capability.network.R;
import com.wd.foundation.wdkitcore.tools.ResUtils;
import retrofit2.HttpException;
/**
* @author wondertek
* @date 2021/3/6
*/
public class ExceptionHandle {
/**
* 对应HTTP的状态码
*/
private static final int UNAUTHORIZED = 401;
private static final int FORBIDDEN = 403;
private static final int NOT_FOUND = 404;
private static final int REQUEST_TIMEOUT = 408;
private static final int INTERNAL_SERVER_ERROR = 500;
private static final int BAD_GATEWAY = 502;
private static final int SERVICE_UNAVAILABLE = 503;
private static final int GATEWAY_TIMEOUT = 504;
/**
* 二级页面错误提示
*/
public static final String NET_ERROR_TIPS_IN_PAGE = ResUtils.getString(R.string.tips_check_network);
/**
* 接口500 情况弹出这个
*/
public static final String NET_ERROR_500 = ResUtils.getString(R.string.default_get_content_failed);
public static ResponseException handleException(Throwable e) {
ResponseException ex;
if (e instanceof HttpException) {
HttpException httpException = (HttpException) e;
ex = new ResponseException(e, Error.HTTP_ERROR);
switch (httpException.code()) {
case INTERNAL_SERVER_ERROR:
ex.message = NET_ERROR_500;
break;
case UNAUTHORIZED:
case FORBIDDEN:
case NOT_FOUND:
case REQUEST_TIMEOUT:
case GATEWAY_TIMEOUT:
case BAD_GATEWAY:
case SERVICE_UNAVAILABLE:
default:
ex.message = NET_ERROR_TIPS_IN_PAGE;
break;
}
return ex;
} else if (e instanceof ServerException) {
ServerException resultException = (ServerException) e;
ex = new ResponseException(resultException, resultException.code);
ex.message = resultException.message;
return ex;
} else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) {
ex = new ResponseException(e, Error.PARSE_ERROR);
ex.message = "ParseException";
return ex;
} else if (e instanceof ConnectException) {
ex = new ResponseException(e, Error.NETWORK_ERROR);
ex.message = "ConnectException";
return ex;
} else if (e instanceof UnknownHostException) {
ex = new ResponseException(e, Error.NETWORK_ERROR);
ex.message = NET_ERROR_TIPS_IN_PAGE;
return ex;
} else {
ex = new ResponseException(e, Error.UNKNOWN);
ex.message = NET_ERROR_TIPS_IN_PAGE;
return ex;
}
}
/**
* 约定异常 这个具体规则需要与服务端或者领导商讨定义
*/
public static class Error {
/**
* 未知错误
*/
public static final int UNKNOWN = 1000;
/**
* 解析错误
*/
public static final int PARSE_ERROR = 1001;
/**
* 网络错误
*/
public static final int NETWORK_ERROR = 1002;
/**
* 协议出错
*/
public static final int HTTP_ERROR = 1003;
}
/**
* 服务器异常
*/
public class ServerException extends RuntimeException {
public int code;
public String message;
}
public static boolean showErrorTips(ResponseException exception) {
if (exception != null && NET_ERROR_TIPS_IN_PAGE.equals(exception.message)) {
return true;
}
return false;
}
}
... ...
package com.wd.capability.network.response;
/**
*
* @author wondertek
* @date 2021/3/6
*/
public class ResponseException extends Exception {
public int code;
public String message;
public ResponseException(Throwable throwable, int code) {
super(throwable);
this.code = code;
}
}
... ...
package com.wd.capability.network.utils;
/**
* 描述:对暗号,切换环境
*
* @author : lvjinhui
* @since: 2022/7/27
*/
public class HostUtil {
public static long serverTime = 0;
}
... ...
/**
* class name :JsonUtils
* class description:
* Copyright:BesTV. All Rights Reserved.
* creator:xu.chaokun
* create time:2013-8-16 上午11:20:27
*/
package com.wd.capability.network.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.internal.Primitives;
import com.google.gson.reflect.TypeToken;
/**
* @author qts
*/
class JsonUtils {
private static final String TAG = "JsonUtils";
private final static String SET_HEAD = "set";
// private static final String SDF = "yyyy-MM-dd HH:mm:ss";
private static Gson createGson() {
Gson gson = new GsonBuilder().create();
return gson;
}
private static String firstUpperCase(String arg) {
return Character.toUpperCase(arg.charAt(0)) + arg.substring(1);
}
public static void attributeCopy(JSONObject jsonObject, Object desc) {
Class descClass = desc.getClass();
Field[] descFields = descClass.getDeclaredFields();
if (null != descFields) {
for (Field field : descFields) {
String name = firstUpperCase(field.getName());
Object value = jsonObject.opt(name);
try {
if (null != value) {
Method setMethod = descClass.getDeclaredMethod(SET_HEAD + name, new Class[] {field.getType()});
setMethod.invoke(desc, value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static <T> T objFromJson(String json, Class<T> classOfT, String dateFormat) {
Gson gson = new GsonBuilder().setDateFormat(dateFormat).create();
Object ret = gson.fromJson(json, classOfT);
return Primitives.wrap(classOfT).cast(ret);
}
public static <T> T objFromJson(JSONObject json, Class<T> classOfT) {
return objFromJson(json.toString(), classOfT);
}
public static <T> T objFromJson(String json, Class<T> classOfT) {
Object ret = null;
Gson gson = createGson();
ret = gson.fromJson(json, classOfT);
return Primitives.wrap(classOfT).cast(ret);
}
public static Object objFromJson(JSONObject json, Type type) {
return objFromJson(json.toString(), type);
}
public static <T> String objToJsonArray(List<T> jsonArrayList) {
Gson gson = createGson();
JsonElement element = gson.toJsonTree(jsonArrayList, new TypeToken<List<T>>() {}.getType());
if (!element.isJsonArray()) {
throw new TypeNotPresentException("JsonArray", null);
}
JsonArray jsonArray = element.getAsJsonArray();
return jsonArray.toString();
}
public static Object objFromJson(String json, Type type) {
Object ret = null;
Gson gson = createGson();
ret = gson.fromJson(json, type);
return ret;
}
public static String objToJson(Object obj) {
Gson gson = createGson();
String ret = gson.toJson(obj);
return ret;
}
public static String getJsonString(JSONObject obj, String key, String defValue) {
String ret = defValue;
try {
ret = obj.getString(key);
} catch (Throwable e) {
e.printStackTrace();
}
return ret;
}
public static JSONObject getJsonObjectSafty(JSONObject src, String objStr) {
JSONObject ret = null;
try {
ret = src.getJSONObject(objStr);
} catch (Throwable e) {
e.printStackTrace();
}
return ret;
}
public static JSONArray getJsonArraySafty(JSONObject src, String objStr) {
JSONArray ret = null;
try {
ret = src.getJSONArray(objStr);
} catch (Throwable e) {
e.printStackTrace();
}
return ret;
}
public static int getJsonInt(JSONObject obj, String key, int defValue) {
int ret = defValue;
try {
ret = obj.getInt(key);
} catch (Throwable e) {
e.printStackTrace();
}
return ret;
}
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--全域异常场景-->
<!--网络出小差了,请检查网络后重试-->
<string name="tips_check_network">网络出小差了,请检查网络后重试!</string>
<!--内容获取失败,用于内容详情页(带重试按钮)-->
<string name="default_get_content_failed">内容获取失败,请稍后重试</string>
<string name="network_request_failed" formatted="false">网络请求失败,请稍后重试。错误码[%d] %s</string>
</resources>
\ No newline at end of file
... ...