新增服务端返回 code 1415 全局拦截跳转至完善资料页功能

(cherry picked from commit c09c07bb01dff140dfebb079fb9b8f6b18468872)
This commit is contained in:
huangjian
2021-06-22 17:31:01 +08:00
parent 7d42dcb285
commit a92e174eeb
15 changed files with 253 additions and 416 deletions

View File

@@ -11,7 +11,6 @@ import android.graphics.Color;
import android.net.http.HttpResponseCache;
import android.os.Build;
import android.os.Environment;
import android.os.StrictMode;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -20,7 +19,6 @@ import androidx.multidex.MultiDex;
import com.alibaba.security.biometrics.activity.ALBiometricsActivity;
import com.alibaba.security.biometrics.activity.ALBiometricsDialogActivity;
import com.alibaba.security.realidentity.RPVerify;
import com.alibaba.security.realidentity.activity.RPTakePhotoActivity;
import com.alibaba.security.realidentity.activity.RPWebViewActivity;
import com.bumptech.glide.request.target.ViewTarget;
@@ -60,6 +58,7 @@ import com.yizhuan.erban.R;
import com.yizhuan.erban.flutter.XplanFlutterBoostCallback;
import com.yizhuan.erban.flutter.XplanFlutterBoostDelegate;
import com.yizhuan.erban.module_hall.HallDataManager;
import com.yizhuan.erban.quick_pass.QuickPassLoginAct;
import com.yizhuan.erban.radish.wallet.RadishWalletManager;
import com.yizhuan.erban.reciever.ConnectiveChangedReceiver;
import com.yizhuan.erban.utils.PushMessageHandler;
@@ -69,17 +68,15 @@ import com.yizhuan.xchat_android_core.DemoCache;
import com.yizhuan.xchat_android_core.Env;
import com.yizhuan.xchat_android_core.UriProvider;
import com.yizhuan.xchat_android_core.auth.AuthModel;
import com.yizhuan.xchat_android_core.bean.response.ServiceResult;
import com.yizhuan.xchat_android_core.channel.ChannelModel;
import com.yizhuan.xchat_android_core.family.model.FamilyModel;
import com.yizhuan.xchat_android_core.gift.GiftModel;
import com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.OpenSignInAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomInviteFansAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomInviteFansInfo;
import com.yizhuan.xchat_android_core.initial.InitialModel;
import com.yizhuan.xchat_android_core.interceptor.NoParamsInterceptor;
import com.yizhuan.xchat_android_core.interceptor.ParamsInterceptor;
import com.yizhuan.xchat_android_core.manager.AudioEngineManager;
import com.yizhuan.xchat_android_core.manager.IMMessageManager;
import com.yizhuan.xchat_android_core.manager.IMSystemMsgManager;
import com.yizhuan.xchat_android_core.market_verify.MarketVerifyModel;
@@ -92,22 +89,25 @@ import com.yizhuan.xchat_android_core.room.face.DynamicFaceModel;
import com.yizhuan.xchat_android_core.statistic.StatisticManager;
import com.yizhuan.xchat_android_core.statistic.protocol.StatisticsProtocol;
import com.yizhuan.xchat_android_core.user.UserModel;
import com.yizhuan.xchat_android_core.user.event.NeedCompleteInfoEvent;
import com.yizhuan.xchat_android_core.utils.SharedPreferenceUtils;
import com.yizhuan.xchat_android_library.net.ErBanAllHostnameVerifier;
import com.yizhuan.xchat_android_core.utils.net.ServerException;
import com.yizhuan.xchat_android_library.net.rxnet.RxNet;
import com.yizhuan.xchat_android_library.net.rxnet.converter.GsonConverterPlugins;
import com.yizhuan.xchat_android_library.utils.AppMetaDataUtil;
import com.yizhuan.xchat_android_library.utils.AppUtils;
import com.yizhuan.xchat_android_library.utils.DeviceUuidFactory;
import com.yizhuan.xchat_android_library.utils.ProcessUtil;
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
import com.yizhuan.xchat_android_library.utils.SystemUtils;
import com.yizhuan.xchat_android_library.utils.VersionUtil;
import com.yizhuan.xchat_android_library.utils.config.BasicConfig;
import com.zhihu.matisse.ui.MatisseActivity;
import org.greenrobot.eventbus.EventBus;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import io.reactivex.plugins.RxJavaPlugins;
import io.realm.Realm;
@@ -138,20 +138,6 @@ public class XChatApplication extends Application {
public static final String TAG = "XChatApplication";
private static XChatApplication instance;
private static boolean isSupportOaid = false;
public static boolean isSupportOaid() {
return isSupportOaid;
}
public static void setIsSupportOaid(boolean isSupportOaid) {
XChatApplication.isSupportOaid = isSupportOaid;
}
public static void setIsSupportOaid(boolean isSupportOaid, int ErrorCode) {
XChatApplication.isSupportOaid = isSupportOaid;
}
public static XChatApplication instance() {
return instance;
}
@@ -163,7 +149,6 @@ public class XChatApplication extends Application {
static {
SmartRefreshLayout.setDefaultRefreshHeaderCreater(
(context, layout) -> {
// layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色
layout.setEnableHeaderTranslationContent(false);
MaterialHeader materialHeader = new MaterialHeader(context);
materialHeader.setShowBezierWave(false);
@@ -191,7 +176,6 @@ public class XChatApplication extends Application {
LogUtils.d(channel + "");
initEnv(channel);
//延迟初始化云信
NIMClient.init(this, null, options());
@@ -204,14 +188,29 @@ public class XChatApplication extends Application {
});
if (inMainProcess(this)) {
// 注册自定义推送消息处理,这个是可选项
// 注册自定义推送消息处理,这个是可选项
NIMPushClient.registerMixPushMessageHandler(new PushMessageHandler());
RxJavaPlugins.setErrorHandler(throwable -> {
throwable.printStackTrace();
// print it
Log.e(TAG, "the subscribe() method default error handler", throwable);
if (BuildConfig.DEBUG) {
Log.e(TAG, "the subscribe() method default error handler", throwable);
}
});
//需要完善资料错误码全局处理
GsonConverterPlugins.setResultHandler(result -> {
if (result instanceof ServiceResult<?>) {
ServiceResult<?> serviceResult = (ServiceResult<?>) result;
if (serviceResult.getCode() == ServiceResult.CODE_NEED_COMPLETE_USER_INFO) {
SingleToastUtil.showToast(serviceResult.getMessage());
EventBus.getDefault().post(new NeedCompleteInfoEvent());
throw new ServerException(serviceResult.getMessage(), serviceResult.getCode());
}
}
return null;
});
GsonConverterPlugins.lockdown();
//fixed: Glide Exception:"You must not call setTag() on a view Glide is targeting"
ViewTarget.setTagId(R.id.tag_glide);
@@ -226,14 +225,12 @@ public class XChatApplication extends Application {
CrashReport.setAppChannel(this, channel);
}
initBuglyUpdate();
Bugly.init(this, BuildConfig.DEBUG ? XChatConstants.BUGLY_KEY_DEBUG : XChatConstants.BUGLY_KEY_RELEASE, BuildConfig.DEBUG);
if (!TextUtils.isEmpty(channel)) {
Bugly.setAppChannel(this, channel);
}
//生命周期监听
if (lifeManager == null) {
lifeManager = new ActivityLifeManager();
@@ -409,7 +406,7 @@ public class XChatApplication extends Application {
return options;
}
private MessageNotifierCustomization messageNotifierCustomization = new MessageNotifierCustomization() {
private final MessageNotifierCustomization messageNotifierCustomization = new MessageNotifierCustomization() {
@Override
public String makeNotifyContent(String nick, IMMessage message) {
if (message.getMsgType() == MsgTypeEnum.custom) {
@@ -419,9 +416,6 @@ public class XChatApplication extends Application {
} else if (customAttachment instanceof OpenSignInAttachment) {
return getContentFromOpenSignIn(customAttachment);
}
// else if (customAttachment.getFirst() == CUSTOM_MSG_PUSH_NOTIFIFICATION){
// return getContentRoomInvite(customAttachment);
// }
}
// 采用SDK默认文案
return "收到一条消息";
@@ -437,9 +431,6 @@ public class XChatApplication extends Application {
} else if (customAttachment instanceof OpenSignInAttachment) {
return getContentFromOpenSignIn(customAttachment);
}
// else if (customAttachment instanceof RoomInviteFansAttachment){
// return getContentRoomInvite(customAttachment);
// }
}
}
// 采用SDK默认文案
@@ -460,20 +451,6 @@ public class XChatApplication extends Application {
return result;
}
private String getContentRoomInvite(CustomAttachment attachment) {
String result = null;
if (attachment instanceof RoomInviteFansAttachment) {
RoomInviteFansInfo roomInviteFansInfo = ((RoomInviteFansAttachment) attachment).getRoomInviteFansInfo();
if (roomInviteFansInfo != null) {
result = roomInviteFansInfo.getData().getData().getContent();
}
}
if (TextUtils.isEmpty(result)) {
result = "收到一条消息";
}
return result;
}
@Override
public String makeRevokeMsgTip(String s, IMMessage imMessage) {
return null;
@@ -533,72 +510,15 @@ public class XChatApplication extends Application {
/**
* 只允许在MainActivity上显示更新弹窗其他activity上不显示弹窗;
* 不设置会默认所有activity都可以显示弹窗;
* 2021/6/22 增加登录页面也可以弹出,万一域名挂了还可以用bugly更新!!
*/
Beta.canShowUpgradeActs.add(MainActivity.class);
Beta.canShowUpgradeActs.add(QuickPassLoginAct.class);
/**
* 自定义布局
*/
Beta.upgradeDialogLayoutId = R.layout.upgrade_dialog;//关键代码写这个布局添加自己想要的
/**
* 设置自定义tip弹窗UI布局
* 注意因为要保持接口统一需要用户在指定控件按照以下方式设置tag否则会影响您的正常使用
* 标题beta_titleandroid:tag="beta_title"
* 提示信息beta_tip_message 如: android:tag="beta_tip_message"
* 取消按钮beta_cancel_button 如android:tag="beta_cancel_button"
* 确定按钮beta_confirm_button 如android:tag="beta_confirm_button"
* 详见layout/tips_dialog.xml
*/
//Beta.tipsDialogLayoutId = R.layout.tips_dialog;
// Beta.upgradeDialogLifecycleListener = new UILifecycleListener<UpgradeInfo>() {
// @Override
// public void onCreate(Context context, View view, UpgradeInfo upgradeInfo) {
//
// // 通过tag方式获取控件并更改布局内容
// TextView textView = (TextView) view.findViewWithTag("beta_upgrade_feature");
// // 更多的操作:比如设置控件的点击事件
// textView.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
//
// }
// });
// }
//
// @Override
// public void onStart(Context context, View view, UpgradeInfo upgradeInfo) {
//
// }
//
// @Override
// public void onResume(Context context, View view, UpgradeInfo upgradeInfo) {
//
// // 注可通过这个回调方式获取布局的控件如果设置了id可通过findViewById方式获取如果设置了tag可以通过findViewWithTag具体参考下面例子:
//
//
// }
//
// @Override
// public void onPause(Context context, View view, UpgradeInfo upgradeInfo) {
//
// }
//
// @Override
// public void onStop(Context context, View view, UpgradeInfo upgradeInfo) {
//
// }
//
// @Override
// public void onDestroy(Context context, View view, UpgradeInfo upgradeInfo) {
//
//// ToastUtils.showGravityToast(MyApplication.this,"更新后注意通知栏下载进度...");
// }
//
// };
}
/**
@@ -659,9 +579,7 @@ public class XChatApplication extends Application {
.setBaseUrl(url)
.addInterceptors(new ParamsInterceptor(httpParams))
.addInterceptors(new NoParamsInterceptor())//注意:拦截器的添加顺序,请求的拦截顺序
//.addInterceptors(new DomainInterceptor())
.certificates()
.hostnameVerifier(new ErBanAllHostnameVerifier())
.build();
//单例的model 初始化
initModel();
@@ -705,7 +623,6 @@ public class XChatApplication extends Application {
*/
private void initModel() {
DynamicFaceModel.get().init();
// RedPacketModel.get();
PayModel.get();
UserModel.get();
//ui层的萝卜钱包
@@ -725,7 +642,6 @@ public class XChatApplication extends Application {
PublicChatHallModel.get();
// 模厅
HallDataManager.get().application();
// HallModel.get();
// 师徒
MentoringRelationshipModel.get();
//全局处理

View File

@@ -42,7 +42,6 @@ android {
'src/model_music/java',
'src/model_database_room/java',
'src/model_mini_world/java',
'src/model_multi_domain/java',
'src/model_bank_card/java',
'src/model_super_admin/java',
'src/model_treasure_box/java',

View File

@@ -83,6 +83,7 @@ public class ServiceResult<T> implements Serializable {
public static final int DIAMONDNUMNOTENOUGH = 2104;//钻石数量不够
public static final int SMSCODEERROR = 4003;//短信验证码错误
public static final int WEEKNOTWITHCASHTOWNUMS = 1600;//每周提现俩次
public static final int CODE_NEED_COMPLETE_USER_INFO = 1415;//每周提现俩次
/** 没有网络 */
public static final int NOT_NET = 50010;

View File

@@ -1,64 +0,0 @@
package com.yizhuan.xchat_android_core.interceptor;
import android.text.TextUtils;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.yizhuan.xchat_android_core.Env;
import com.yizhuan.xchat_android_core.domain.model.DomainModel;
import com.yizhuan.xchat_android_core.utils.SharedPreferenceUtils;
import java.io.IOException;
import java.util.Objects;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by MadisonRong on 2019-07-28
*/
public class DomainInterceptor implements Interceptor {
private static final String TAG = "DomainInterceptor";
@Override
public Response intercept(Chain chain) throws IOException {
if (Env.getCurrentEnv() == Env.EnvType.Staging) {
// 预发布环境下不走动态域名的逻辑
return chain.proceed(chain.request());
}
// 从缓存里获得可用域名
String domain = (String) SharedPreferenceUtils.get(DomainModel.KEY_AVAILABLE_HOST, "");
// 原请求里的域名
Request oldRequest = chain.request();
String host = oldRequest.url().host();
LogUtil.e(TAG, String.format("intercept: host: %s, domain: %s", host, domain));
String updateUrl = oldRequest.header("need_update_url");
if (!TextUtils.isEmpty(updateUrl) && !Boolean.getBoolean(updateUrl)) {
return chain.proceed(oldRequest);
}
// 缓存域名为空,则认为是第一次启动,此时默认放行
if (!TextUtils.isEmpty(domain)) {
String scheme = DomainModel.getInstance().getScheme(domain);
int port = DomainModel.getInstance().getPort(domain);
// 域名不同,表示需要更换域名进行访问
domain = DomainModel.getInstance().getHostString(domain, false);
String tempHost = DomainModel.getInstance().getHostString(host, false);
LogUtil.e(TAG, String.format("intercept: scheme: %s, port: %s, domain: %s, tempHost: %s, host: %s",
scheme, port, domain, tempHost, host));
if (!Objects.equals(domain, tempHost)) {
LogUtil.e(TAG, String.format("intercept: change domain, previous: %s, now: %s", host, domain));
HttpUrl.Builder builder = oldRequest.url().newBuilder()
.scheme(scheme)
.port(port)
.host(domain);
Request newRequest = oldRequest.newBuilder()
.url(builder.build())
.build();
return chain.proceed(newRequest);
}
}
return chain.proceed(oldRequest);
}
}

View File

@@ -4,7 +4,7 @@ package com.yizhuan.xchat_android_core.utils.net;
* Created by fwhm on 2017/7/27.
*/
public class ServerException extends Exception {
public class ServerException extends RuntimeException {
public int code;
public ServerException(String message, int code) {

View File

@@ -1,7 +0,0 @@
package com.yizhuan.xchat_android_core.domain;
/**
* Created by MadisonRong on 2019-07-27
*/
public class TEMP {
}

View File

@@ -1,186 +0,0 @@
package com.yizhuan.xchat_android_core.domain.model;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.yizhuan.xchat_android_core.Env;
import com.yizhuan.xchat_android_core.UriProvider;
import com.yizhuan.xchat_android_core.base.BaseModel;
import com.yizhuan.xchat_android_core.utils.SharedPreferenceUtils;
import com.yizhuan.xchat_android_core.utils.net.RxHelper;
import com.yizhuan.xchat_android_library.utils.JavaUtil;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
/**
* Created by MadisonRong on 2019-07-27
*/
public class DomainModel extends BaseModel implements IDomainModel {
/**
* 目前可用的域名,用于整个 APP 进行业务接口调用
*/
public static final String KEY_AVAILABLE_HOST = "AvailableHost";
public static final String SCHEME_HTTP = "http";
public static final String SCHEME_HTTPS = "https";
public static final String HTTP = "http://";
public static final String HTTPS = "https://";
public static final int PORT_DEFAULT = 80;
private static final String TAG = "DomainModel";
private String lb = Env.isDebug() ? "http://115.28.86.139/" : "http://118.190.129.218:10003/";
// 记录域名检测列表
private volatile List<Disposable> disposableList = new ArrayList<>();
// 异步请求管理
private volatile CompositeDisposable compositeDisposable = new CompositeDisposable();
private List<String> domainList = new ArrayList<>();
private DomainModel() {
if (Env.isDebug()) {
domainList.add("http://apibeta.qxjiaoyou.com/");
} else {
domainList.add("http://api.woaicv.com:10003/");
domainList.add("http://api.woaiww.com:10003/");
}
}
public static DomainModel getInstance() {
return SingletonHolder.INSTANCE;
}
@Override
public Single<Boolean> analyseDomain(String host) {
AtomicReference<Disposable> analyDisposable = new AtomicReference<>();
return Single.create((SingleOnSubscribe<Boolean>) e -> {
LogUtil.e(TAG, "analyseDomain: " + host);
e.onSuccess(isAvailableHost(host));
})
.doOnSubscribe(disposable -> {
analyDisposable.set(disposable);
compositeDisposable.add(disposable);
disposableList.add(disposable);
})
.doOnSuccess(result -> {
LogUtil.e(TAG, String.format("analyseDomain: %s result: %s", host, result));
if (result) {
// 域名可用,先缓存起来
SharedPreferenceUtils.put(KEY_AVAILABLE_HOST, host);
UriProvider.initUri(getBaseUrl(host), getBaseUrl(host), getBaseUrl(host));
LogUtil.e(TAG, "analyseDomain: 往后请求都用此可用域名进行请求: " + host);
// 然后把其他的请求都停掉,避免泄露
compositeDisposable.dispose();
}
// 列表手动管理请求个数
disposableList.remove(analyDisposable.get());
Log.e(TAG, "analyseDomain: size of disposableList: " + disposableList.size());
// 当列表个数为零时,则认为所有的域名都不可用了
if (disposableList.size() == 0) {
// 所有域名都不行,尝试 LB
LogUtil.e(TAG, "analyseDomain: 所有域名都不行,尝试 LB ");
analyseDomain(lb).subscribe();
}
})
.compose(RxHelper.handleSchedulers());
}
public boolean isAvailableHost(String host) {
boolean result;
String ipAddress = "";
String domain = getHostString(host, false);
InetAddress returnStr;
try {
returnStr = InetAddress.getByName(domain);
ipAddress = returnStr.getHostAddress();
LogUtil.e(TAG, String.format("analyseDomain: %s ipAddress: %s", host, ipAddress));
} catch (UnknownHostException exception) {
LogUtil.e(TAG, String.format("analyseDomain: %s exception: %s", host, exception.getMessage(), exception));
//未知主机,域名解析失败
result = false;
}
// 域名解析成功
result = !TextUtils.isEmpty(ipAddress);
return result;
}
@NonNull
/**
* 获取 host
* @param needPort 是否需要端口号
*/
public String getHostString(String host, boolean needPort) {
String domain = host;
domain = domain.startsWith(HTTP) ? domain.substring(HTTP.length()) : domain;
domain = domain.startsWith(HTTPS) ? domain.substring(HTTPS.length()) : domain;
domain = domain.replaceAll("/", "").trim();
if (!needPort && domain.contains(":")) {
domain = domain.split(":")[0];
}
return domain;
}
/**
* 基本都是 H5 要用到
*
* @param host
* @return
*/
public String getBaseUrl(String host) {
if (TextUtils.isEmpty(host)) return host;
return host.endsWith("/") ? host : host + "/";
}
/**
* 获取域名中的协议头http 还是 https
*
* @param host
* @return
*/
public String getScheme(String host) {
if (TextUtils.isEmpty(host)) return SCHEME_HTTP;
if (host.startsWith(HTTPS)) return SCHEME_HTTPS;
if (host.startsWith(HTTP)) return SCHEME_HTTP;
return SCHEME_HTTP;
}
/**
* 获取端口号
*
* @param host
* @return
*/
public int getPort(String host) {
if (TextUtils.isEmpty(host)) return PORT_DEFAULT;
if (host.contains(":")) {
String[] strings = host.split(":");
if (strings.length <= 1) return PORT_DEFAULT;
String string = strings[strings.length - 1];
string = string.replaceAll("/", "").trim();
int result = JavaUtil.str2int(string);
return result > 0 ? result : PORT_DEFAULT;
}
return PORT_DEFAULT;
}
public List<String> getDomainList() {
return domainList;
}
public void appendDomainList(List<String> urls) {
this.domainList.addAll(urls);
}
private static class SingletonHolder {
private static final DomainModel INSTANCE = new DomainModel();
}
}

View File

@@ -1,19 +0,0 @@
package com.yizhuan.xchat_android_core.domain.model;
import com.yizhuan.xchat_android_core.base.IModel;
import io.reactivex.Single;
/**
* Created by MadisonRong on 2019-07-27
*/
public interface IDomainModel extends IModel {
/**
* 域名是否可用
* @param host
* @return
*/
Single<Boolean> analyseDomain(String host);
}

View File

@@ -40,7 +40,6 @@ dependencies {
def okhttp3 = "3.14.9"
def okio = "2.2.2"
def rxjava_adapter = "2.3.0"
def gson_converter = "2.9.0"
def rxjava = "2.1.7"
def rxjava_android = "2.0.1"
def rxlifecycle = "3.1.0"
@@ -73,8 +72,7 @@ dependencies {
api "com.squareup.okhttp3:okhttp:${okhttp3}"
api "com.squareup.okhttp3:logging-interceptor:${okhttp3}"
api "com.squareup.retrofit2:adapter-rxjava2:${rxjava_adapter}"
api "com.squareup.retrofit2:converter-gson:${gson_converter}"
api 'com.google.code.gson:gson:2.8.7'
api "com.squareup.okio:okio:${okio}"
api "com.scwang.smartrefresh:SmartRefreshLayout:${SmartRefreshLayoutVersion}"

View File

@@ -1,19 +0,0 @@
package com.yizhuan.xchat_android_library.net;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
/**
* <p> </p>
*
* @author jiahui
* @date 2017/12/16
*/
public final class ErBanAllHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
//信任所有的证书
return true;
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2015 Square, Inc.
*
* 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.yizhuan.xchat_android_library.net.rxnet.converter;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
/**
* A {@linkplain Converter.Factory converter} which uses Gson for JSON.
*
* <p>Because Gson is so flexible in the types it supports, this converter assumes that it can
* handle all types. If you are mixing JSON serialization with something else (such as protocol
* buffers), you must {@linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this
* instance} last to allow the other converters a chance to see their types.
*/
public final class GsonConverterFactory extends Converter.Factory {
/**
* Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
public static GsonConverterFactory create() {
return create(new Gson());
}
/**
* Create an instance using {@code gson} for conversion. Encoding to JSON and decoding from JSON
* (when no charset is specified by a header) will use UTF-8.
*/
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(
Type type,
Annotation[] parameterAnnotations,
Annotation[] methodAnnotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}

View File

@@ -0,0 +1,30 @@
package com.yizhuan.xchat_android_library.net.rxnet.converter;
import androidx.annotation.Nullable;
import kotlin.jvm.functions.Function1;
public class GsonConverterPlugins {
private static Function1<Object, Object> resultHandler;
static volatile boolean lockdown;
public static void onConvertResult(@Nullable Object object) {
if (resultHandler != null && object != null) {
resultHandler.invoke(object);
}
}
public static void setResultHandler(Function1<Object, Object> handler) {
if (lockdown) {
throw new IllegalStateException("GsonConverterPlugins can't be changed anymore");
}
resultHandler = handler;
}
public static void lockdown() {
lockdown = true;
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2015 Square, Inc.
*
* 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.yizhuan.xchat_android_library.net.rxnet.converter;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonWriter;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import retrofit2.Converter;
final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson gson;
private final TypeAdapter<T> adapter;
GsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public RequestBody convert(@NotNull T value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
JsonWriter jsonWriter = gson.newJsonWriter(writer);
adapter.write(jsonWriter, value);
jsonWriter.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2015 Square, Inc.
*
* 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.yizhuan.xchat_android_library.net.rxnet.converter;
import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Converter;
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
T result = adapter.read(jsonReader);
if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonIOException("JSON document was not fully consumed.");
}
//hook
GsonConverterPlugins.onConvertResult(result);
return result;
} finally {
value.close();
}
}
}

View File

@@ -5,6 +5,7 @@ import android.content.Context;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.yizhuan.xchat_android_library.BuildConfig;
import com.yizhuan.xchat_android_library.net.rxnet.converter.GsonConverterFactory;
import com.yizhuan.xchat_android_library.net.rxnet.https.HttpsUtils;
import com.yizhuan.xchat_android_library.net.rxnet.interceptor.HttpLoggingInterceptor;
import com.yizhuan.xchat_android_library.net.rxnet.utils.RxNetLog;
@@ -29,7 +30,6 @@ import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* <p> RxNet 管理类 </p>