atom
This commit is contained in:
1
common/.gitignore
vendored
Normal file
1
common/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
47
common/build.gradle
Normal file
47
common/build.gradle
Normal file
@@ -0,0 +1,47 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion app_android.compileSdkVersion
|
||||
buildToolsVersion app_android.buildToolsVersion
|
||||
defaultConfig {
|
||||
minSdkVersion app_android.minSdkVersion
|
||||
targetSdkVersion app_android.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
consumerProguardFiles 'consumer-rules.pro'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
|
||||
api 'com.squareup.retrofit2:converter-gson:2.3.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
|
||||
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
|
||||
//v1.5
|
||||
api 'io.reactivex.rxjava2:rxandroid:2.1.1'
|
||||
// Because RxAndroid releases are few and far between, it is recommended you also
|
||||
// explicitly depend on RxJava's latest version for bug fixes and new features.
|
||||
// (see https://github.com/ReactiveX/RxJava/releases for latest 2.x.x version)
|
||||
api 'io.reactivex.rxjava2:rxjava:2.2.12'
|
||||
|
||||
|
||||
api 'androidx.preference:preference:1.0.0'
|
||||
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
|
||||
// 因为每一个 “子Module”都依赖了 common,所有当我们在 common中依赖 arouter_api(柱状)
|
||||
// 就等于 全部都依赖了 arouter_api
|
||||
api project(":arouter_api")
|
||||
}
|
||||
0
common/consumer-rules.pro
Normal file
0
common/consumer-rules.pro
Normal file
21
common/proguard-rules.pro
vendored
Normal file
21
common/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# 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
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.xiangxue.common.network;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
||||
assertEquals("com.xiangxue.common.network.test", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
3
common/src/main/AndroidManifest.xml
Normal file
3
common/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.xiangxue.common" />
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.xiangxue.common;
|
||||
|
||||
import com.xiangxue.common.bean.PathBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 全局路径记录器(根据子模块分组)
|
||||
*
|
||||
* 5种方式通信 之一 全局map 已经废除了
|
||||
*/
|
||||
public class RecordPathManager {
|
||||
|
||||
// key:"order"组 value:order子模块下,对应所有的Activity路径信息
|
||||
private static Map<String, List<PathBean>> groupMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 将路径信息加入全局Map
|
||||
*
|
||||
* @param groupName 组名,如:"personal"
|
||||
* @param pathName 路劲名,如:"Personal_MainActivity"
|
||||
* @param clazz 类对象,如:Personal_MainActivity.class
|
||||
*/
|
||||
public static void joinGroup(String groupName, String pathName, Class<?> clazz) {
|
||||
List<PathBean> list = groupMap.get(groupName);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
list.add(new PathBean(pathName, clazz));
|
||||
groupMap.put(groupName, list);
|
||||
} else {
|
||||
groupMap.put(groupName, list);
|
||||
}
|
||||
groupMap.put(groupName, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据组名和路径名获取类对象,达到跳转目的
|
||||
*
|
||||
* @param groupName 组名
|
||||
* @param pathName 路径名
|
||||
* @return 跳转目标的class类对象
|
||||
*/
|
||||
public static Class<?> getTargetClass(String groupName, String pathName) {
|
||||
List<PathBean> list = groupMap.get(groupName);
|
||||
if (list == null) return null;
|
||||
for (PathBean path : list) {
|
||||
if (pathName.equalsIgnoreCase(path.getPath())) {
|
||||
return path.getClazz();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理、回收
|
||||
*/
|
||||
public static void recycleGroup() {
|
||||
groupMap.clear();
|
||||
groupMap = null;
|
||||
System.gc();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.xiangxue.common.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.xiangxue.common.utils.Cons;
|
||||
|
||||
/**
|
||||
* 项目父Activity
|
||||
*/
|
||||
public class BaseActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Log.e(Cons.TAG, "common/BaseActivity");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.xiangxue.common.base;
|
||||
|
||||
import android.app.Application;
|
||||
import android.util.Log;
|
||||
|
||||
import com.xiangxue.common.utils.Cons;
|
||||
|
||||
|
||||
/**
|
||||
* 项目父Application
|
||||
*/
|
||||
public class BaseApplication extends Application {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Log.e(Cons.TAG, "common/BaseApplication");
|
||||
}
|
||||
}
|
||||
37
common/src/main/java/com/xiangxue/common/bean/PathBean.java
Normal file
37
common/src/main/java/com/xiangxue/common/bean/PathBean.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.xiangxue.common.bean;
|
||||
|
||||
/**
|
||||
* 路径对象(公共基础库中,所有子模块都可以调用)
|
||||
* 如:
|
||||
* path : ”order/Order_MainActivity”
|
||||
* clazz : Order_MainActivity.class
|
||||
*/
|
||||
public class PathBean {
|
||||
|
||||
private String path;
|
||||
private Class clazz;
|
||||
|
||||
public PathBean() {
|
||||
}
|
||||
|
||||
public PathBean(String path, Class clazz) {
|
||||
this.path = path;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public Class getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public void setClazz(Class clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
}
|
||||
52
common/src/main/java/com/xiangxue/common/bean/Student.java
Normal file
52
common/src/main/java/com/xiangxue/common/bean/Student.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package com.xiangxue.common.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Student implements Serializable {
|
||||
|
||||
private String name = "";
|
||||
private String sex;
|
||||
private int age;
|
||||
|
||||
/*public Student() {
|
||||
}*/
|
||||
|
||||
public Student(String name, String sex, int age) {
|
||||
this.name = name;
|
||||
this.sex = sex;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setSex(String sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Student{" +
|
||||
"name='" + name + '\'' +
|
||||
", sex='" + sex + '\'' +
|
||||
", age=" + age +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.xiangxue.common.images;
|
||||
|
||||
/**
|
||||
* 图片加载管理器
|
||||
*/
|
||||
public class GlideManager {
|
||||
|
||||
// .....
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.xiangxue.common.network;
|
||||
|
||||
import com.xiangxue.common.network.base.NetworkApi;
|
||||
|
||||
import io.reactivex.functions.Function;
|
||||
import okhttp3.Interceptor;
|
||||
|
||||
public class DoupanNetworkApi extends NetworkApi {
|
||||
private static volatile DoupanNetworkApi sInstance;
|
||||
|
||||
public static DoupanNetworkApi getInstance() {
|
||||
if (sInstance == null) {
|
||||
synchronized (DoupanNetworkApi.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new DoupanNetworkApi();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Interceptor getInterceptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> Function<T, T> getAppErrorHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T getService(Class<T> service) {
|
||||
return getInstance().getRetrofit(service).create(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormal() {
|
||||
return "https://api.douban.com";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTest() {
|
||||
return "https://api.douban.com";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.xiangxue.common.network;
|
||||
|
||||
import com.xiangxue.common.network.base.NetworkApi;
|
||||
import com.xiangxue.common.network.beans.TecentBaseResponse;
|
||||
import com.xiangxue.common.network.errorhandler.ExceptionHandle;
|
||||
import com.xiangxue.common.network.utils.TecentUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import io.reactivex.functions.Function;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class TecentNetworkApi extends NetworkApi {
|
||||
private static volatile TecentNetworkApi sInstance;
|
||||
|
||||
public static TecentNetworkApi getInstance() {
|
||||
if (sInstance == null) {
|
||||
synchronized (TecentNetworkApi.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new TecentNetworkApi();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public static <T> T getService(Class<T> service) {
|
||||
return getInstance().getRetrofit(service).create(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Interceptor getInterceptor() {
|
||||
return new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
String timeStr = TecentUtil.getTimeStr();
|
||||
Request.Builder builder = chain.request().newBuilder();
|
||||
// builder.addHeader("Source", "source");
|
||||
// builder.addHeader("Authorization", TecentUtil.getAuthorization(timeStr));
|
||||
// builder.addHeader("Date", timeStr);
|
||||
return chain.proceed(builder.build());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected <T> Function<T, T> getAppErrorHandler() {
|
||||
return new Function<T, T>() {
|
||||
@Override
|
||||
public T apply(T response) throws Exception {
|
||||
//response中code码不会0 出现错误
|
||||
if (response instanceof TecentBaseResponse && ((TecentBaseResponse) response).success != 0) {
|
||||
ExceptionHandle.ServerException exception = new ExceptionHandle.ServerException();
|
||||
exception.code = ((TecentBaseResponse) response).success;
|
||||
exception.message = ((TecentBaseResponse) response).msg != null ? ((TecentBaseResponse) response).msg : "";
|
||||
throw exception;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormal() {
|
||||
return "http://139.186.151.48/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTest() {
|
||||
return "http://service-o5ikp40z-1255468759.ap-shanghai.apigateway.myqcloud.com/";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.xiangxue.common.network.base;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.functions.Function;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.CallAdapter;
|
||||
|
||||
public class CallAdapterFactory<R, W> implements CallAdapter<R, W> {
|
||||
|
||||
public static <R, W> CallAdapterFactory<R, W> create(@NonNull CallAdapter<R, W> mAdapter, @NonNull Function<W, W> mFunction) {
|
||||
return new CallAdapterFactory(mAdapter, mFunction);
|
||||
}
|
||||
|
||||
private CallAdapterFactory(@NonNull CallAdapter<R, W> mAdapter, @NonNull Function<W, W> mFunction) {
|
||||
this.mAdapter = mAdapter;
|
||||
this.mFunction = mFunction;
|
||||
}
|
||||
|
||||
private CallAdapter<R, W> mAdapter;
|
||||
|
||||
private Function<W, W> mFunction;
|
||||
|
||||
@Override
|
||||
public Type responseType() {
|
||||
return mAdapter.responseType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public W adapt(Call<R> call) {
|
||||
W adapt = mAdapter.adapt(call);
|
||||
try {
|
||||
return mFunction.apply(adapt);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return adapt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.xiangxue.common.network.base;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
/**
|
||||
* Created by Allen on 2017/7/20.
|
||||
* 保留所有版权,未经允许请不要分享到互联网和其他人
|
||||
*/
|
||||
public interface INetworkRequiredInfo {
|
||||
String getAppVersionName();
|
||||
String getAppVersionCode();
|
||||
boolean isDebug();
|
||||
Application getApplicationContext();
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.xiangxue.common.network.base;
|
||||
|
||||
import com.xiangxue.common.network.commoninterceptor.CommonRequestInterceptor;
|
||||
import com.xiangxue.common.network.commoninterceptor.CommonResponseInterceptor;
|
||||
import com.xiangxue.common.network.environment.EnvironmentActivity;
|
||||
import com.xiangxue.common.network.environment.IEnvironment;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import io.reactivex.functions.Function;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
|
||||
public abstract class NetworkApi implements IEnvironment {
|
||||
private static INetworkRequiredInfo iNetworkRequiredInfo;
|
||||
private static HashMap<String, Retrofit> retrofitHashMap = new HashMap<>();
|
||||
private String mBaseUrl;
|
||||
private OkHttpClient mOkHttpClient;
|
||||
private static boolean mIsFormal = true;
|
||||
|
||||
public NetworkApi() {
|
||||
if (!mIsFormal) {
|
||||
mBaseUrl = getTest();
|
||||
return;
|
||||
}
|
||||
mBaseUrl = getFormal();
|
||||
}
|
||||
|
||||
public static void init(INetworkRequiredInfo networkRequiredInfo) {
|
||||
iNetworkRequiredInfo = networkRequiredInfo;
|
||||
mIsFormal = EnvironmentActivity.isOfficialEnvironment(networkRequiredInfo.getApplicationContext());
|
||||
}
|
||||
|
||||
protected Retrofit getRetrofit(Class service) {
|
||||
if (retrofitHashMap.get(mBaseUrl + service.getName()) != null) {
|
||||
return retrofitHashMap.get(mBaseUrl + service.getName());
|
||||
}
|
||||
Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
|
||||
retrofitBuilder.baseUrl(mBaseUrl);
|
||||
retrofitBuilder.client(getOkHttpClient());
|
||||
retrofitBuilder.addConverterFactory(GsonConverterFactory.create());
|
||||
retrofitBuilder.addCallAdapterFactory(XiangxueRxJava2CallAdapterFactory.create(getAppErrorHandler()));
|
||||
Retrofit retrofit = retrofitBuilder.build();
|
||||
retrofitHashMap.put(mBaseUrl + service.getName(), retrofit);
|
||||
return retrofit;
|
||||
}
|
||||
|
||||
private OkHttpClient getOkHttpClient() {
|
||||
if(mOkHttpClient == null) {
|
||||
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
|
||||
if (getInterceptor() != null) {
|
||||
okHttpClientBuilder.addInterceptor(getInterceptor());
|
||||
}
|
||||
okHttpClientBuilder.addInterceptor(new CommonRequestInterceptor(iNetworkRequiredInfo));
|
||||
okHttpClientBuilder.addInterceptor(new CommonResponseInterceptor());
|
||||
if (iNetworkRequiredInfo != null &&(iNetworkRequiredInfo.isDebug())) {
|
||||
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
|
||||
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
okHttpClientBuilder.addInterceptor(httpLoggingInterceptor);
|
||||
}
|
||||
mOkHttpClient = okHttpClientBuilder.build();
|
||||
}
|
||||
return mOkHttpClient;
|
||||
}
|
||||
public static OkHttpClient getOkHttpClientt() {
|
||||
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
|
||||
okHttpClientBuilder.addInterceptor(new CommonRequestInterceptor(iNetworkRequiredInfo));
|
||||
okHttpClientBuilder.addInterceptor(new CommonResponseInterceptor());
|
||||
if (iNetworkRequiredInfo != null &&(iNetworkRequiredInfo.isDebug())) {
|
||||
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
|
||||
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
okHttpClientBuilder.addInterceptor(httpLoggingInterceptor);
|
||||
}else {
|
||||
|
||||
}
|
||||
return okHttpClientBuilder.build();
|
||||
}
|
||||
// public static void getTencentNewsChannels(){
|
||||
// Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
|
||||
// retrofitBuilder.baseUrl("http://139.186.151.48/");
|
||||
// retrofitBuilder.client(getOkHttpClientt());
|
||||
// retrofitBuilder.addConverterFactory(GsonConverterFactory.create());
|
||||
// retrofitBuilder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
|
||||
// Retrofit retrofit = retrofitBuilder.build();
|
||||
// NewsApiInterface newsApiInterface = retrofit.create(NewsApiInterface.class);
|
||||
// newsApiInterface.getNowVersion()
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe(new Observer<GetVesionResponseBean>() {
|
||||
// @Override
|
||||
// public void onSubscribe(@NonNull Disposable d) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onNext(@NonNull GetVesionResponseBean getVesionResponseBean) {
|
||||
// Log.e("TIAOSHI", new Gson().toJson(getVesionResponseBean));
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onError(@NonNull Throwable e) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onComplete() {
|
||||
//
|
||||
// }
|
||||
// });
|
||||
//
|
||||
//// nowVersion.enqueue(new Callback<GetVesionResponseBean>() {
|
||||
//// @Override
|
||||
//// public void onResponse(Call<GetVesionResponseBean> call, Response<GetVesionResponseBean> response) {
|
||||
//// Log.e("TIAOSHI", new Gson().toJson(response.body()));
|
||||
//// }
|
||||
////
|
||||
//// @Override
|
||||
//// public void onFailure(Call<GetVesionResponseBean> call, Throwable t) {
|
||||
//// Log.e("TIAOSHI", t.getMessage());
|
||||
//// }
|
||||
//// });
|
||||
// }
|
||||
|
||||
protected abstract Interceptor getInterceptor();
|
||||
|
||||
protected abstract <T> Function<T, T> getAppErrorHandler();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.xiangxue.common.network.base;
|
||||
|
||||
|
||||
import com.xiangxue.common.network.errorhandler.HttpErrorHandler;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.functions.Function;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import retrofit2.CallAdapter;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
||||
|
||||
public class XiangxueRxJava2CallAdapterFactory extends CallAdapter.Factory {
|
||||
Function function;
|
||||
private CallAdapter.Factory mFactory;
|
||||
|
||||
public static XiangxueRxJava2CallAdapterFactory create(Function function) {
|
||||
return new XiangxueRxJava2CallAdapterFactory(function);
|
||||
}
|
||||
|
||||
private XiangxueRxJava2CallAdapterFactory(Function function) {
|
||||
this.function = function;
|
||||
mFactory = RxJava2CallAdapterFactory.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallAdapter<?, ?> get(@NonNull Type returnType, @NonNull Annotation[] annotations, @NonNull Retrofit retrofit) {
|
||||
final CallAdapter<?, ?> callAdapter = mFactory.get(returnType, annotations, retrofit);
|
||||
Class<?> rawType = getRawType(returnType);
|
||||
if(callAdapter != null) {
|
||||
//生产不同的CallAdapter
|
||||
if (rawType == Observable.class) {
|
||||
return CallAdapterFactory.create((CallAdapter<Observable<?>, Observable<?>>) callAdapter, new Function<Observable<?>, Observable<?>>() {
|
||||
@Override
|
||||
public Observable<?> apply(@NonNull Observable<?> f) throws Exception {
|
||||
Observable<?> observable = f.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
|
||||
if (function != null) {
|
||||
return observable.map(function).onErrorResumeNext(new HttpErrorHandler());
|
||||
} else {
|
||||
return observable.onErrorResumeNext(new HttpErrorHandler());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (rawType == Flowable.class) {
|
||||
return CallAdapterFactory.create((CallAdapter<Flowable<?>, Flowable<?>>) callAdapter, new Function<Flowable<?>, Flowable<?>>() {
|
||||
@Override
|
||||
public Flowable<?> apply(@NonNull Flowable<?> f) throws Exception {
|
||||
Flowable<?> observable = f.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
|
||||
if (function != null) {
|
||||
return observable.map(function).onErrorResumeNext(new HttpErrorHandler());
|
||||
} else {
|
||||
return observable.onErrorResumeNext(new HttpErrorHandler());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
//省略...
|
||||
return callAdapter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.xiangxue.common.network.beans;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Created by Allen on 2017/7/20.
|
||||
* 保留所有版权,未经允许请不要分享到互联网和其他人
|
||||
*/
|
||||
public class TecentBaseResponse {
|
||||
@SerializedName("success")
|
||||
@Expose
|
||||
public Integer success;
|
||||
@SerializedName("msg")
|
||||
@Expose
|
||||
public String msg;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.xiangxue.common.network.commoninterceptor;
|
||||
|
||||
import com.xiangxue.common.network.base.INetworkRequiredInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class CommonRequestInterceptor implements Interceptor {
|
||||
private INetworkRequiredInfo requiredInfo;
|
||||
public CommonRequestInterceptor(INetworkRequiredInfo requiredInfo){
|
||||
this.requiredInfo = requiredInfo;
|
||||
}
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
Request.Builder builder = chain.request().newBuilder();
|
||||
builder.addHeader("os", "android");
|
||||
builder.addHeader("appVersion",this.requiredInfo.getAppVersionCode());
|
||||
return chain.proceed(builder.build());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.xiangxue.common.network.commoninterceptor;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class CommonResponseInterceptor implements Interceptor {
|
||||
private static final String TAG = "ResponseInterceptor";
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
long requestTime = System.currentTimeMillis();
|
||||
Response response = chain.proceed(chain.request());
|
||||
Log.d(TAG, "requestTime="+ (System.currentTimeMillis() - requestTime));
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.xiangxue.common.network.environment;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.xiangxue.common.R;
|
||||
|
||||
|
||||
public class EnvironmentActivity extends AppCompatActivity {
|
||||
|
||||
public static final String NETWORK_ENVIRONMENT_PREF_KEY = "network_environment_type";
|
||||
private static String sCurrentNetworkEnvironment = "";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_environment);
|
||||
//setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.content, new MyPreferenceFragment())
|
||||
.commit();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
sCurrentNetworkEnvironment = prefs.getString(EnvironmentActivity.NETWORK_ENVIRONMENT_PREF_KEY, "1");
|
||||
}
|
||||
|
||||
public static class MyPreferenceFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener {
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.environment_preference);
|
||||
findPreference(NETWORK_ENVIRONMENT_PREF_KEY).setOnPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
if (!sCurrentNetworkEnvironment.equalsIgnoreCase(String.valueOf(o))) {
|
||||
Toast.makeText(getContext(), "您已经更改了网络环境,再您退出当前页面的时候APP将会重启切换环境!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
String newValue = prefs.getString(EnvironmentActivity.NETWORK_ENVIRONMENT_PREF_KEY, "1");
|
||||
if (!sCurrentNetworkEnvironment.equalsIgnoreCase(newValue)) {
|
||||
android.os.Process.killProcess(android.os.Process.myPid());
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isOfficialEnvironment(Application application) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(application);
|
||||
String environment = prefs.getString(EnvironmentActivity.NETWORK_ENVIRONMENT_PREF_KEY, "1");
|
||||
return "1".equalsIgnoreCase(environment);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.xiangxue.common.network.environment;
|
||||
|
||||
public interface IEnvironment {
|
||||
String getFormal();
|
||||
|
||||
String getTest();
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package com.xiangxue.common.network.errorhandler;
|
||||
|
||||
import android.net.ParseException;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import org.apache.http.conn.ConnectTimeoutException;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.net.ConnectException;
|
||||
|
||||
import retrofit2.HttpException;
|
||||
|
||||
/**
|
||||
* Created by Allen on 2017/7/20.
|
||||
* 保留所有版权,未经允许请不要分享到互联网和其他人
|
||||
*/
|
||||
public class ExceptionHandle {
|
||||
|
||||
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 ResponeThrowable handleException(Throwable e) {
|
||||
ResponeThrowable ex;
|
||||
if (e instanceof HttpException) {
|
||||
HttpException httpException = (HttpException) e;
|
||||
ex = new ResponeThrowable(e, ERROR.HTTP_ERROR);
|
||||
switch (httpException.code()) {
|
||||
case UNAUTHORIZED:
|
||||
case FORBIDDEN:
|
||||
case NOT_FOUND:
|
||||
case REQUEST_TIMEOUT:
|
||||
case GATEWAY_TIMEOUT:
|
||||
case INTERNAL_SERVER_ERROR:
|
||||
case BAD_GATEWAY:
|
||||
case SERVICE_UNAVAILABLE:
|
||||
default:
|
||||
ex.message = "网络错误";
|
||||
break;
|
||||
}
|
||||
return ex;
|
||||
} else if (e instanceof ServerException) {
|
||||
ServerException resultException = (ServerException) e;
|
||||
ex = new ResponeThrowable(resultException, resultException.code);
|
||||
ex.message = resultException.message;
|
||||
return ex;
|
||||
} else if (e instanceof JsonParseException
|
||||
|| e instanceof JSONException
|
||||
|| e instanceof ParseException) {
|
||||
ex = new ResponeThrowable(e, ERROR.PARSE_ERROR);
|
||||
ex.message = "解析错误";
|
||||
return ex;
|
||||
} else if (e instanceof ConnectException) {
|
||||
ex = new ResponeThrowable(e, ERROR.NETWORD_ERROR);
|
||||
ex.message = "连接失败";
|
||||
return ex;
|
||||
} else if (e instanceof javax.net.ssl.SSLHandshakeException) {
|
||||
ex = new ResponeThrowable(e, ERROR.SSL_ERROR);
|
||||
ex.message = "证书验证失败";
|
||||
return ex;
|
||||
} else if (e instanceof ConnectTimeoutException){
|
||||
ex = new ResponeThrowable(e, ERROR.TIMEOUT_ERROR);
|
||||
ex.message = "连接超时";
|
||||
return ex;
|
||||
} else if (e instanceof java.net.SocketTimeoutException) {
|
||||
ex = new ResponeThrowable(e, ERROR.TIMEOUT_ERROR);
|
||||
ex.message = "连接超时";
|
||||
return ex;
|
||||
}
|
||||
else {
|
||||
ex = new ResponeThrowable(e, ERROR.UNKNOWN);
|
||||
ex.message = "未知错误";
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 约定异常
|
||||
*/
|
||||
public class ERROR {
|
||||
/**
|
||||
* 未知错误
|
||||
*/
|
||||
public static final int UNKNOWN = 1000;
|
||||
/**
|
||||
* 解析错误
|
||||
*/
|
||||
public static final int PARSE_ERROR = 1001;
|
||||
/**
|
||||
* 网络错误
|
||||
*/
|
||||
public static final int NETWORD_ERROR = 1002;
|
||||
/**
|
||||
* 协议出错
|
||||
*/
|
||||
public static final int HTTP_ERROR = 1003;
|
||||
|
||||
/**
|
||||
* 证书出错
|
||||
*/
|
||||
public static final int SSL_ERROR = 1005;
|
||||
|
||||
/**
|
||||
* 连接超时
|
||||
*/
|
||||
public static final int TIMEOUT_ERROR = 1006;
|
||||
}
|
||||
|
||||
public static class ResponeThrowable extends Exception {
|
||||
public int code;
|
||||
public String message;
|
||||
|
||||
public ResponeThrowable(Throwable throwable, int code) {
|
||||
super(throwable);
|
||||
this.code = code;
|
||||
|
||||
}
|
||||
@Override
|
||||
public String getMessage(){
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ServerException extends RuntimeException {
|
||||
public int code;
|
||||
public String message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.xiangxue.common.network.errorhandler;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.functions.Function;
|
||||
|
||||
/**
|
||||
* Created by Allen on 2017/7/20.
|
||||
* 保留所有版权,未经允许请不要分享到互联网和其他人
|
||||
*/
|
||||
|
||||
/**
|
||||
* HttpResponseFunc处理以下两类网络错误:
|
||||
* 1、http请求相关的错误,例如:404,403,socket timeout等等;
|
||||
* 2、应用数据的错误会抛RuntimeException,最后也会走到这个函数来统一处理;
|
||||
*/
|
||||
public class HttpErrorHandler<T> implements Function<Throwable, Observable<T>> {
|
||||
@Override
|
||||
public io.reactivex.Observable<T> apply(Throwable throwable) throws Exception {
|
||||
return io.reactivex.Observable.error(ExceptionHandle.handleException(throwable));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.xiangxue.common.network.observer;
|
||||
|
||||
import io.reactivex.Observer;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
|
||||
public abstract class BaseObserver<T> implements Observer<T> {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(T t) {
|
||||
onSuccess(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
onFailure(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
|
||||
}
|
||||
|
||||
public abstract void onSuccess(T t);
|
||||
public abstract void onFailure(Throwable e);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.xiangxue.common.network.utils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public class Base64 {
|
||||
private static char[] base64EncodeChars = new char[] { 'A', 'B', 'C', 'D',
|
||||
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
|
||||
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
|
||||
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
|
||||
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '/' };
|
||||
|
||||
private static byte[] base64DecodeChars = new byte[] { -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1,
|
||||
-1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
|
||||
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1,
|
||||
-1, -1 };
|
||||
|
||||
public static String encode(byte[] data) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int len = data.length;
|
||||
int i = 0;
|
||||
int b1, b2, b3;
|
||||
while (i < len) {
|
||||
b1 = data[i++] & 0xff;
|
||||
if (i == len) {
|
||||
sb.append(base64EncodeChars[b1 >>> 2]);
|
||||
sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
|
||||
sb.append("==");
|
||||
break;
|
||||
}
|
||||
b2 = data[i++] & 0xff;
|
||||
if (i == len) {
|
||||
sb.append(base64EncodeChars[b1 >>> 2]);
|
||||
sb.append(base64EncodeChars[((b1 & 0x03) << 4)
|
||||
| ((b2 & 0xf0) >>> 4)]);
|
||||
sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
|
||||
sb.append("=");
|
||||
break;
|
||||
}
|
||||
b3 = data[i++] & 0xff;
|
||||
sb.append(base64EncodeChars[b1 >>> 2]);
|
||||
sb.append(base64EncodeChars[((b1 & 0x03) << 4)
|
||||
| ((b2 & 0xf0) >>> 4)]);
|
||||
sb.append(base64EncodeChars[((b2 & 0x0f) << 2)
|
||||
| ((b3 & 0xc0) >>> 6)]);
|
||||
sb.append(base64EncodeChars[b3 & 0x3f]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static byte[] decode(String str) throws UnsupportedEncodingException {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
byte[] data = str.getBytes("US-ASCII");
|
||||
int len = data.length;
|
||||
int i = 0;
|
||||
int b1, b2, b3, b4;
|
||||
while (i < len) {
|
||||
/* b1 */
|
||||
do {
|
||||
b1 = base64DecodeChars[data[i++]];
|
||||
} while (i < len && b1 == -1);
|
||||
if (b1 == -1)
|
||||
break;
|
||||
/* b2 */
|
||||
do {
|
||||
b2 = base64DecodeChars[data[i++]];
|
||||
} while (i < len && b2 == -1);
|
||||
if (b2 == -1)
|
||||
break;
|
||||
sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4)));
|
||||
/* b3 */
|
||||
do {
|
||||
b3 = data[i++];
|
||||
if (b3 == 61)
|
||||
return sb.toString().getBytes("ISO-8859-1");
|
||||
b3 = base64DecodeChars[b3];
|
||||
} while (i < len && b3 == -1);
|
||||
if (b3 == -1)
|
||||
break;
|
||||
sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));
|
||||
/* b4 */
|
||||
do {
|
||||
b4 = data[i++];
|
||||
if (b4 == 61)
|
||||
return sb.toString().getBytes("ISO-8859-1");
|
||||
b4 = base64DecodeChars[b4];
|
||||
} while (i < len && b4 == -1);
|
||||
if (b4 == -1)
|
||||
break;
|
||||
sb.append((char) (((b3 & 0x03) << 6) | b4));
|
||||
}
|
||||
return sb.toString().getBytes("ISO-8859-1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.xiangxue.common.network.utils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public final class TecentUtil {
|
||||
public static final String secretId = "AKIDbdB15u6x60cw50p242zez6lj3v8vhjtbbg8";
|
||||
public static final String secretKey = "4g7w4RqetblslngIxoUqkhtyf2pdy15dAml8uu9e";
|
||||
private static final String CONTENT_CHARSET = "UTF-8";
|
||||
private static final String HMAC_ALGORITHM = "HmacSHA1";
|
||||
private TecentUtil(){
|
||||
}
|
||||
|
||||
private static String sign(String secret, String timeStr) {
|
||||
//get signStr
|
||||
String signStr = "date: " + timeStr + "\n" + "source: " + "source";
|
||||
//get sig
|
||||
try {
|
||||
Mac mac1 = Mac.getInstance(HMAC_ALGORITHM);
|
||||
|
||||
byte[] hash;
|
||||
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(CONTENT_CHARSET), mac1.getAlgorithm());
|
||||
mac1.init(secretKey);
|
||||
hash = mac1.doFinal(signStr.getBytes(CONTENT_CHARSET));
|
||||
String sig = new String(Base64.encode(hash));
|
||||
System.out.println("signValue--->" + sig);
|
||||
return sig;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getAuthorization(String timeStr){
|
||||
String sig = sign(secretKey, timeStr);
|
||||
return "hmac id=\"" + secretId + "\", algorithm=\"hmac-sha1\", headers=\"date source\", signature=\"" + sig + "\"";
|
||||
}
|
||||
|
||||
public static String getTimeStr(){
|
||||
Calendar cd = Calendar.getInstance();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
|
||||
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
return sdf.format(cd.getTime());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.xiangxue.common.order;
|
||||
|
||||
import com.xiangxue.arouter_api.Call;
|
||||
|
||||
public interface OrderDrawable extends Call {
|
||||
|
||||
int getDrawable();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.xiangxue.common.order.net;
|
||||
|
||||
import com.xiangxue.arouter_api.Call;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 订单模块对外暴露接口,其他模块可以获取返回业务数据
|
||||
*/
|
||||
public interface OrderAddress extends Call {
|
||||
|
||||
OrderBean getOrderBean(String key, String ip) throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.xiangxue.common.order.net;
|
||||
|
||||
/**
|
||||
* {"resultcode":"200","reason":"查询成功",
|
||||
* "result":{"Country":"美国","Province":"加利福尼亚","City":"","Isp":""},"error_code":0}
|
||||
*/
|
||||
public class OrderBean {
|
||||
|
||||
private String resultcode;
|
||||
private String reason;
|
||||
private Result result;
|
||||
private int error_code;
|
||||
|
||||
public static class Result {
|
||||
|
||||
private String Country;
|
||||
private String Province;
|
||||
private String City;
|
||||
private String Isp;
|
||||
|
||||
public String getCountry() {
|
||||
return Country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
Country = country;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return Province;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
Province = province;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return City;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
City = city;
|
||||
}
|
||||
|
||||
public String getIsp() {
|
||||
return Isp;
|
||||
}
|
||||
|
||||
public void setIsp(String isp) {
|
||||
Isp = isp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Result{" +
|
||||
"Country='" + Country + '\'' +
|
||||
", Province='" + Province + '\'' +
|
||||
", City='" + City + '\'' +
|
||||
", Isp='" + Isp + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public String getResultcode() {
|
||||
return resultcode;
|
||||
}
|
||||
|
||||
public void setResultcode(String resultcode) {
|
||||
this.resultcode = resultcode;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Result result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public int getError_code() {
|
||||
return error_code;
|
||||
}
|
||||
|
||||
public void setError_code(int error_code) {
|
||||
this.error_code = error_code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OrderBean{" +
|
||||
"resultcode='" + resultcode + '\'' +
|
||||
", reason='" + reason + '\'' +
|
||||
", result=" + result +
|
||||
", error_code=" + error_code +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.xiangxue.common.order.user;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 例如:用户实体父类
|
||||
*/
|
||||
public class BaseUser implements Serializable {
|
||||
|
||||
private String name;
|
||||
private String account;
|
||||
private String password;
|
||||
private String phoneNumber;
|
||||
private int gender;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public void setAccount(String account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getPhoneNumber() {
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
public void setPhoneNumber(String phoneNumber) {
|
||||
this.phoneNumber = phoneNumber;
|
||||
}
|
||||
|
||||
public int getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
public void setGender(int gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BaseUser{" +
|
||||
"name='" + name + '\'' +
|
||||
", account='" + account + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", phoneNumber='" + phoneNumber + '\'' +
|
||||
", gender=" + gender +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.xiangxue.common.order.user;
|
||||
|
||||
import com.xiangxue.arouter_api.Call;
|
||||
|
||||
public interface IUser extends Call {
|
||||
|
||||
/**
|
||||
* @return 根据不同子模块的具体实现,调用得到不同的结果
|
||||
*/
|
||||
BaseUser getUserInfo();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.xiangxue.common.utils;
|
||||
|
||||
/**
|
||||
* 常用工具类
|
||||
*/
|
||||
public final class CommonUtils {
|
||||
}
|
||||
7
common/src/main/java/com/xiangxue/common/utils/Cons.java
Normal file
7
common/src/main/java/com/xiangxue/common/utils/Cons.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package com.xiangxue.common.utils;
|
||||
|
||||
public final class Cons {
|
||||
|
||||
public static final String TAG = "Derray";
|
||||
|
||||
}
|
||||
15
common/src/main/res/drawable/ic_controls.xml
Normal file
15
common/src/main/res/drawable/ic_controls.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="56dp"
|
||||
android:height="56dp"
|
||||
android:viewportWidth="56"
|
||||
android:viewportHeight="56">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M8,41.08V2c0,-0.553 -0.448,-1 -1,-1S6,1.447 6,2v39.08C2.613,41.568 0,44.481 0,48c0,3.859 3.14,7 7,7s7,-3.141 7,-7C14,44.481 11.387,41.568 8,41.08zM7,53c-2.757,0 -5,-2.243 -5,-5s2.243,-5 5,-5s5,2.243 5,5S9.757,53 7,53z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M29,20.695V2c0,-0.553 -0.448,-1 -1,-1s-1,0.447 -1,1v18.632c-3.602,0.396 -6.414,3.456 -6.414,7.161s2.812,6.765 6.414,7.161V54c0,0.553 0.448,1 1,1s1,-0.447 1,-1V34.891c3.4,-0.577 6,-3.536 6,-7.098S32.4,21.272 29,20.695zM27.793,33c-2.871,0 -5.207,-2.336 -5.207,-5.207s2.335,-5.207 5.207,-5.207S33,24.922 33,27.793S30.664,33 27.793,33z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M56,8c0,-3.859 -3.14,-7 -7,-7s-7,3.141 -7,7c0,3.519 2.613,6.432 6,6.92V54c0,0.553 0.448,1 1,1s1,-0.447 1,-1V14.92C53.387,14.432 56,11.519 56,8zM49,13c-2.757,0 -5,-2.243 -5,-5s2.243,-5 5,-5s5,2.243 5,5S51.757,13 49,13z"/>
|
||||
</vector>
|
||||
7
common/src/main/res/layout/activity_environment.xml
Normal file
7
common/src/main/res/layout/activity_environment.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"></FrameLayout>
|
||||
</layout>
|
||||
12
common/src/main/res/values/array.xml
Normal file
12
common/src/main/res/values/array.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="environmentArray">
|
||||
<item>正式</item>
|
||||
<item>测试</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="environmentValues">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
4
common/src/main/res/values/strings.xml
Normal file
4
common/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">network</string>
|
||||
<string name="network_environment_setting">开发者设置</string>
|
||||
</resources>
|
||||
12
common/src/main/res/xml/environment_preference.xml
Normal file
12
common/src/main/res/xml/environment_preference.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="1"
|
||||
android:entries="@array/environmentArray"
|
||||
android:entryValues="@array/environmentValues"
|
||||
android:icon="@drawable/ic_controls"
|
||||
android:key="network_environment_type"
|
||||
android:summary="请您选择您需要使用的网络环境,选择完后会重启APP生效"
|
||||
android:title="设置网络环境" />
|
||||
</PreferenceScreen>
|
||||
4
common/src/main/res/xml/network_security_config.xml
Normal file
4
common/src/main/res/xml/network_security_config.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true" />
|
||||
</network-security-config>
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.xiangxue.common.network;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user