蒋洪波

修改忽略文件

正在显示 54 个修改的文件 包含 4791 行增加0 行删除

要显示太多修改。

为保证性能只显示 54 of 54+ 个文件。

# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
... ...
# Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# Intellij
*.iml
# Keystore files
#*.jks
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear in the roo of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
#我加上避免漏掉
*.iml
*.properties
!gradle-wrapper.properties
.gradle
.idea
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
gradlew
*.bat
/captures
#Freeline ignore 忽略freeline的文件
*.py
/freeline
/freeline_core
freeline_project_description.json
maindexlist.txt
main/maindexlist.txt
... ...
apply plugin: 'com.android.library'
apply plugin: 'com.neenbedankt.android-apt'
android {
publishNonDefault true
useLibrary 'org.apache.http.legacy'
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
buildToolsVersion rootProject.ext.android["buildToolsVersion"]
defaultConfig {
minSdkVersion rootProject.ext.android["minSdkVersion"]
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
versionCode rootProject.ext.android["versionCode"]
versionName rootProject.ext.android["versionName"]
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile rootProject.ext.dependencies["junit"]
compile project(':Fragmentation')
compile project(':UIModule')
compile project(':UtilModule')
compile project(':NetWorkModule')
compile rootProject.ext.dependencies["rxlifecycle"]
compile rootProject.ext.dependencies["rxlifecycle-components"]
//Sysmtem bar
compile rootProject.ext.dependencies["systembar"]
provided rootProject.ext.dependencies["javax.annotation"]
compile rootProject.ext.dependencies["dagger2"]
apt rootProject.ext.dependencies["dagger2-apt-compiler"]
compile rootProject.ext.dependencies["glide"]
//butterknife
// compile rootProject.ext.dependencies["butterknife"]
// compile rootProject.ext.dependencies["butterknife-apt"]
compile ("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.1.3")
compile 'org.greenrobot:eventbus:3.0.0'
apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
compile rootProject.ext.dependencies["nineoldandroids"]
//PG工具
provided 'com.baoyz.pg:compiler:2.1.1'
compile 'com.baoyz.pg:core:2.1.1'
}
... ...
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\jianghongbo\SDK/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# 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 *;
#}
... ...
package com.xdy.commonlibrary;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}
\ No newline at end of file
... ...
<manifest package="com.xdy.commonlibrary"
xmlns:android="http://schemas.android.com/apk/res/android">
<application />
</manifest>
... ...
package com.xdy.commonlibrary.adapter; import android.os.Handler;import android.os.Looper;import android.support.annotation.NonNull;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter; import com.xdy.commonlibrary.mvp.BasePresenter; import java.lang.ref.WeakReference;import java.util.ArrayList;import java.util.Collection;import java.util.List; /** * <pre> * 千万不要重载{@link LIBBaseAdapter#getView(int, View, ViewGroup)} * </pre> * @author lixi * @Description <通用的Adapter> * @date 2017-5-19 */public abstract class LIBBaseAdapter<T, P extends BasePresenter> extends BaseAdapter implements LIBViewHolder.OnDatasetChangeListener { protected List<T> mData; protected WeakReference<P> mPresenter; private Handler uiHandler; public void setPresenter(P presenter) { this.mPresenter = new WeakReference<>(presenter); } protected synchronized final Handler getHandler() { if (uiHandler == null) { uiHandler = new Handler(Looper.getMainLooper()); } return uiHandler; } public LIBBaseAdapter() { this(null); } public LIBBaseAdapter(List<T> list) { if (list == null) { mData = new ArrayList<T>(); } else { mData = list; } init(); } protected void init() { } /** * 直接使用外部的List,自动调用notifyDataSetChanged */ public void setData(@NonNull List<T> list) { mData = list; notifyDataSetChanged(); } public List<T> getList() { return mData; } /** * 添加数据 ,自动调用notifyDataSetChanged */ public boolean addData(Collection<? extends T> collection) { return addData(collection, false); } /** * 如果是第一笔数据,则会清空之前数据,自动调用notifyDataSetChanged */ public boolean addData(Collection<? extends T> collection, boolean isFirstData) { if (null == collection || collection.isEmpty()) { return false; } if (isFirstData) { mData.clear(); } mData.addAll(collection); notifyDataSetChanged(); return true; } /** * 添加1个数据,自动调用notifyDataSetChanged */ public void addData(T data) { mData.add(data); notifyDataSetChanged(); } /** * 移除1个数据,自动调用notifyDataSetChanged */ public T remove(int index) { T t = this.mData.remove(index); notifyDataSetChanged(); return t; } /** * 移除1个数据,外部调用notifyDataSetChanged,需重载 {@link Object#equals(Object)} */ public T remove(Object object) { if (null == object) { return null; } for (int i = 0, size = null == mData ? 0 : mData.size(); i < size; i++) { T t = mData.get(i); if (null != t && t.equals(object)) { return mData.remove(i); } } return null; } /** * 添加数据,自动调用notifyDataSetChanged */ public void addData(int position, T data) { mData.add(position, data); notifyDataSetChanged(); } /** * 添加数据,自动调用notifyDataSetChanged */ public boolean addData(int position, Collection<? extends T> collection) { if (null == collection || collection.isEmpty()) { return false; } mData.addAll(position, collection); notifyDataSetChanged(); return true; } /** * 清空数据,自动调用notifyDataSetChanged */ public void clear() { mData.clear(); notifyDataSetChanged(); } @Override public int getCount() { return mData.size(); } public int getSize() { return mData.size(); } @Override public T getItem(int position) { return mData.get(position); } /** * 获得某个item,需重载 {@link Object#equals(Object)} */ public T getItem(Object object) { if (object == null) { return null; } for (int i = 0, size = null != mData ? mData.size() : 0; i < size; i++) { T t = getItem(i); if (null != t && t.equals(object)) { return t; } } return null; } public T getLastItem() { return mData.get(mData.size() - 1); } @Override public long getItemId(int position) { return position; } private ArrayList<LIBViewHolder> holders = new ArrayList<LIBViewHolder>(); private LIBViewHolder getHolder(Object data) { if (null == data) { return null; } for (int i = 0, size = holders.size(); i < size; i++) { LIBViewHolder holder = holders.get(i); if (holder.equals(data)) { return holder; } } return null; } @Override public final void onChange(final LIBViewHolder holder) { if (Looper.myLooper() != Looper.getMainLooper()) {// 如果不是主线程,就交给Handler做处理 getHandler().post(new Runnable() { @Override public void run() { onChange(holder); } }); return; } T data = holder.getTag(); holder.markRecyclerHolder();// 标记当前是重用状态 convert(holder, data, holder.getItemViewType(), holder.getPosition());// 转换布局 holder.resetRecyclerHolder();// 重置标记 } @Override public final synchronized void notifyDataSetChanged() { if (Looper.myLooper() != Looper.getMainLooper()) {// 如果不是主线程,就交给Handler做处理 getHandler().post(new Runnable() { @Override public void run() { LIBBaseAdapter.super.notifyDataSetChanged(); } }); return; } else { super.notifyDataSetChanged(); } } /** * 刷新Item,需重写 {@link Object#equals(Object)} */ public final synchronized void refreshItem(final Object item) { LIBViewHolder holder = getHolder(item);// 查找Holder,根据Holder缓存的Tag和当前传入的item匹配 if (null == holder) {// 如果找不到Holder,则刷新全部 notifyDataSetChanged(); return; } else { onChange(holder); return; } } private static final int FLAG_NONE = 0; private static final int FLAG_BASE_ENTITY = 1; private static final int FLAG_OTHER_ENTITY = 2; private int mFlag = FLAG_NONE; public void setNoRecycleFlag(boolean mNoRecycleFlag) { this.mNoRecycleFlag = mNoRecycleFlag; } private boolean mNoRecycleFlag = false;//不回收标示默认为FALSE @Deprecated @Override public View getView(int position, View convertView, ViewGroup parent) { T data = getItem(position); int itemViewType = getItemViewType(position); LIBViewHolder holder = LIBViewHolder.getHolder(convertView, parent, getLayoutId(data, itemViewType, position), position, itemViewType, mNoRecycleFlag); setTag(data, holder); if (!holder.isRecyleHolder()) { holders.add(holder);// 缓存Holder holder.setListener(this);// 设置刷新监听 } convert(holder, data, itemViewType, position);// 回调UI return holder.getConvertView();// 返回主布局,即ConvertView } private final void setTag(T data, LIBViewHolder holder) { switch (mFlag) { case FLAG_NONE: if (data instanceof LIBBaseEntity) { ((LIBBaseEntity) data).registerObserver(holder); mFlag = FLAG_BASE_ENTITY; } else { mFlag = FLAG_OTHER_ENTITY; } break; case FLAG_BASE_ENTITY: ((LIBBaseEntity) data).registerObserver(holder); break; default: break; } holder.setTag(data); } /** * 转换布局 */ public abstract void convert(LIBViewHolder holder, T data, int itemViewType, int position); /** * 获取布局id */ public abstract int getLayoutId(T data, int itemViewType, int position); }
\ No newline at end of file
... ...
package com.xdy.commonlibrary.adapter; import java.lang.ref.SoftReference; /** * 通过实体类,缓存ViewHolder的引用 * * @Description <LIBBaseEntity> * @author lixi * @date 2017年7月17日 */public abstract class LIBBaseEntity { private SoftReference<LIBViewHolder> observer; public final void registerObserver(LIBViewHolder observer) { unregisterAll(); this.observer = new SoftReference<LIBViewHolder>(observer); } public final LIBViewHolder getObserver() { if (null == observer) { return null; } return observer.get(); } /** * @return False ,entity is not visible */ public final boolean refresh() { LIBViewHolder holder = getObserver(); if (null != holder && equals(holder.getTag())) { return holder.refresh(); } else { unregisterAll(); return false; } } private final void unregisterAll() { if (null != observer) { observer.clear(); } this.observer = null; } }
\ No newline at end of file
... ...
package com.xdy.commonlibrary.adapter;
import android.content.Context;
import android.content.res.Resources;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
/**
* <pre>
* <B>非与LIBBaseAdapter使用时,下列方法将会失效 </B>
* 1.{@link #refresh()}
* 2.{@link #isRecyleHolder()}
* 3.{@link #getPosition()}
* 4.{@link #getTag()}
* 5.{@link #getItemViewType()}
* <B>若主布局只有一个View时,外部不能调用{@link View#setTag(Object)} </B>
* </pre>
* @author lixi
* @Description <LIBViewHolder>
* @date 2017-5-19
*/
public class LIBViewHolder {
private View mConvertView;// 主布局
private LIBBaseAdapter adapter;// 主布局
private Context context;//上下文
private SparseArray<View> mCacheViews;// 缓存容器
private int layoutId;// 布局ID
private boolean isMarkRecycler;// 标记当前在Adapter中是否是重用的ViewHolder
private Object tag;// 实体类缓存 只有在Adapter中才会缓存实体类
private int position;// 在Adapter中的位置
private boolean isRecyle;// 在Adapter中是否是重用的ViewHolder
private int itemViewType; // 在Adapter中的布局类型
private OnDatasetChangeListener listener;// Adapter中数据变更监听
private LIBViewHolder(Context context, ViewGroup parentView, int layoutId, int position, boolean attachToRoot, int itemViewType) {
this.context = context;
this.itemViewType = itemViewType;
this.layoutId = layoutId;
mCacheViews = new SparseArray<View>();
setConvertView(context, layoutId, parentView, attachToRoot);
}
/** 设置主布局,若为null */
private void setConvertView(Context context, int layoutId, ViewGroup parentView, boolean attachToRoot) {
if (layoutId > 0) {
View convertView = LayoutInflater.from(context).inflate(layoutId, parentView, attachToRoot);
setConvertView(convertView);
}
}
/**
* @return 是否已经设置的主布局
*/
public final boolean hasAlreadySetConvertView() {
return null != mConvertView;
}
/** 设置主布局,若为null,不会覆盖原有布局 */
public final void setConvertView(View view) {
if (null == view) {
return;
}
if (null != mConvertView) {
mCacheViews.clear();
mConvertView = null;
}
mConvertView = view;
mConvertView.setTag(this);
}
/**
* 获得ViewHolder,BaseAdapter中使用 ,attachToRoot=<code>false</code>
*/
public static LIBViewHolder getHolder(View convertView, ViewGroup parentView, int layoutId, int position, int itemViewType, boolean noRecycle) {
return getHolder(convertView, parentView, layoutId, position, false, itemViewType, noRecycle);
}
/**
* 获得ViewHolder,BaseAdapter中使用
*/
public static LIBViewHolder getHolder(View convertView, ViewGroup parentView, int layoutId, int position, boolean attachToRoot, int itemViewType, boolean noRecycle) {
LIBViewHolder holder = null;
if (convertView == null || noRecycle) {
holder = new LIBViewHolder(parentView.getContext(), parentView, layoutId, position, attachToRoot, itemViewType);
holder.isRecyle = false;
return holder;
} else {
holder = (LIBViewHolder) convertView.getTag();
holder.position = position;
holder.isRecyle = true;
holder.itemViewType = itemViewType;
return holder;
}
}
/**
* 获得ViewHolder,在某些情况下使用.
* <p/>
* <pre>
* <B>注意:以下方法将会不工作</B>
* {@link #refresh()} {@link #isRecyleHolder()}
* {@link #getPosition()} {@link #getTag()} {@link #getItemViewType()}
* </pre>
*/
public static LIBViewHolder getHolder(Context context, ViewGroup parentView, int layoutId, boolean attachToRoot) {
return new LIBViewHolder(context, parentView, layoutId, 0, attachToRoot, 0);
}
/** 获得当前在Adapter中的布局类型 */
public int getItemViewType() {
return itemViewType;
}
/** 设置在Adapter中缓存的实体类 */
protected void setTag(Object tag) {
this.tag = tag;
}
;
/** 获得在Adapter中缓存的实体类 */
@SuppressWarnings("unchecked")
public <T> T getTag() {
return (T) tag;
}
/** 获得Resources资源 */
public Resources getResources() {
return mConvertView.getResources();
}
/** Adapter中数据变更监听 */
protected static interface OnDatasetChangeListener {
void onChange(LIBViewHolder holder);
}
/** 设置Adapter中数据变更监听 */
protected void setListener(OnDatasetChangeListener listener) {
this.listener = listener;
}
/** 标记当前的ViewHolder,在Adapter中是重用的 */
protected void markRecyclerHolder() {
if (isRecyle) {
return;
}
isMarkRecycler = true;
}
/** 重置在Adapter中重用标记 */
protected void resetRecyclerHolder() {
isMarkRecycler = false;
}
/** R.layout.id */
public int getLayoutID() {
return layoutId;
}
/** 获得上下文Context */
public Context getContext() {
return context;
}
/** 在Adapter中是否是重用的ViewHolder,若不是重用的Item 在Refresh的时候 会标记为TRUE,Refresh后会重置标记 */
public boolean isRecyleHolder() {
return isMarkRecycler ? true : isRecyle;
}
/**
* 刷新item,会回调{@link LIBBaseAdapter#convert(LIBViewHolder, Object, int, int)}
* ,此时{@link #isRecyleHolder()}暂时标记为TRUE,Refresh后会重置该标记
*/
public boolean refresh() {
if (null != listener) {
listener.onChange(this);
return true;
} else {
return false;
}
}
/** 获得当前在Adapter中的位置 */
public int getPosition() {
return position;
}
/** 获得当前的View */
public View getConvertView() {
return mConvertView;
}
/** 获得某个View */
@SuppressWarnings("unchecked")
public <T extends View> T getView(int id) {
View view = mCacheViews.get(id);
if (view == null) {
view = mConvertView.findViewById(id);
}
return (T) view;
}
/** 获得某个View, 只有在初始化View 的时候才会对view设置监听事件 */
public <T extends View> T getView(int id, OnClickListener clickListener) {
return getView(id, clickListener, isRecyleHolder());
}
/** 获得某个View, 只有在初始化View 的时候才会对view设置监听事件 */
public <T extends View> T getView(int id, OnClickListener clickListener, boolean isRecycleHolder) {
T view = getView(id);
if (isRecycleHolder == false) {
view.setOnClickListener(clickListener);
view.setClickable(clickListener != null);
}
return view;
}
/** 设置文本,必须是TextView */
public TextView setText(int id, CharSequence sequence) {
return setText(id, sequence, false);
}
/** 设置文本,必须是TextView */
public TextView setText(int id, CharSequence sequence, boolean isAutoChangeVisibleAndGone) {
TextView textView = getView(id);
textView.setText(sequence);
if (isAutoChangeVisibleAndGone) {
textView.setVisibility(null == sequence || sequence.length() < 1 ? View.GONE : View.VISIBLE);
}
return textView;
}
/** 加载图片,必须是ImageView */
public ImageView loadImage(int id, int defaultResId) {
ImageView imageView = getView(id);
imageView.setImageResource(defaultResId);
return imageView;
}
;
/** 加载图片,必须是ImageView */
public ImageView loadImage(int id, String url, int defaultResId) {
return loadImage(id, url, defaultResId, 640);
}
;
/** 加载图片,必须是ImageView */
public ImageView loadImage(int id, String url, int defaultResId, int width) {
ImageView imageView = getView(id);
//RKImageLoader.getInstance().loadImage(url, imageView, defaultResId, width);
return imageView;
}
;
/** 设置View的可见性 */
public LIBViewHolder setVisibility(int id, int visibility) {
View view = getView(id);
if (view.getVisibility() != visibility) {
view.setVisibility(visibility);
}
return this;
}
@Override
public boolean equals(Object o) {
if (null == o) {
return false;
}
if (this == o) {
return true;
}
if (null != tag && tag.equals(o)) {
return true;
}
if (o instanceof Integer) {
if (position == (Integer) o) {
return true;
}
}
return false;
}
public LIBBaseAdapter getAdapter() {
return adapter;
}
public void setAdapter(LIBBaseAdapter adapter) {
this.adapter = adapter;
}
@SuppressWarnings("unchecked")
public static <T extends View> T get(View view, int id) {
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
if (viewHolder == null) {
viewHolder = new SparseArray<View>();
view.setTag(viewHolder);
}
View childView = viewHolder.get(id);
if (childView == null) {
childView = view.findViewById(id);
viewHolder.put(id, childView);
}
return (T) childView;
}
}
... ...
package com.xdy.commonlibrary.adapter;
import android.view.View;
/**
* @author 蒋洪波
* @version 版本号
* @file 文件名
* @brief 简要说明
* 详细说明,如果没有请删除
* @date 2017/10/28
* Copyright (c) 2017, 上品折扣[]
* All rights reserved.
*/
public interface OnItemClickListener<T> {
void onItemClick(View v, int position, T t);
}
... ...
package com.xdy.commonlibrary.adapter;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import java.lang.ref.WeakReference;
/**
* Created by Administrator on 2017/5/20.
*/
public class PriceTextWatcher<T extends PriceTextWatcher.UpdateEntityPrice> implements TextWatcher {
private WeakReference<EditText> mEditText;
private T t;
private int numMax = 8;//默认可以输入8位小数
public PriceTextWatcher(EditText editText) {
mEditText = new WeakReference<>(editText);
}
public void setNumMax(int numMax) {
if (numMax > 0)
this.numMax = numMax;
}
public void setSyncEntity(T t) {
this.t = t;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//如果有小数点的情况下
EditText editText = null;
if ((editText = mEditText.get()) != null) {
//如果有小数点的情况下
if (s.toString().contains(".")) {
if (s.length() - 1 - s.toString().indexOf(".") > 2) {
s = s.toString().subSequence(0,
s.toString().indexOf(".") + 3);
editText.setText(s);
editText.setSelection(s.length());
}
} else {
if (s.toString().length() > numMax) {
s = s.toString().subSequence(0, numMax);
editText.setText(s);
editText.setSelection(s.length());
}
}
//当是“.”开头的时候 直接输入为0.XX
if (s.toString().trim().substring(0).equals(".")) {
s = "0" + s;
editText.setText(s);
editText.setSelection(2);
}
// 如果是0开头的话 只能输入 0.XX
if (s.toString().startsWith("0")
&& s.toString().trim().length() > 1) {
if (!s.toString().substring(1, 2).equals(".")) {
editText.setText(s.subSequence(0, 1));
editText.setSelection(1);
return;
}
}
}
}
@Override
public void afterTextChanged(Editable s) {
// String temp = s.toString();
// if (!TextUtils.isEmpty(temp)) {
// Double price = Double.valueOf(s.toString());
// if (price > 0) {
// if (t != null)
// t.setPrice(price);
// }
// }
}
public interface UpdateEntityPrice {
public void setPrice(double price);
}
}
... ...
package com.xdy.commonlibrary.api;
import com.xdy.util.AppUtil;
import com.xdy.util.StringUtils;
import com.xdy.commonlibrary.core.CommonAppLike;
import java.io.File;
/**
* 主要定义与服务器交互的主要参数
*/
public class Api {
//主机地址
public final static String APP_HOST = "http://172.16.103.145:9002/";
// public final static String APP_HOST = "http://172.16.102.77:8080/";
//只有在达人时用到的地址
public final static String APP_HOST_TALENT = "http://192.168.205.132:9002/";
//图片主机,图片拼接规则 HOST+{proPictDir}+{proPictName}
public final static String IMAGE_HOST = "http://images.shopin.net/images";
//测试数据文件位置
public final static String API_TEST = "api/test/";
//首页地址
public final static String SUFFIX_H5_URL = "http://172.16.103.145:9002/h5/";
public final static String SUFFIX_CMS_URL = "http://172.16.200.2/";
//! H5 example:http://172.16.103.145:9002/h5/v1_0_0/html
public static final String BASE_H5_URL = StringUtils.concat(SUFFIX_H5_URL,
"v", AppUtil.getVersionName(CommonAppLike.getContext()).replace(".", "_")
, File.separator, "html", File.separator);
public final static String MALE_STYLE = StringUtils.concat(SUFFIX_CMS_URL, "index.html");
public final static String FEMALE_STYLE = StringUtils.concat(SUFFIX_CMS_URL, "index_wm.html");
public final static String CHILD_STYLE = StringUtils.concat(SUFFIX_CMS_URL, "index_kid.html");
//门店对应的地址
public final static String MALL_LGY = "http://news.baidu.com/";
public final static String MALL_WFJ = "http://www.baidu.com/";
public final static String MALL_WKS = "http://news.baidu.com/";
public final static String MALL_SLH = "http:/www.sina.com.cn/";
//帖子发布评论
public final static String PUBLISH_COMMENT = StringUtils.concat(APP_HOST_TALENT, "fashion/commentInvitation");
//获取帖子详情
public final static String GETINVITATIONINFO = StringUtils.concat(APP_HOST_TALENT, "fashion/getInvitationInfo");
//发布 上传图片
public final static String RELASEINVITATION = StringUtils.concat(APP_HOST_TALENT, "fashion/relaseInvitation");
//达人的发布
public final static String PUBLICINVITATION = StringUtils.concat(APP_HOST_TALENT, "fashion/publicInvitation");
//点赞
public final static String PRAISEINVITATION = StringUtils.concat(APP_HOST_TALENT, "fashion/publicInvitation");
//取消点赞
public final static String CANCELPRAISE = StringUtils.concat(APP_HOST_TALENT, "fashion/cancelPraise");
//关注
public final static String ATTENTIONINVITATION = StringUtils.concat(APP_HOST_TALENT, "fashion/attentionInvitation");
//取消关注
public final static String CANCELATTENTION = StringUtils.concat(APP_HOST_TALENT, "fashion/cancelAttention");
//修改帖子
public final static String UPDATEINVITATION = StringUtils.concat(APP_HOST_TALENT, "fashion/updateInvitation");
//帖子的删除
public final static String DELETEINVITATION = StringUtils.concat(APP_HOST_TALENT, "fashion/deleteInvitation");
//获取帖子分享到第三方需要的资料
public final static String SHARESANINVITATION = StringUtils.concat(APP_HOST_TALENT, "fashion/shareSanInvitation");
//用户签到
public final static String ADDDAILYSIGN = StringUtils.concat(APP_HOST_TALENT, "member/addDailysign");
//获取用户本月所有的签到信息
public final static String GETDAILYSIGN = StringUtils.concat(APP_HOST_TALENT, "member/getDailysign");
//意见反馈接口
public final static String ADDFEEDBACK = StringUtils.concat(APP_HOST_TALENT, "member/addFeedback");
//商品详情
public static final String H5_GOOD_DETAIL = StringUtils.concat(BASE_H5_URL + "goodsDetail.html?productSid=%1$s&supplySid=%2$s&channelMark=%3$s& optUserName=%4$s");
//待支付
public static final String H5_ORDER_UNPAY = StringUtils.concat(BASE_H5_URL + "order.html?k=waitpay");
//待提货
public static final String H5_ORDER_UNRECEIVER = StringUtils.concat(BASE_H5_URL + "order.html?k=waitpick");
//配送中
public static final String H5_ORDER_ONTHEWAY = StringUtils.concat(BASE_H5_URL + "order.html?k=delivering");
//全部订单
public static final String H5_ORDER_ALL = StringUtils.concat(BASE_H5_URL + "order.html?k=allorder");
//退货订单
public static final String H5_ORDER_REFUND = StringUtils.concat(BASE_H5_URL + "refundOrder.html");
//订单回收站
public static final String H5_ORDER_RECYCLE = StringUtils.concat(BASE_H5_URL + "order.html?k=recycle");
//积分
public static final String H5_JIFEN = StringUtils.concat(BASE_H5_URL + "jifen.html");
//我的券
public static final String H5_MY_COUPON = StringUtils.concat(BASE_H5_URL + "myCoupon.html");
//领取券
public static final String H5_GET_COUPON = StringUtils.concat(BASE_H5_URL + "getCoupon.html");
//关于
public static final String H5_ABOUT = StringUtils.concat(BASE_H5_URL + "about.html");
//帮助中心
public static final String H5_HELP = StringUtils.concat(BASE_H5_URL + "help.html");
}
... ...
package com.xdy.commonlibrary.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializer;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.xdy.network.WrapGsonDeserializerInfo;
import com.xdy.commonlibrary.utils.dataprocess.DoubleMayBeEmptyStringDeserializer;
import com.xdy.commonlibrary.utils.dataprocess.IntegerMayBeEmptyStringDeserializer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
/**
* @author jianghongbo
* @version 1.0
* @file ShopinGsonConverterFactory.java
* @brief
* @date 2017/1/8
* Copyright (c) 2017, 上品折扣
* All rights reserved.
*/
public class ShopinGsonConverterFactory extends Converter.Factory {
static IntegerMayBeEmptyStringDeserializer emptyStringDeserializer = new IntegerMayBeEmptyStringDeserializer();
static DoubleMayBeEmptyStringDeserializer doubleEmptyStringDeserializer = new DoubleMayBeEmptyStringDeserializer();
/**
* 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 ShopinGsonConverterFactory create(List<WrapGsonDeserializerInfo> info) {
GsonBuilder gsonBuilder = new GsonBuilder().serializeNulls();
//默认注册两个
gsonBuilder.registerTypeAdapter(int.class, emptyStringDeserializer);
gsonBuilder.registerTypeAdapter(double.class, doubleEmptyStringDeserializer);
if (info != null && info.size() > 0) {
for (WrapGsonDeserializerInfo wrapGsonDeserializerInfo : info) {
JsonDeserializer deserializer = wrapGsonDeserializerInfo.getDeserializer();
Class cls = wrapGsonDeserializerInfo.getClazz();
gsonBuilder.registerTypeAdapter(cls, deserializer);
}
}
Gson gson = gsonBuilder.create();
return new ShopinGsonConverterFactory(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.
*/
public static ShopinGsonConverterFactory create() {
return ShopinGsonConverterFactory.create(null);
}
private final Gson gson;
private ShopinGsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new ShopinGsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
//在这里需要判断一下请求不同类型的数据了文件了,返回不同的转换
return new ShopinGsonRequestBodyConverter<>(gson, adapter);
}
}
... ...
/*
* Copyright (C) 2017 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.xdy.commonlibrary.api;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonWriter;
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 ShopinGsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=UTF-8");
private static final MediaType MEDIA_TYPE_FILE = MediaType.parse("application/otcet-stream");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson gson;
private final TypeAdapter<T> adapter;
ShopinGsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public RequestBody convert(T value) throws IOException {
//请求的类型我们还不清楚,我们应该判断使用何种MEDIA_TYPE进行请求,默认是JSON的形式
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_FILE, file);
return RequestBody.create(MEDIA_TYPE_JSON, buffer.readByteString());
}
}
... ...
/*
* Copyright (C) 2017 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.xdy.commonlibrary.api;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Converter;
final class ShopinGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
ShopinGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public T convert(ResponseBody value) throws IOException {
//可以在这里通过异常的方式处理,也可以通过工具类统一的map变换一下。
// String response = value.string();
// ResultEntity result = gson.fromJson(response, ResultEntity.class);
// if (result != null && !result.isValidate(result.code)) {
// value.close();
// ResultException resultException = new ResultException(result.errorMessage);
// resultException.setResultCode(result.code);
// resultException.setErrorMessage(result.errorMessage);
// throw resultException;
// }
//这里我们可以考虑直接T extentd BaseEntity 然后返回那个data
//返回正常结果
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}
}
... ...
package com.xdy.commonlibrary.api;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.xdy.network.HttpConstants;
import com.xdy.util.AppUtil;
import com.xdy.commonlibrary.core.CommonAppLike;
import com.xdy.commonlibrary.utils.dataprocess.GsonUtil;
import java.io.File;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
/**
* @author jianghongbo
* @version 1.0
* @file ShopinRequestParams.java
* @brief 封装请求参数
* @date 2017/1/8
* Copyright (c) 2017, 上品折扣
* All rights reserved.
*/
public class ShopinRequestParams {
private ShopinRequestParams() {
}
public static Builder build() {
return new Builder();
}
public static class Builder {
public Builder() {
}
Map<String, Object> map = new TreeMap<>();
public Builder add(String key, Object value) {
if (!TextUtils.isEmpty(key) && value != null) {
map.put(key, value);
}
return this;
}
/**
* 用于content type为json的post请求,service方法为@Body类型的参数
* @return
*/
public RequestBody body() {
//添加公共参数
addCommonParams();
String body = GsonUtil.bean2json(map);
return RequestBody.create(MediaType.parse(HttpConstants.CONTENT_TYPE_FORM), body);
}
/**
* 返回一个map用于QueryMap注解的参数类型
* @return
*/
public Map<String, Object> paramsMap() {
//添加公共参数
addCommonParams();
return map;
}
public MultipartBody.Builder filesToMultipartBody(@NonNull List<File> files) {
MultipartBody.Builder builder = new MultipartBody.Builder();
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
// 这里为了简单起见,没有判断file的类型,并且按照本项目只能上传一个文件 并且name为file修改
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);
//文件以file0,1,2这样命名
builder.addFormDataPart("file", file.getName(), requestBody);
}
builder.setType(MultipartBody.FORM);
return builder;
}
private void addCommonParams() {
add("deviceType", "1")
.add("deviceSn", AppUtil.getDeviceId(CommonAppLike.getContext()))
.add("appVersion", AppUtil.getVersionName(CommonAppLike.getContext()))
.add("systemVersion", AppUtil.getOSVersion())
.add("versionNo", String.valueOf(AppUtil.getVersionCode(CommonAppLike.getContext())));
}
public Builder addAudio(String key, String path) {
File file = new File(path);
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentTypeFor = fileNameMap.getContentTypeFor(path);
RequestBody requestBody =
RequestBody.create(MediaType.parse(contentTypeFor), file);
map.put(key + "\";filename=\"" + file.getName(), requestBody);
return this;
}
public Builder addPic(String key, List<File> fileList) {
for (int i = 0; i < fileList.size(); i++) {
RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), fileList.get(i));
map.put(key + "[" + i + "]" + "\";filename=\"" + fileList.get(i).getName(), requestBody);
}
return this;
}
public Builder addSinglePic(String key, File file) {
RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file);
map.put(key + "\";filename=\"" + file.getName(), requestBody);
return this;
}
public Builder addGif(String key, File file) {
RequestBody requestBody = RequestBody.create(MediaType.parse("image/gif"), file);
map.put(key + "\";filename=\"" + file.getName(), requestBody);
return this;
}
public Builder addVideo(String key, String path) {
File file = new File(path);
RequestBody requestBody = RequestBody.create(MediaType.parse("video/mp4"), file);
map.put(key + "\";filename=\"" + file.getName(), requestBody);
return this;
}
}
}
... ...
package com.xdy.commonlibrary.api.interceptor;
import android.text.TextUtils;
import com.xdy.util.AppUtil;
import com.xdy.util.StringUtils;
import com.xdy.commonlibrary.core.CommonAppLike;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;
/**
* Created by jk.yeo on 16/3/4 15:28.
* Mail to ykooze@gmail.com
*/
public class BasicParamsInterceptor implements Interceptor {
Map<String, String> queryParamsMap = new HashMap<>();
Map<String, String> paramsMap = new HashMap<>();
Map<String, String> headerParamsMap = new HashMap<>();
List<String> headerLinesList = new ArrayList<>();
private BasicParamsInterceptor() {
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder();
/*
* process header params inject ,
* 支持完整的请求头参数和name value两种形式
* 如 可以通过headerLineList 直接加入 content-type:application/json
* 也可以通过headerParamsMap加入name为content-type value为applicaiton/json的头
*
*/
Headers.Builder headerBuilder = request.headers().newBuilder();
if (headerParamsMap.size() > 0) {
Iterator iterator = headerParamsMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
}
}
if (headerLinesList.size() > 0) {
for (String line : headerLinesList) {
headerBuilder.add(line);
}
requestBuilder.headers(headerBuilder.build());
}
// process header params end
/*
process queryParams inject whatever it's GET ,如果POST也要加到URL中把第二个判断条件去掉即可
是否在query参数中加入公共参数,稍微改一下只加入到URL上面
*/
if (queryParamsMap.size() > 0 && canInjectIntoUrl(request)) {
//根据需要加入设备ID
addDeviceId(queryParamsMap);
request = injectParamsIntoUrl(request.url().newBuilder(), requestBuilder, queryParamsMap);
}
// process post body inject
if (paramsMap.size() > 0) {
//根据需要加入设备ID
addDeviceId(paramsMap);
if (canInjectIntoFormBody(request)) {
//表单提交公共参数
FormBody.Builder formBodyBuilder = new FormBody.Builder();
for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
formBodyBuilder.add((String) entry.getKey(), (String) entry.getValue());
}
RequestBody formBody = formBodyBuilder.build();
String postBodyString = bodyToString(request.body());
postBodyString += StringUtils.concat(postBodyString.length() > 0 ? "&" : "", bodyToString(formBody));
requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
} else if (canInjectIntoJsonBody(request)) {
String postBodyString = bodyToString(request.body());
if (!TextUtils.isEmpty(postBodyString)) {
int i = postBodyString.lastIndexOf('}');
if (i != -1) {
try {
JSONObject object = new JSONObject(postBodyString);
for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
object.put(entry.getKey(), entry.getValue());
}
postBodyString = object.toString();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
requestBuilder.post(RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), postBodyString));
}
}
request = requestBuilder.build();
return chain.proceed(request);
}
private void addDeviceId(Map<String, String> map) {
boolean hasDeviceId = !TextUtils.isEmpty(map.get("deviceSn"));
if (!hasDeviceId) {
String deviceId = AppUtil.getDeviceId(CommonAppLike.getContext());
map.put("deviceSn", deviceId);
}
}
/**
* 是否能加入到BODY中,必须是POST FORM表单提交参数才能添加
* @param request
* @return
*/
private boolean canInjectIntoFormBody(Request request) {
if (request == null) {
return false;
}
if (!TextUtils.equals(request.method(), "POST")) {
return false;
}
RequestBody body = request.body();
if (body == null) {
return false;
}
MediaType mediaType = body.contentType();
if (mediaType == null) {
return false;
}
if (!TextUtils.equals(mediaType.subtype(), "x-www-form-urlencoded")) {
return false;
}
return true;
}
/**
* 是否能加入到请求地址中
* @param request
* @return
*/
private boolean canInjectIntoUrl(Request request) {
if (request == null) {
return false;
}
if (!TextUtils.equals(request.method(), "GET")) {
return false;
}
return true;
}
/**
* 是否能加入到JSON格式中,必须是POST JSON提交参数才能添加
* @param request
* @return
*/
private boolean canInjectIntoJsonBody(Request request) {
// if (paramsMap.size() == 0) {
// return false;
// }
if (request == null) {
return false;
}
if (!TextUtils.equals(request.method(), "POST")) {
return false;
}
RequestBody body = request.body();
if (body == null) {
return false;
}
MediaType mediaType = body.contentType();
if (mediaType == null) {
return false;
}
//判断子类型是不是json格式 格式为 [type]/[subType]
if (!TextUtils.equals(mediaType.subtype(), "json")) {
return false;
}
return true;
}
// func to inject params into url
private Request injectParamsIntoUrl(HttpUrl.Builder httpUrlBuilder, Request.Builder requestBuilder, Map<String, String> paramsMap) {
if (paramsMap.size() > 0) {
Iterator iterator = paramsMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
httpUrlBuilder.addQueryParameter((String) entry.getKey(), (String) entry.getValue());
}
requestBuilder.url(httpUrlBuilder.build());
return requestBuilder.build();
}
return null;
}
private static String bodyToString(final RequestBody request) {
try {
final RequestBody copy = request;
final Buffer buffer = new Buffer();
if (copy != null)
copy.writeTo(buffer);
else
return "";
return buffer.readUtf8();
} catch (final IOException e) {
return "did not work";
}
}
public static class Builder {
BasicParamsInterceptor interceptor;
public Builder() {
interceptor = new BasicParamsInterceptor();
}
public Builder addParam(String key, String value) {
interceptor.paramsMap.put(key, value);
return this;
}
public Builder addParamsMap(Map<String, String> paramsMap) {
interceptor.paramsMap.putAll(paramsMap);
return this;
}
public Builder addHeaderParam(String key, String value) {
interceptor.headerParamsMap.put(key, value);
return this;
}
public Builder addHeaderParamsMap(Map<String, String> headerParamsMap) {
interceptor.headerParamsMap.putAll(headerParamsMap);
return this;
}
public Builder addHeaderLine(String headerLine) {
int index = headerLine.indexOf(":");
if (index == -1) {
throw new IllegalArgumentException("Unexpected header: " + headerLine);
}
interceptor.headerLinesList.add(headerLine);
return this;
}
public Builder addHeaderLinesList(List<String> headerLinesList) {
for (String headerLine : headerLinesList) {
int index = headerLine.indexOf(":");
if (index == -1) {
throw new IllegalArgumentException("Unexpected header: " + headerLine);
}
interceptor.headerLinesList.add(headerLine);
}
return this;
}
public Builder addQueryParam(String key, String value) {
interceptor.queryParamsMap.put(key, value);
return this;
}
public Builder addQueryParamsMap(Map<String, String> queryParamsMap) {
interceptor.queryParamsMap.putAll(queryParamsMap);
return this;
}
public BasicParamsInterceptor build() {
return interceptor;
}
}
/**
* @param obj
* @return
* @brief 对JSONOBJECT内部进行排序
*/
public static String sortJSONObject(JSONObject obj) {
try {
if (obj == null)
return null;
Iterator<String> keys = obj.keys();
String[] keySort = new String[obj.length()];
//把KEY取出来
for (int i = 0; i < keySort.length; i++) {
keySort[i] = keys.next();
}
//对Key进行排序
Arrays.sort(keySort);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < keySort.length; i++) {
sb.append(keySort[i]);
sb.append("=");
//先取值的类型
Object opt = obj.opt(keySort[i]);
if (opt instanceof Number) {
//对于数字类型的数据要用JSONObject处理数字方式重新处理,否则会与传递给服务器的不一样,因为在put参数的时候会按这样的方式做检查处理,会导致舍弃精度的操作。
String num = JSONObject.numberToString((Number) opt);
sb.append(num);
} else if (opt instanceof JSONArray) {//判断是否是JSONArray
//提供一个方法用于返回JSONArray的值,此处按理来说应该递归sortJSONArray,但是后台为了简单点处理,直接把第二层做字符串拼接起来
String result = sortJSONArray((JSONArray) opt);
sb.append(result);
} else {
sb.append(obj.optString(keySort[i]));
}
}
return sb.toString();
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
public static String sortJSONArray(JSONArray value) {
StringBuilder jsonString = new StringBuilder();
for (int i = 0; i < value.length(); i++) {
String s = sortJSONObject(value.optJSONObject(i));
//如果为空,取字符串
if (TextUtils.isEmpty(s)) {
s = value.optString(i);
}
jsonString.append(s);
}
return jsonString.toString();
}
}
\ No newline at end of file
... ...
package com.xdy.commonlibrary.api.interceptor;
import android.support.annotation.NonNull;
import com.xdy.network.http.GlobeHttpHandler;
import com.xdy.util.LogUtil;
import com.xdy.util.StringUtils;
import com.xdy.commonlibrary.utils.ZipHelper;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import javax.inject.Inject;
import javax.inject.Singleton;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
@Singleton
public class RequestIntercept implements Interceptor {
private GlobeHttpHandler mHandler;
@Inject
public RequestIntercept(GlobeHttpHandler handler) {
this.mHandler = handler;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (mHandler != null)//在请求服务器之前可以拿到request,做一些操作比如给request添加header,如果不做操作则返回参数中的request
request = mHandler.onHttpRequestBefore(chain, request);
Buffer requestbuffer = new Buffer();
if (request.body() != null) {
request.body().writeTo(requestbuffer);
}
LogUtil.i("Request", "Sending Request %s %n Params ---> %s", request.url()
, request.body() != null ? parseParams(request.body(), requestbuffer) : "null");
long t1 = System.nanoTime();
Response originalResponse = chain.proceed(request);
long t2 = System.nanoTime();
LogUtil.i("Request", "Sending Request %s %nReceived response in %.1fms"
, request.url()
, (t2 - t1) / 1e6d);
//读取服务器返回的结果
ResponseBody responseBody = originalResponse.body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
//获取content的压缩类型
String encoding = originalResponse
.headers()
.get("Content-Encoding");
Buffer clone = buffer.clone();
String bodyString;
//解析response content
if (encoding != null && encoding.equalsIgnoreCase("gzip")) {//content使用gzip压缩
bodyString = ZipHelper.decompressForGzip(clone.readByteArray());//解压
} else if (encoding != null && encoding.equalsIgnoreCase("zlib")) {//content使用zlib压缩
bodyString = ZipHelper.decompressToStringForZlib(clone.readByteArray());//解压
} else {//content没有被压缩
Charset charset = Charset.forName("UTF-8");
MediaType contentType = responseBody.contentType();
if (contentType != null) {
charset = contentType.charset(charset);
}
bodyString = clone.readString(charset);
LogUtil.i("Result", StringUtils.jsonFormat(bodyString));
}
if (mHandler != null)//这里可以比客户端提前一步拿到服务器返回的结果,可以做一些操作,比如token超时,重新获取
return mHandler.onHttpResultResponse(bodyString, chain, originalResponse);
return originalResponse;
// return originalResponse.newBuilder()
// .body(ResponseBody.create(MediaType.parse("UTF-8"), bodyString))
// .build();
}
@NonNull
public static String parseParams(RequestBody body, Buffer requestbuffer) throws UnsupportedEncodingException {
if (body.contentType() != null && !body.contentType().toString().contains("multipart")) {
return URLDecoder.decode(requestbuffer.readUtf8(), "UTF-8");
}
return "null";
}
}
... ...
package com.xdy.commonlibrary.core;
/**
* @author jianghongbo
* @version 1.0
* @file AbsCrashHandler.java
* @brief
* @date 2017/12/19
* Copyright (c) 2017
* All rights reserved.
*/
public abstract class AbsCrashHandler implements Thread.UncaughtExceptionHandler {
public void init() {
Thread.currentThread().setUncaughtExceptionHandler(this);
}
/**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public void uncaughtException(final Thread thread, final Throwable throwable) {
handleException(throwable);
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
* @param throwable
*/
private void handleException(final Throwable throwable) {
if (!AppConfig.LOCAL_FILE_DIR.exists())
AppConfig.LOCAL_FILE_DIR.mkdirs();
saveCrash(throwable);
}
/**
* 保存崩溃的信息
*/
abstract void saveCrash(Throwable throwable);
}
... ...
package com.xdy.commonlibrary.core;
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import com.flyco.systembar.SystemBarHelper;
import com.xdy.commonlibrary.core.di.AppComponent;
import com.xdy.commonlibrary.mvp.BasePresenter;
import com.xdy.commonlibrary.mvp.BaseView;
import com.xdy.ui.loading.LoadingDialogUtils;
import com.xdy.util.ActivityUtil;
import com.xdy.util.ResUtil;
import com.xdy.util.ToastUtil;
import com.xdy.util.UIUtils;
import javax.inject.Inject;
/**
* @author jianghongbo
* @version 1.0
* @file AppBaseActivity.java
* @brief Activity业务基类
* @date 2017/12/25
* Copyright (c) 2017,上品折扣
* All rights reserved.
*/
public abstract class AppBaseActivity<P extends BasePresenter> extends com.xdy.commonlibrary.core.BaseActivity implements BaseView {
protected com.xdy.commonlibrary.core.CommonAppLike mApplication;
@Inject
protected P mPresenter;
//状态深色样式
public static final int TITLE_STYLE_DARK = 0x0;
//浅色样式
public static final int TITLE_STYLE_LIGHT = 0x1;
//男士标题
public static final int TITLE_STYLE_MALE = 0x2;
//女士标题
public static final int TITLE_STYLE_FEMAL = 0x3;
//儿童标题
public static final int TITLE_STYLE_CHILD = 0x4;
//透明
protected static final int TITLE_STYLE_TRANSPARENT = 0x2;
//是否活动的标记
private boolean isActive;
//加载进度条
private Dialog loadingDialog;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isActive = true;
// 添加Activity到堆栈
ActivityUtil.getInstance().addActivity(this);
getIntentParams();
initBaseLayout();
setStatusBarStyle();//不能加到前面
bindView();
initViews(savedInstanceState);
initComponent();
initData();
}
private void initComponent() {
AppComponent appComponent = com.xdy.commonlibrary.core.CommonAppLike.getInstance().getAppComponent();
setupActivityComponent(appComponent);//依赖注入
}
private void bindView() {
}
//提供AppComponent(提供所有的单例对象)给子类,进行Component依赖
protected abstract void setupActivityComponent(AppComponent appComponent);
/**
* 获得整个布局ID
* @return
*/
protected abstract int getLayoutId();
@Override
protected void onDestroy() {
if (mPresenter != null) mPresenter.onDestroy();//释放资源
this.mPresenter = null;
this.mApplication = null;
isActive = false;
ActivityUtil.getInstance().finishActivity(this);
super.onDestroy();
}
/**
* 提供给子类初始化基类布局使用
*/
protected void initBaseLayout() {
}
/**
* 获取标题栏样式
* @return
*/
protected int getTitleBarStyle() {
return TITLE_STYLE_DARK;
}
private void setStatusBarStyle() {
//此项目只根据主题类型设置
int titleBarStyle = getTitleBarStyle();
switch (titleBarStyle) {
case TITLE_STYLE_TRANSPARENT:
SystemBarHelper.immersiveStatusBar(this, 0f);
break;
default:
break;
}
}
@Override
public void showLoading() {
if (loadingDialog != null && loadingDialog.isShowing())
return;
if (loadingDialog == null)
loadingDialog = LoadingDialogUtils.createLoadingDialog(this, null);
loadingDialog.show();
}
@Override
public void hideLoading() {
UIUtils.closeDialog(loadingDialog);
}
@Override
public void showMessage(String message) {
ToastUtil.showToast(getBaseContext(),message);
}
public void showMessage(@StringRes int res) {
showMessage(ResUtil.get().getString(res));
}
@Override
public boolean isActive() {
return isActive;
}
}
... ...
package com.xdy.commonlibrary.core;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.xdy.ui.viewgroup.CodeMultipleStatusView;
import com.xdy.util.ResUtil;
import com.xdy.commonlibrary.core.di.AppComponent;
import com.xdy.commonlibrary.mvp.BasePresenter;
import com.xdy.commonlibrary.mvp.BaseView;
import javax.inject.Inject;
/**
* @author jianghongbo
* @version 1.0
* @file AppBaseFragment.java
* @brief
* @date 2017/12/25
* Copyright (c) 2017
* All rights reserved.
*/
public abstract class AppBaseFragment<P extends BasePresenter> extends BaseFragment implements BaseView {
protected BaseActivity mActivity;
protected CodeMultipleStatusView mRootView;
protected final String TAG = this.getClass().getSimpleName();
@Inject
protected P mPresenter;
public <T extends View> T $(View v, int id) {
return (T) v.findViewById(id);
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
@Override
public void onDestroy() {
super.onDestroy();
if (mPresenter != null) mPresenter.onDestroy();//释放资源
this.mPresenter = null;
this.mActivity = null;
this.mRootView = null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = new CodeMultipleStatusView(getContext());
return mRootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
mActivity = (BaseActivity) getActivity();
initComponent();
super.onActivityCreated(savedInstanceState);
}
@Override
public void onLazyInitView(@Nullable Bundle savedInstanceState) {
super.onLazyInitView(savedInstanceState);
//加载我们自己的布局
View view = View.inflate(getContext(), this.getLayoutId(), null);
mRootView.setContentView(view);
mRootView.showContent();
mRootView.setOnRetryClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
retry();
}
});
initView(view, savedInstanceState);
initData();
}
private void initComponent() {
AppComponent appComponent = CommonAppLike.getInstance().getAppComponent();
setupFragmentComponent(appComponent);
}
protected void setHeaderTitle(String title) {
if (getBaseActivity() instanceof TitleBaseActivity) {
((TitleBaseActivity) getBaseActivity()).setHeaderTitle(title);
}
}
protected void setHeaderTitle(@StringRes int res) {
if (getBaseActivity() instanceof TitleBaseActivity) {
((TitleBaseActivity) getBaseActivity()).setHeaderTitle(res);
}
}
/**
* 注入Fragment的组件
* @param appComponent
*/
protected abstract void setupFragmentComponent(AppComponent appComponent);
/**
* 初始化控件
*/
protected abstract void initView(View v, Bundle savedInstanceState);
/**
* 初始化数据
*/
protected abstract void initData();
/**
* 获得Fragment布局ID,除了TitleBaseFragment。
* @return
*/
@NonNull
@LayoutRes
protected abstract int getLayoutId();
/**
* 获得所属Activity,有可能为空
* @return
*/
protected AppBaseActivity getBaseActivity() {
if (getActivity() instanceof AppBaseActivity)
return (AppBaseActivity) getActivity();
return null;
}
@Override
public void showLoading() {
AppBaseActivity baseActivity = getBaseActivity();
if (baseActivity != null && baseActivity.isActive())
baseActivity.showLoading();
}
@Override
public void hideLoading() {
AppBaseActivity baseActivity = getBaseActivity();
if (baseActivity != null && baseActivity.isActive())
baseActivity.hideLoading();
}
@Override
public void showMessage(String message) {
if (getBaseActivity() != null) {
getBaseActivity().showMessage(message);
}
}
public void showMessage(@StringRes int res) {
showMessage(ResUtil.get().getString(res));
}
@Override
public boolean isActive() {
return this.isAdded();
}
protected void showFragmentEmpty() {
mRootView.showEmpty();
}
protected void showFragmentError() {
mRootView.showError();
}
protected void showFragmentNoNetwork() {
mRootView.showNoNetwork();
}
protected void showFragmentLoading() {
mRootView.showLoading();
}
protected void showFragmentContent() {
mRootView.showContent();
}
/**
* 状态不为正常内容处理点击需要重写的方法
*/
protected void retry() {
}
}
... ...
package com.xdy.commonlibrary.core;
import android.os.Environment;
import java.io.File;
/**
* @author 蒋洪波
* @version 1.0
* @file AppConfig.java
* @brief 配置应用关键参数
* @date 2017/10/17
* Copyright (c) 2017
* All rights reserved.
*/
public class AppConfig {
//应用编码方式
public static final String ENCODING = "utf-8";
//本地数据库名称
public static final String DATABASE_NAME = "database";
//! 设备类型 1.IPHONE 2.IPAD 3.ANDROID
public static final String IPHONE = "1";
public static final String IPAD = "2";
public static final String ANDROID = "3";
public static final String ANDROID_UPGRADE = "2";
//! 屏幕类型 1 小屏 2 大屏
public static final String HD = "1";
public static final String FULLHD = "2";
//! APP_KEY
public static final String APP_KEY = "123456";
//! APPSecret
public static final String APP_SECRET = "1dfa5cd879df472484138b41dbb6197e";
//SD卡 统一文件夹名称
public static final String SHOPIN_DIR = "shopin";
//本地文件夹位置
public static final File LOCAL_FILE_DIR = new File(Environment.getExternalStorageDirectory(), SHOPIN_DIR);
//辨识系统常量,在某些页面需要针对
public static final CharSequence SAMSUNG_BRAND = "samsung";
public static final CharSequence K_TOUCH_BRAND = "K-Touch";
public static final CharSequence HUAWEI = "huawei";
public static final CharSequence HONOR = "honor";
//不适配机型集合
public static final CharSequence[] INCOMPATIBILITY_PHONE = {SAMSUNG_BRAND, K_TOUCH_BRAND, HUAWEI, HONOR};
}
... ...
package com.xdy.commonlibrary.core;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Message;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* 用于管理所有activity,和在前台的 activity
* 可以通过直接持有AppManager对象执行对应方法
* 也可以通过eventbus post事件,远程遥控执行对应方法
* Created by jess on 14/12/2017 13:50
* Contact with jess.yan.effort@gmail.com
*/
@Singleton
public class AppManager {
protected final String TAG = this.getClass().getSimpleName();
public static final String APPMANAGER_MESSAGE = "appmanager_message";
public static final int START_ACTIVITY = 0;
public static final int SHOW_SNACKBAR = 1;
public static final int KILL_ALL = 2;
public static final int APP_EXIT = 3;
private Application mApplication;
//管理所有activity
public List<BaseActivity> mActivityList;
//当前在前台的activity
private BaseActivity mCurrentActivity;
@Inject
public AppManager(Application application) {
this.mApplication = application;
}
private void dispatchStart(Message message) {
if (message.obj instanceof Intent)
startActivity((Intent) message.obj);
else if (message.obj instanceof Class)
startActivity((Class) message.obj);
return;
}
/**
* 使用snackbar显示内容
*
* @param message
* @param isLong
*/
public void showSnackbar(String message, boolean isLong) {
// if (getCurrentActivity() == null) {
// return;
// }
// View view = getCurrentActivity().getWindow().getDecorView().findViewById(android.R.id.content);
// Snackbar.make(view, message, isLong ? Snackbar.LENGTH_LONG : Snackbar.LENGTH_SHORT).show();
}
/**
* 让在前台的activity,打开下一个activity
*
* @param intent
*/
public void startActivity(Intent intent) {
if (getCurrentActivity() == null) {
//如果没有前台的activity就使用new_task模式启动activity
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mApplication.startActivity(intent);
return;
}
getCurrentActivity().startActivity(intent);
}
/**
* 让在前台的activity,打开下一个activity
*
* @param activityClass
*/
public void startActivity(Class activityClass) {
startActivity(new Intent(mApplication, activityClass));
}
/**
* 释放资源
*/
public void release() {
mActivityList.clear();
mActivityList = null;
mCurrentActivity = null;
mApplication = null;
}
/**
* 将在前台的activity保存
*
* @param currentActivity
*/
public void setCurrentActivity(BaseActivity currentActivity) {
this.mCurrentActivity = currentActivity;
}
/**
* 获得当前在前台的activity
*
* @return
*/
public BaseActivity getCurrentActivity() {
return mCurrentActivity;
}
/**
* 返回一个存储所有未销毁的activity的集合
*
* @return
*/
public List<BaseActivity> getActivityList() {
if (mActivityList == null) {
mActivityList = new LinkedList<>();
}
return mActivityList;
}
/**
* 添加Activity到集合
*/
public void addActivity(BaseActivity activity) {
if (mActivityList == null) {
mActivityList = new LinkedList<>();
}
synchronized (AppManager.class) {
if (!mActivityList.contains(activity)) {
mActivityList.add(activity);
}
}
}
/**
* 删除集合里的指定activity
*
* @param activity
*/
public void removeActivity(BaseActivity activity) {
if (mActivityList == null) {
return;
}
synchronized (AppManager.class) {
if (mActivityList.contains(activity)) {
mActivityList.remove(activity);
}
}
}
/**
* 删除集合里的指定位置的activity
*
* @param location
*/
public BaseActivity removeActivity(int location) {
if (mActivityList == null) {
return null;
}
synchronized (AppManager.class) {
if (location > 0 && location < mActivityList.size()) {
return mActivityList.remove(location);
}
}
return null;
}
/**
* 关闭指定activity
*
* @param activityClass
*/
public void killActivity(Class<?> activityClass) {
if (mActivityList == null) {
return;
}
for (BaseActivity activity : mActivityList) {
if (activity.getClass().equals(activityClass)) {
activity.finish();
}
}
}
/**
* 指定的activity实例是否存活
*
* @param activity
* @return
*/
public boolean activityInstanceIsLive(BaseActivity activity) {
if (mActivityList == null) {
return false;
}
return mActivityList.contains(activity);
}
/**
* 指定的activity class是否存活(一个activity可能有多个实例)
*
* @param activityClass
* @return
*/
public boolean activityClassIsLive(Class<?> activityClass) {
if (mActivityList == null) {
return false;
}
for (BaseActivity activity : mActivityList) {
if (activity.getClass().equals(activityClass)) {
return true;
}
}
return false;
}
/**
* 关闭所有activity
*/
public void killAll() {
// while (getActivityList().size() != 0) { //此方法只能兼容LinkedList
// getActivityList().remove(0).finish();
// }
Iterator<BaseActivity> iterator = getActivityList().iterator();
while (iterator.hasNext()) {
iterator.next().finish();
iterator.remove();
}
}
/**
* 退出应用程序
*/
public void AppExit() {
try {
killAll();
if (mActivityList != null)
mActivityList = null;
ActivityManager activityMgr =
(ActivityManager) mApplication.getSystemService(Context.ACTIVITY_SERVICE);
activityMgr.killBackgroundProcesses(mApplication.getPackageName());
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
... ...
package com.xdy.commonlibrary.core;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.CallSuper;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import com.trello.rxlifecycle.ActivityEvent;
import com.trello.rxlifecycle.ActivityLifecycleProvider;
import com.trello.rxlifecycle.LifecycleTransformer;
import com.trello.rxlifecycle.RxLifecycle;
import com.xdy.commonlibrary.permission.PermissifyActivity;
import rx.Observable;
import rx.subjects.BehaviorSubject;
/**
* @author jianghongbo
* @version 1.0
* @file BaseActivity.java
* @brief Activity无关业务基类
* @date 2017/12/25
* Copyright (c) 2017,上品折扣
* All rights reserved.
*/
public abstract class BaseActivity extends PermissifyActivity implements ActivityLifecycleProvider {
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
//! 当前Activity的TAG标签
protected final String TAG = this.getClass().getSimpleName();
/**
* 为了减少findViewById太冗余,直接在Activity提供该方法
* @param id
* @param <T>
* @return
*/
public <T extends View> T $(int id) {
return (T) findViewById(id);
}
@Override
@NonNull
@CheckResult
public final Observable<ActivityEvent> lifecycle() {
return lifecycleSubject.asObservable();
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycle.bindActivity(lifecycleSubject);
}
@Override
@CallSuper
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleSubject.onNext(ActivityEvent.CREATE);
}
@Override
@CallSuper
protected void onStart() {
super.onStart();
lifecycleSubject.onNext(ActivityEvent.START);
}
@Override
@CallSuper
protected void onResume() {
super.onResume();
lifecycleSubject.onNext(ActivityEvent.RESUME);
}
@Override
@CallSuper
protected void onPause() {
lifecycleSubject.onNext(ActivityEvent.PAUSE);
super.onPause();
}
@Override
@CallSuper
protected void onStop() {
lifecycleSubject.onNext(ActivityEvent.STOP);
super.onStop();
}
@Override
@CallSuper
protected void onDestroy() {
lifecycleSubject.onNext(ActivityEvent.DESTROY);
super.onDestroy();
}
/**
* 封装获取意图参数
*/
protected void getIntentParams() {
Intent intent = getIntent();
initIntentParams(intent);
}
/**
* 初始化意图参数
* @param intent
*/
protected abstract void initIntentParams(Intent intent);
/**
* 初始化控件方法,需实现
* @param savedInstanceState
*/
protected abstract void initViews(Bundle savedInstanceState);
/**
* 初始化数据方法
*/
protected abstract void initData();
// 空白处隐藏软键盘--开始--------------------------------
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
// 获得当前得到焦点的View,一般情况下就是EditText(特殊情况就是轨迹求或者实体案件会移动焦点)
View v = getCurrentFocus();
if (isShouldHideInput(v, ev)) {
hideAndLostFocus(v);
}
}
return super.dispatchTouchEvent(ev);
}
public void hideAndLostFocus(View v) {
hideSoftInput(v.getWindowToken());
//使EditText失去焦点
View parent = (View) v.getParent();
if (parent != null) {
parent.setFocusable(true);
parent.setFocusableInTouchMode(true);
//请求焦点前一定要先设置上面两个方法
parent.requestFocus();
parent.requestFocusFromTouch();
}
}
/**
* 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘,因为当用户点击EditText时没必要隐藏
* @param v
* @param event
* @return
*/
private boolean isShouldHideInput(View v, MotionEvent event) {
if (v != null && (v instanceof EditText)) {
int[] l = {0, 0};
v.getLocationInWindow(l);
int left = l[0], top = l[1], bottom = top + v.getHeight(), right = left
+ v.getWidth();
return !(event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom);
}
// 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditView上,和用户用轨迹球选择其他的焦点
return false;
}
/**
* 多种隐藏软件盘方法的其中一种
* @param token
*/
public void hideSoftInput(IBinder token) {
if (token != null) {
InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
im.hideSoftInputFromWindow(token,
InputMethodManager.HIDE_NOT_ALWAYS);
}
}
// 空白处隐藏软键盘--结束--------------------------------
}
... ...
package com.xdy.commonlibrary.core;
import com.tencent.tinker.loader.app.TinkerApplication;
import com.tencent.tinker.loader.shareutil.ShareConstants;
/**
* @author jianghongbo
* @version 1.0
* @file BaseApplication.java
* @brief 请勿修改此类!
* @date 2017/3/16
* Copyright (c) 2017, 上品折扣
* All rights reserved.
*/
public class BaseApplication extends TinkerApplication {
/**
* 这个方法只提供给组件APPLICATION继承使用,其他人勿用
*/
public BaseApplication() {
super(
//tinkerFlags, tinker支持的类型,dex,library,还是全部都支持!
ShareConstants.TINKER_ENABLE_ALL,
//ApplicationLike的实现类,只能传递字符串,不能使用class.getName()
"com.xdy.commonlibrary.core.CommonAppLike",
//加载Tinker的主类名,对于特殊需求可能需要使用自己的加载类。需要注意的是:
//这个类以及它使用的类都是不能被补丁修改的,并且我们需要将它们加到dex.loader[]中。
//一般来说,我们使用默认即可。
"com.tencent.tinker.loader.TinkerLoader",
//由于合成过程中我们已经校验了各个文件的Md5,并将它们存放在/data/data/..目录中。
// 默认每次加载时我们并不会去校验tinker文件的Md5,但是你也可通过开启loadVerifyFlag强制每次加载时校验,
// 但是这会带来一定的时间损耗。
false);
}
public BaseApplication(int tinkerFlags, String delegateClassName, String loaderClassName, boolean tinkerLoadVerifyFlag) {
super(tinkerFlags, delegateClassName, loaderClassName, tinkerLoadVerifyFlag);
}
@Override
public void onCreate() {
super.onCreate();
}
}
... ...
package com.xdy.commonlibrary.core;
import android.os.Bundle;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import com.trello.rxlifecycle.FragmentEvent;
import com.trello.rxlifecycle.FragmentLifecycleProvider;
import com.trello.rxlifecycle.LifecycleTransformer;
import com.trello.rxlifecycle.RxLifecycle;
import me.yokeyword.fragmentation.SupportFragment;
import rx.Observable;
import rx.subjects.BehaviorSubject;
/**
* @author jianghongbo
* @version 1.0
* @file BaseFragment.java
* @brief 无关业务的Fragment基类
* @date 2017/6/4
* Copyright (c) 2017, 上品折扣[]
* All rights reserved.
*/
public abstract class BaseFragment extends SupportFragment implements FragmentLifecycleProvider {
//! 当前Fragment的TAG标签
protected String TAG= this.getClass().getSimpleName();
@Override
public void onLazyInitView(@Nullable Bundle savedInstanceState) {
super.onLazyInitView(savedInstanceState);
}
private final BehaviorSubject<FragmentEvent> lifecycleSubject = BehaviorSubject.create();
@Override
@NonNull
@CheckResult
public final Observable<FragmentEvent> lifecycle() {
return lifecycleSubject.asObservable();
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull FragmentEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycle.bindFragment(lifecycleSubject);
}
@Override
public void onAttach(android.app.Activity activity) {
super.onAttach(activity);
lifecycleSubject.onNext(FragmentEvent.ATTACH);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleSubject.onNext(FragmentEvent.CREATE);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lifecycleSubject.onNext(FragmentEvent.CREATE_VIEW);
}
@Override
public void onStart() {
super.onStart();
lifecycleSubject.onNext(FragmentEvent.START);
}
@Override
public void onResume() {
super.onResume();
lifecycleSubject.onNext(FragmentEvent.RESUME);
}
@Override
public void onPause() {
lifecycleSubject.onNext(FragmentEvent.PAUSE);
super.onPause();
}
@Override
public void onStop() {
lifecycleSubject.onNext(FragmentEvent.STOP);
super.onStop();
}
@Override
public void onDestroyView() {
lifecycleSubject.onNext(FragmentEvent.DESTROY_VIEW);
super.onDestroyView();
}
@Override
public void onDestroy() {
lifecycleSubject.onNext(FragmentEvent.DESTROY);
super.onDestroy();
}
@Override
public void onDetach() {
lifecycleSubject.onNext(FragmentEvent.DETACH);
super.onDetach();
}
}
... ...
package com.xdy.commonlibrary.core;
import java.lang.ref.WeakReference;
/**
* @author jianghongbo
* @version 1.0
* @file BaseRunnable.java
* @brief runnable简单封装好使用
* @date 2017/12/25
* Copyright (c) 2017,上品折扣
* All rights reserved.
*/
public abstract class BaseRunnable<T> implements Runnable {
WeakReference<T> weakReference;
public BaseRunnable() {
}
public BaseRunnable(T t) {
weakReference = new WeakReference<>(t);
}
@Override
public void run() {
T t = null;
if (weakReference != null && (t = weakReference.get()) != null) {
handle(t);
} else {
handle(null);
}
}
protected abstract void handle(T t);
}
... ...
package com.xdy.commonlibrary.core;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import rx.Subscription;
/**
* Created by jess on 16/5/6.
*/
public abstract class BaseService extends Service {
protected final String TAG = this.getClass().getSimpleName();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
init();
}
@Override
public void onDestroy() {
super.onDestroy();
}
public void unSubscribe(Subscription subscription) {
if (subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();//保证service结束时取消所有正在执行的订阅
}
}
/**
* 初始化
*/
abstract public void init();
}
... ...
package com.xdy.commonlibrary.core;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.text.TextUtils;
import com.tencent.tinker.loader.app.DefaultApplicationLike;
import com.xdy.commonlibrary.BuildConfig;
import com.xdy.commonlibrary.R;
import com.xdy.commonlibrary.api.Api;
import com.xdy.commonlibrary.api.interceptor.BasicParamsInterceptor;
import com.xdy.commonlibrary.core.di.AppComponent;
import com.xdy.commonlibrary.core.di.AppModule;
import com.xdy.commonlibrary.core.di.ClientModule;
import com.xdy.commonlibrary.core.di.DaggerAppComponent;
import com.xdy.commonlibrary.core.di.DaggerBaseComponent;
import com.xdy.commonlibrary.core.di.GlobeConfigModule;
import com.xdy.commonlibrary.core.di.ImageModule;
import com.xdy.commonlibrary.entity.BaseEntity;
import com.xdy.commonlibrary.event.CheckUpgradeEvent;
import com.xdy.commonlibrary.exception.ResultException;
import com.xdy.commonlibrary.mvp.GlobalDialogActivity;
import com.xdy.commonlibrary.permission.DialogText;
import com.xdy.commonlibrary.permission.PermissifyConfig;
import com.xdy.network.CacheModule;
import com.xdy.network.ServiceModule;
import com.xdy.network.http.GlobeHttpHandler;
import com.xdy.util.AppUtil;
import com.xdy.util.LogUtil;
import com.xdy.util.ResUtil;
import com.xdy.util.ToastUtil;
import com.zhy.changeskin.SkinManager;
import org.greenrobot.eventbus.EventBus;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import javax.inject.Inject;
import me.jessyan.rxerrorhandler.handler.listener.ResponseErroListener;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;
/**
* @author jianghongbo
* @version 1.0
* @file AppLike.java
* @brief 不要在这里初始化组件里的任何东西
* @date 2017/12/16
* Copyright (c) 2017
* All rights reserved.
*/
public class CommonAppLike extends DefaultApplicationLike {
private static Boolean isDebug;
private static CommonAppLike appLike;
//单位,小时
private int tinkerUpdateInterval = 3;
private String versionName;
public CommonAppLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag,
long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {
super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
appLike = this;
}
/**
* install multiDex before install tinker
* so we don't need to put the tinker lib classes in the main dex
*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
public void onBaseContextAttached(Context base) {
super.onBaseContextAttached(base);
}
@Override
public void onCreate() {
super.onCreate();
CrashHandler.getInstance().init();
ResUtil.init(getApplication());
LogUtil.init(isDebug());
initPermission();
initDagger();
initSkin();
}
private void initSkin() {
SkinManager.getInstance().init(getApplication());
}
private void initPermission() {
PermissifyConfig permissifyConfig = new PermissifyConfig.Builder()
.withDefaultTextForPermissions(new HashMap<String, DialogText>() {{
put(Manifest.permission_group.STORAGE, new DialogText(R.string.storage_rational, R.string.storage_deny_dialog));
put(Manifest.permission_group.CONTACTS, new DialogText(R.string.contact_rational, R.string.contact_deny_dialog));
put(Manifest.permission_group.PHONE, new DialogText(R.string.phone_rational, R.string.phone_deny_dialog));
put(Manifest.permission_group.SMS, new DialogText(R.string.sms_rational, R.string.sms_deny_dialog));
put(Manifest.permission_group.CAMERA, new DialogText(R.string.camera_rational, R.string.camera_deny_dialog));
put(Manifest.permission_group.LOCATION, new DialogText(R.string.location_rational, R.string.location_deny_dialog));
}})
.build();
PermissifyConfig.initDefault(permissifyConfig);
}
private void initDagger() {
//这块本应该放入到commonLib中,但是Tinker必须继承他的Application
this.mAppModule = new AppModule(getApplication());//提供application
DaggerBaseComponent
.builder()
.appModule(mAppModule)
.build()
.inject(this);
this.mImagerModule = new ImageModule();//图片加载框架默认使用glide
this.mClientModule = new ClientModule(mAppManager);//用于提供okhttp和retrofit的单例
this.mGlobeConfigModule = createGlobeConfigModule();
mAppComponent = DaggerAppComponent
.builder()
.appModule(getAppModule())//baseApplication提供
.clientModule(getClientModule())//baseApplication提供
.imageModule(getImageModule())//baseApplication提供
.globeConfigModule(mGlobeConfigModule)//Retrofit的全局配置,为clientModule提供Retrofit
.serviceModule(new ServiceModule())//需自行创建,可以创建对应的ServiceManager
.cacheModule(new CacheModule())//需自行创建
.build();
}
@Override
public void onTerminate() {
super.onTerminate();
if (mAppComponent != null)
this.mAppComponent = null;
if (mClientModule != null)
this.mClientModule = null;
if (mAppModule != null)
this.mAppModule = null;
if (mImagerModule != null)
this.mImagerModule = null;
if (mAppManager != null) {//释放资源
this.mAppManager.release();
this.mAppManager = null;
}
if (appLike != null)
this.appLike = null;
}
private ClientModule mClientModule;
private AppModule mAppModule;
private ImageModule mImagerModule;
private GlobeConfigModule mGlobeConfigModule;
@Inject
protected AppManager mAppManager;
private static AppComponent mAppComponent;
/**
* 将app的全局配置信息封装进module(使用Dagger注入到需要配置信息的地方)
* @return
*/
private GlobeConfigModule createGlobeConfigModule() {
return GlobeConfigModule
.buidler()
.baseurl(Api.APP_HOST)
.globeHttpHandler(new GlobeHttpHandler() {// 这里可以提供一个全局处理http响应结果的处理类,
// 这里可以比客户端提前一步拿到服务器返回的结果,可以做一些操作,比如token超时,重新获取
@Override
public Response onHttpResultResponse(String httpResult, Interceptor.Chain chain, Response response) {
//这里可以先客户端一步拿到每一次http请求的结果,可以解析成json,做一些操作,如检测到token过期后
//重新请求token,并重新执行请求
// try {
// } catch (JSONException e) {
// e.printStackTrace();
// return response;
// }
//这里如果发现token过期,可以先请求最新的token,然后在拿新的token放入request里去重新请求
//注意在这个回调之前已经调用过proceed,所以这里必须自己去建立网络请求,如使用okhttp使用新的request去请求
// create a new request and modify it accordingly using the new token
// Request newRequest = chain.request().newBuilder().header("token", newToken)
// .build();
// // retry the request
//
// response.body().close();
//如果使用okhttp将新的请求,请求成功后,将返回的response return出去即可
//如果不需要返回新的结果,则直接把response参数返回出去
return response;
}
// 这里可以在请求服务器之前可以拿到request,做一些操作比如给request统一添加token或者header
@Override
public Request onHttpRequestBefore(Interceptor.Chain chain, Request request) {
//如果需要再请求服务器之前做一些操作,则重新返回一个新的requeat如增加header,不做操作则返回request
// RequestBody body = request.body();
// Request.Builder requestBuilder = request.newBuilder();
// if (body != null && body.contentType() != null) {
// HttpUrl.Builder urlBuilder = null;
// //Application/json类型
// if (body.contentType().toString().contains("json")) {
// urlBuilder = postJson(request);
// requestBuilder
// .url(urlBuilder.build());//使用新拼接的url
// }
// }
return request;
}
})
//此公共参数是表单提交时候使用,普通使用ShopinRequestBody封装POST参数,但是get请求暂时没有添加公参
.addInterceptor(createCommonParamIntercept())
// .addInterceptor(new OkHttpMockInterceptor(getContext(), 1))
.responseErroListener(new ResponseErroListener() {
// 用来提供处理所有错误的监听
// rxjava必要要使用ErrorHandleSubscriber(默认实现Subscriber的onError方法),此监听才生效
@Override
public void handleResponseError(Context context, Exception e) {
//所有异常在这里处理
if (e instanceof ResultException) {
String resultCode = ((ResultException) e).getResultCode();
String message = e.getMessage();
if (!TextUtils.isEmpty(message)) {
ToastUtil.showToast(getApplication(), message);
}
LogUtil.e("code:" + resultCode + "msg:" + message);
if (TextUtils.equals(resultCode, BaseEntity.LACK_PARAMS)) {
//缺少必要参数
LogUtil.i(ResUtil.get().getString(R.string.lack_params));
} else if (TextUtils.equals(BaseEntity.INVALID_TOKENID, resultCode)) {
//不合法的TOKEN
Intent intent = new Intent(getContext(), GlobalDialogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(GlobalDialogActivity.INTENT, GlobalDialogActivity.INVALIDATE_TOKEN);
if (!TextUtils.isEmpty(message)) {
intent.putExtra(BaseEntity.ERROR_MESSAGE, message);
}
getContext().startActivity(intent);
} else if (TextUtils.equals(BaseEntity.FORCE_UPGRADE, resultCode)) {
//强制更新 发一个EventBus通知主页和登陆页面,保证有一方会接收到通知。
EventBus.getDefault().post(new CheckUpgradeEvent());
} else if (TextUtils.equals(BaseEntity.FIX_TIME, resultCode)) {
//客制化
Intent intent = new Intent(getContext(), GlobalDialogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(GlobalDialogActivity.INTENT, GlobalDialogActivity.CUSTOM);
if (!TextUtils.isEmpty(message)) {
intent.putExtra(GlobalDialogActivity.CONTENT, message);
}
getContext().startActivity(intent);
}
} else {
LogUtil.e(e.getMessage());
}
}
}).build();
}
public static AppComponent getAppComponent() {
return mAppComponent;
}
public Interceptor createCommonParamIntercept() {
boolean readPhonePermission = false;
// if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_PHONE_STATE)
// == PackageManager.PERMISSION_GRANTED) {
// readPhonePermission = true;
// }
BasicParamsInterceptor interceptor = new BasicParamsInterceptor
.Builder()
.addParam("deviceType", "1")
.addParam("deviceSn", readPhonePermission ? AppUtil.getDeviceId(CommonAppLike.getContext()) : "")
.addParam("appVersion", AppUtil.getVersionName(getContext()))
.addParam("systemVersion", AppUtil.getOSVersion())
.addParam("versionNo", String.valueOf(AppUtil.getVersionCode(getContext())))
.addQueryParam("deviceType", "1")
.addQueryParam("deviceSn", readPhonePermission ? AppUtil.getDeviceId(CommonAppLike.getContext()) : "")
.addQueryParam("appVersion", AppUtil.getVersionName(getContext()))
.addQueryParam("systemVersion", AppUtil.getOSVersion())
.addQueryParam("versionNo", String.valueOf(AppUtil.getVersionCode(getContext())))
.build();
return interceptor;
}
private String bodyToString(RequestBody body) {
String postBodyString = null;
if (body != null) {
try {
Buffer requestbuffer = new Buffer();
body.writeTo(requestbuffer);
if (body.contentType() != null && !body.contentType().toString().contains("multipart")) {
postBodyString = URLDecoder.decode(requestbuffer.readUtf8(), "UTF-8");
}
} catch (IOException e) {
e.printStackTrace();
}
}
return postBodyString;
}
public ClientModule getClientModule() {
return mClientModule;
}
public AppModule getAppModule() {
return mAppModule;
}
public ImageModule getImageModule() {
return mImagerModule;
}
public AppManager getAppManager() {
return mAppManager;
}
public GlobeConfigModule getGlobeConfigModule() {
return mGlobeConfigModule;
}
/**
* 返回上下文
* @return
*/
public static Context getContext() {
return appLike.getApplication();
}
public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback) {
getApplication().registerActivityLifecycleCallbacks(callback);
}
public static CommonAppLike getInstance() {
return appLike;
}
public static boolean isDebug() {
if (isDebug == null) {
try {
final Class<?> activityThread = Class.forName("android.app.ActivityThread");
final Method currentPackage = activityThread.getMethod("currentPackageName");
final String packageName = (String) currentPackage.invoke(null, (Object[]) null);
final Class<?> buildConfig = Class.forName(packageName + ".BuildConfig");
final Field DEBUG = buildConfig.getField("DEBUG");
DEBUG.setAccessible(true);
isDebug = DEBUG.getBoolean(null);
} catch (final Throwable t) {
final String message = t.getMessage();
if (message != null && message.contains("BuildConfig")) {
// Proguard obfuscated build. Most likely a production build.
isDebug = false;
} else {
isDebug = BuildConfig.DEBUG;
}
}
}
return isDebug;
}
}
... ...
package com.xdy.commonlibrary.core;
import com.xdy.util.AppUtil;
import com.xdy.util.LogUtil;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
/**
* UncaughtExceptionHandler:线程未捕获异常控制器是用来处理未捕获异常的。 如果程序出现了未捕获异常默认情况下则会出现强行关闭对话框
* 实现该接口并注册为程序中的默认未捕获异常处理 这样当未捕获异常发生时,就可以做些异常处理操作 例如:收集异常信息,发送错误报告 等。
* <p/>
* UncaughtException处理类,当程序发生Uncaught异常的时候,由该类来接管程序,并记录发送错误报告.
*/
public class CrashHandler extends AbsCrashHandler {
public static final String TAG = "CrashHandler";
private static CrashHandler INSTANCE;
private CrashHandler() {
}
public static CrashHandler getInstance() {
if (CrashHandler.INSTANCE == null) {
CrashHandler.INSTANCE = new CrashHandler();
}
return CrashHandler.INSTANCE;
}
@Override
public void saveCrash(Throwable throwable) {
// String date = DateUtils.getTimeWithSec();
// DbManager instance = DbManager.getInstance(AppLike.getInstance().getApplication());
// CrashExceptionEntity entity = new CrashExceptionEntity();
// entity.setIphoneModel(AppUtil.getMaker());
// entity.setOccurDate(date);
// entity.setUploadFlag(false);
// String title = throwable.toString();
// if (title.length() > 70) {
// title = title.substring(0, 70);
// }
// entity.setModel(title);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
throwable.printStackTrace(new PrintStream(baos));
String errorMessage = baos.toString();
// entity.setMd5Summary(EncryptUtil.MD5Encode(errorMessage, AppConfig.ENCODING));
// entity.setErrorMsg(errorMessage);
// instance.insertOrUpdateData(entity);
LogUtil.e(TAG, errorMessage);
baos.close();
} catch (IOException e) {
e.printStackTrace();
LogUtil.e(TAG, "insert error ex");
} finally {
//杀死我们进程
AppUtil.shutDownApp();
}
}
}
\ No newline at end of file
... ...
package com.xdy.commonlibrary.core;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.xdy.commonlibrary.R;
import com.xdy.ui.viewgroup.MultipleStatusView;
import com.xdy.ui.viewgroup.TitleHeaderBar;
import me.yokeyword.fragmentation.SupportFragment;
/**
* @author Administrator
* @version 1.0
* @file TitleBaseActivity.java
* @brief 带头的ACTIVITY
* @date 2017/6/7
* Copyright (c) 2017
* All rights reserved.
*/
public abstract class TitleBaseActivity<P extends com.xdy.commonlibrary.mvp.BasePresenter> extends com.xdy.commonlibrary.core.AppBaseActivity<P> {
protected TitleHeaderBar mTitleHeaderBar;
protected FrameLayout mContentContainer;
MultipleStatusView mBaseMultiple;
private boolean layoutIsAdded;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public com.xdy.ui.viewgroup.TitleHeaderBar getTitleHeaderBar() {
return (TitleHeaderBar) findViewById(R.id.content_frame_title_header);
}
protected FrameLayout getContentContainer() {
return (FrameLayout) findViewById(R.id.content_view);
}
public com.xdy.ui.viewgroup.MultipleStatusView getMultipleStatusView() {
return (com.xdy.ui.viewgroup.MultipleStatusView) findViewById(R.id.base_multiplestatusview);
}
@Override
protected void initBaseLayout() {
//用基类布局
super.setContentView(R.layout.ui_base_activity_with_title_header);
mTitleHeaderBar = getTitleHeaderBar();
mContentContainer = getContentContainer();
mBaseMultiple = getMultipleStatusView();
if (enableDefaultBack()) {
mTitleHeaderBar.setLeftOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressedSupport();
}
});
} else {
mTitleHeaderBar.getLeftViewContainer().setVisibility(View.INVISIBLE);
}
if (getLayoutId() != 0 && !layoutIsAdded) {
setContentView(getLayoutId());
layoutIsAdded = true;
}
mBaseMultiple.setOnRetryClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (mBaseMultiple.getViewStatus()) {
case com.xdy.ui.viewgroup.MultipleStatusView.STATUS_EMPTY:
case com.xdy.ui.viewgroup.MultipleStatusView.STATUS_ERROR:
case com.xdy.ui.viewgroup.MultipleStatusView.STATUS_NO_NETWORK:
retry();
break;
}
}
});
}
protected boolean enableDefaultBack() {
return true;
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
View view = LayoutInflater.from(this).inflate(layoutResID, null);
view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
setContentView(view);
}
@Override
public void setContentView(View view) {
mContentContainer.addView(view);
}
public void setContentViewSupper(int layoutResID) {
super.setContentView(layoutResID);
}
protected void setHeaderTitle(int id) {
mTitleHeaderBar.getTitleTextView().setText(id);
}
protected void setHeaderTitle(String title) {
mTitleHeaderBar.setTitle(title);
}
/**
* 加载fragment,具体更多方法参考fragmentation
* @param toFragment
*/
public void loadRootFragment(SupportFragment toFragment) {
SupportFragment fragment = findFragment(toFragment.getClass());
if (fragment == null)
super.loadRootFragment(getContentContainer().getId(), toFragment);
}
public void loadMultipleRootFragment(int showPosition, SupportFragment... toFragments) {
super.loadMultipleRootFragment(getContentContainer().getId(), showPosition, toFragments);
}
/**
* 展示空数据Activity
*/
protected void showActEmpty() {
mBaseMultiple.showEmpty();
}
/**
* 展示错误Activity界面
*/
protected void showActError() {
mBaseMultiple.showError();
}
/**
* 展示没有网络状态Activity
*/
protected void showActNoNetwork() {
mBaseMultiple.showNoNetwork();
}
/**
* 展示正常Activity的进度条
*/
protected void showActLoading() {
mBaseMultiple.showLoading();
}
/**
* 展示正常Activity的内容
*/
protected void showActContent() {
mBaseMultiple.showContent();
}
/**
* 出现错误的时候重试点击事件
*/
protected void retry() {
showMessage("重试");
}
}
... ...
package com.xdy.commonlibrary.core.di;
import android.app.Application;
import android.os.Handler;
import com.google.gson.Gson;
import com.xdy.network.CacheModule;
import com.xdy.network.ServiceModule;
import com.xdy.network.cache.CacheManager;
import com.xdy.network.service.ServiceManager;
import com.xdy.commonlibrary.core.AppManager;
import com.xdy.commonlibrary.imageloader.ImageLoader;
import com.xdy.commonlibrary.utils.cache.ICache;
import javax.inject.Singleton;
import dagger.Component;
import me.jessyan.rxerrorhandler.core.RxErrorHandler;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
/**
* Created by jess on 8/4/16.
*/
@Singleton
@Component(modules = {AppModule.class, ClientModule.class, ServiceModule.class, ImageModule.class,
CacheModule.class, GlobeConfigModule.class})
public interface AppComponent {
Application application();
//服务管理器,retrofitApi
ServiceManager serviceManager();
//Retrofit
Retrofit retrofitManager();
//缓存管理器
CacheManager cacheManager();
//Rxjava错误处理管理类
RxErrorHandler rxErrorHandler();
OkHttpClient okHttpClient();
//图片管理器,用于加载图片的管理类,默认使用glide,使用策略模式,可替换框架
ImageLoader imageLoader();
//gson
Gson gson();
//用于管理所有activity
AppManager appManager();
Handler getHandler();
ICache getCacheUtil();
}
... ...
package com.xdy.commonlibrary.core.di;
import android.app.Application;
import android.os.Handler;
import com.google.gson.Gson;
import com.xdy.commonlibrary.utils.cache.ACache;
import com.xdy.commonlibrary.utils.cache.ICache;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
/**
* Created by jess on 8/4/16.
*/
@Module
public class AppModule {
private Application mApplication;
private Handler handler;
public AppModule(Application application) {
this.mApplication = application;
this.handler = new Handler();
}
@Singleton
@Provides
public Application provideApplication() {
return mApplication;
}
@Singleton
@Provides
public Gson provideGson() {
return new Gson();
}
@Singleton
@Provides
public Handler provideHandler() {
return handler;
}
@Singleton
@Provides
public ICache provideCache() {
return ACache.get(mApplication);
}
}
... ...
package com.xdy.commonlibrary.core.di;
import com.xdy.commonlibrary.core.CommonAppLike;
import javax.inject.Singleton;
import dagger.Component;
/**
* Created by jess on 14/12/2017 13:58
* Contact with jess.yan.effort@gmail.com
*/
@Singleton
@Component(modules={AppModule.class})
public interface BaseComponent {
void inject(CommonAppLike application);
}
... ...
package com.xdy.commonlibrary.core.di;
import android.app.Application;
import com.xdy.network.MyCacheSpeak;
import com.xdy.network.WrapGsonDeserializerInfo;
import com.xdy.commonlibrary.api.ShopinGsonConverterFactory;
import com.xdy.commonlibrary.api.interceptor.RequestIntercept;
import com.xdy.commonlibrary.core.AppManager;
import com.xdy.commonlibrary.entity.UserEntity;
import com.xdy.commonlibrary.entity.UserMayBeEmptyStringDeserializer;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import io.rx_cache.internal.RxCache;
import me.jessyan.rxerrorhandler.core.RxErrorHandler;
import me.jessyan.rxerrorhandler.handler.listener.ResponseErroListener;
import okhttp3.Cache;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
/**
* Created by jessyan on 2017/3/14.
*/
@Module
public class ClientModule {
private static final int TIME_OUT = 10;
public static final int HTTP_RESPONSE_DISK_CACHE_MAX_SIZE = 10 * 1024 * 1024;//缓存文件最大值为10Mb
private AppManager mAppManager;
public ClientModule(AppManager appManager) {
this.mAppManager = appManager;
}
/**
* @param builder
* @param client
* @param httpUrl
* @return
* @author: jess
* @date 8/30/16 1:15 PM
* @description:提供retrofit
*/
@Singleton
@Provides
Retrofit provideRetrofit(Retrofit.Builder builder, OkHttpClient client, HttpUrl httpUrl) {
//处理一些有可能反序列化错误的接口
List<WrapGsonDeserializerInfo> deserializerInfos = new ArrayList<>();
WrapGsonDeserializerInfo user = new WrapGsonDeserializerInfo();
user.setClazz(UserEntity.class);
user.setDeserializer(new UserMayBeEmptyStringDeserializer());
deserializerInfos.add(user);
return builder
.baseUrl(httpUrl)//域名
.client(client)//设置okhttp
//使用rxjava
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//使用我们自定义的Gson
.addConverterFactory(ShopinGsonConverterFactory.create(deserializerInfos))
.build();
}
/**
* 提供OkhttpClient
* @param okHttpClient
* @return
*/
@Singleton
@Provides
OkHttpClient provideClient(OkHttpClient.Builder okHttpClient, Cache cache, Interceptor intercept
, List<Interceptor> interceptors) {
OkHttpClient.Builder builder = okHttpClient
.connectTimeout(TIME_OUT, TimeUnit.SECONDS)
.readTimeout(TIME_OUT, TimeUnit.SECONDS)
.cache(cache)//设置缓存
.addNetworkInterceptor(intercept);
if (interceptors != null && interceptors.size() > 0) {//如果外部提供了interceptor的数组则遍历添加
for (Interceptor interceptor : interceptors) {
builder.addInterceptor(interceptor);
}
}
return builder
.build();
}
@Singleton
@Provides
Retrofit.Builder provideRetrofitBuilder() {
return new Retrofit.Builder();
}
@Singleton
@Provides
OkHttpClient.Builder provideClientBuilder() {
return new OkHttpClient.Builder();
}
@Singleton
@Provides
Cache provideCache(File cacheFile) {
return new Cache(cacheFile, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE);//设置缓存路径和大小
}
@Singleton
@Provides
Interceptor provideIntercept(RequestIntercept intercept) {
return intercept;//打印请求信息的拦截器
}
/**
* 提供RXCache客户端
* @param cacheDir 缓存路径
* @return
*/
@Singleton
@Provides
RxCache provideRxCache(File cacheDir) {
return new RxCache
.Builder()
.persistence(cacheDir, new MyCacheSpeak());
}
/**
* 提供处理Rxjava错误的管理器
* @return
*/
@Singleton
@Provides
RxErrorHandler proRxErrorHandler(Application application, ResponseErroListener listener) {
return RxErrorHandler
.builder()
.with(application)
.responseErroListener(listener)
.build();
}
//
// /**
// * 提供权限管理类,用于请求权限,适配6.0的权限管理
// *
// * @param application
// * @return
// */
// @Singleton
// @Provides
// RxPermissions provideRxPermissions(Application application) {
// return RxPermissions.getInstance(application);
// }
/**
* 提供管理所有activity的管理类
* @return
*/
@Singleton
@Provides
AppManager provideAppManager() {
return mAppManager;
}
// .addNetworkInterceptor(new Interceptor() {
// @Override
// public Response intercept(Interceptor.Chain chain) throws IOException {
// Request request = chain.request();
// if(!DeviceUtils.netIsConnected(UiUtils.getContext())){
// request = request.newBuilder()
// .cacheControl(CacheControl.FORCE_CACHE)
// .build();
// LogUtils.warnInfo("http","no network");
// }
// Response originalResponse = chain.proceed(request);
// if(DeviceUtils.netIsConnected(UiUtils.getContext())){
// //有网的时候读接口上的@Headers里的配置,你可以在这里进行统一的设置
// String cacheControl = request.cacheControl().toString();
// return originalResponse.newBuilder()
// .header("Cache-Control", cacheControl)
// .removeHeader("Pragma")
// .build();
// }else{
// return originalResponse.newBuilder()
// .header("Cache-Control", "public, only-if-cached, max-stale=2419200")
// .removeHeader("Pragma")
// .build();
// }
// }
// })
}
... ...
package com.xdy.commonlibrary.core.di;
import android.app.Application;
import android.text.TextUtils;
import com.xdy.network.http.GlobeHttpHandler;
import com.xdy.util.DataHelper;
import com.xdy.util.Preconditions;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import me.jessyan.rxerrorhandler.handler.listener.ResponseErroListener;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
/**
* Created by jessyan on 2017/3/14.
*/
@Module
public class GlobeConfigModule {
private HttpUrl mApiUrl;
private GlobeHttpHandler mHandler;
private List<Interceptor> mInterceptors;
private ResponseErroListener mErroListener;
private File mCacheFile;
public void setUrl(HttpUrl mApiUrl) {
this.mApiUrl = mApiUrl;
}
/**
* @author: jess
* @date 8/5/16 11:03 AM
* @description: 设置baseurl
*/
private GlobeConfigModule(Buidler buidler) {
this.mApiUrl = buidler.apiUrl;
this.mHandler = buidler.handler;
this.mInterceptors = buidler.interceptors;
this.mErroListener = buidler.responseErroListener;
this.mCacheFile = buidler.cacheFile;
}
public static Buidler buidler() {
return new Buidler();
}
@Singleton
@Provides
List<Interceptor> provideInterceptors() {
return mInterceptors;
}
@Singleton
@Provides
HttpUrl provideBaseUrl() {
return mApiUrl;
}
@Singleton
@Provides
GlobeHttpHandler provideGlobeHttpHandler() {
return mHandler == null ? GlobeHttpHandler.EMPTY : mHandler;//打印请求信息
}
/**
* 提供缓存地址
*/
@Singleton
@Provides
File provideCacheFile(Application application) {
return mCacheFile == null ? DataHelper.getCacheFile(application) : mCacheFile;
}
/**
* 提供处理Rxjava错误的管理器的回调
* @return
*/
@Singleton
@Provides
ResponseErroListener provideResponseErroListener() {
return mErroListener == null ? ResponseErroListener.EMPTY : mErroListener;
}
public static final class Buidler {
private HttpUrl apiUrl = HttpUrl.parse("https://api.github.com/");
private GlobeHttpHandler handler;
private List<Interceptor> interceptors = new ArrayList<>();
private ResponseErroListener responseErroListener;
private File cacheFile;
private Buidler() {
}
public Buidler baseurl(String baseurl) {//基础url
if (TextUtils.isEmpty(baseurl)) {
throw new IllegalArgumentException("baseurl can not be empty");
}
this.apiUrl = HttpUrl.parse(baseurl);
return this;
}
public Buidler globeHttpHandler(GlobeHttpHandler handler) {//用来处理http响应结果
this.handler = handler;
return this;
}
public Buidler addInterceptor(Interceptor interceptor) {//动态添加任意个interceptor
this.interceptors.add(interceptor);
return this;
}
public Buidler responseErroListener(ResponseErroListener listener) {//处理所有Rxjava的onError逻辑
this.responseErroListener = listener;
return this;
}
public Buidler cacheFile(File cacheFile) {
this.cacheFile = cacheFile;
return this;
}
public GlobeConfigModule build() {
Preconditions.checkNotNull(apiUrl, "baseurl is required");
return new GlobeConfigModule(this);
}
}
}
... ...
package com.xdy.commonlibrary.core.di;
import com.xdy.commonlibrary.imageloader.BaseImageLoaderStrategy;
import com.xdy.commonlibrary.imageloader.glide.GlideImageLoaderStrategy;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
/**
* Created by jess on 8/5/16 16:10
* contact with jess.yan.effort@gmail.com
*/
@Module
public class ImageModule {
@Singleton
@Provides
public BaseImageLoaderStrategy provideImageLoaderStrategy(GlideImageLoaderStrategy glideImageLoaderStrategy) {
return glideImageLoaderStrategy;
}
}
... ...
/**
* Copyright (C) 2017 Fernando Cejas Open Source Project
*
* 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.xdy.commonlibrary.di.scope;
import java.lang.annotation.Retention;
import javax.inject.Scope;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* A scoping annotation to permit objects whose lifetime should
* conform to the life of the activity to be memorized in the
* correct component.
*/
@Scope
@Retention(RUNTIME)
public @interface ActivityScope {}
... ...
/**
* Copyright (C) 2017 Fernando Cejas Open Source Project
*
* 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.xdy.commonlibrary.di.scope;
import java.lang.annotation.Retention;
import javax.inject.Scope;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* A scoping annotation to permit objects whose lifetime should
* conform to the life of the activity to be memorized in the
* correct component.
*/
@Scope
@Retention(RUNTIME)
public @interface FragmentScope {}
... ...
package com.xdy.commonlibrary.entity;
/**
* @author 蒋洪波
* @file BaseBean.java
* @brief 新接口实体封装对象的基类
* @date 2017/1/8
* Copyright (c) 2017
* All rights reserved.
*/
public class BaseEntity<T> {
//结果是否正常
public boolean success;
//返回码
public String code;
//返回信息
public String errorMessage;
//具体数据类型
public T data;
//强制更新标记
public static String FORCE_UPGRADE = "128";
//! 不合法token 标记
public static String INVALID_TOKENID = "004";
//! 停机维护时间
public static String FIX_TIME = "006";
//! 服务器返回 JSON结果正确标记
public static boolean RESULT_OK = true;
public static String CODE_RESULT_OK = "A00000";
//! JSON结果不正确标记
public static boolean RESULT_ERROR = false;
//! 缺少必要参数
public static String LACK_PARAMS = "003";
//! 服务器返回错误信息字段
public static String ERROR_MESSAGE = "errorMessage";
//! 服务器返回的code字段
public static String CODE = "code";
//网络请求的TOKEN KEY
public static String TOKEN = "tokenId";
}
... ...
package com.xdy.commonlibrary.entity;
/**
* @author jianghongbo
* @version 1.0
* @file CrashExceptionEntity.java
* @brief 崩溃异常的实体
* @date 2017/12/19
* Copyright (c) 2017
* All rights reserved.
*/
//@Entity(
// // Whether getters and setters for properties should be generated if missing.
// generateGettersSetters = true)
public class CrashExceptionEntity {
//主键
// @NotNull
// @Unique
// @Id
// private String md5Summary;
// @NotNull
// private String iphoneModel;
// @NotNull
// private String model;
// @NotNull
// private String errorMsg;
// private String occurDate;
// private Boolean uploadFlag;
// private String ReservedField1;
// private String ReservedField2;
// private String ReservedField3;
//
//
// @Generated(hash = 1266713787)
// public CrashExceptionEntity(@NotNull String md5Summary, @NotNull String iphoneModel,
// @NotNull String model, @NotNull String errorMsg, String occurDate,
// Boolean uploadFlag, String ReservedField1, String ReservedField2,
// String ReservedField3) {
// this.md5Summary = md5Summary;
// this.iphoneModel = iphoneModel;
// this.model = model;
// this.errorMsg = errorMsg;
// this.occurDate = occurDate;
// this.uploadFlag = uploadFlag;
// this.ReservedField1 = ReservedField1;
// this.ReservedField2 = ReservedField2;
// this.ReservedField3 = ReservedField3;
// }
//
// @Generated(hash = 1937612897)
// public CrashExceptionEntity() {
// }
//
//
// public String getMd5Summary() {
// return md5Summary;
// }
//
// public void setMd5Summary(String md5Summary) {
// this.md5Summary = md5Summary;
// }
//
// public String getIphoneModel() {
// return iphoneModel;
// }
//
// public void setIphoneModel(String iphoneModel) {
// this.iphoneModel = iphoneModel;
// }
//
// public String getModel() {
// return model;
// }
//
// public void setModel(String model) {
// this.model = model;
// }
//
// public String getErrorMsg() {
// return errorMsg;
// }
//
// public void setErrorMsg(String errorMsg) {
// this.errorMsg = errorMsg;
// }
//
// public String getOccurDate() {
// return occurDate;
// }
//
// public void setOccurDate(String occurDate) {
// this.occurDate = occurDate;
// }
//
// public Boolean getUploadFlag() {
// return uploadFlag;
// }
//
// public void setUploadFlag(Boolean uploadFlag) {
// this.uploadFlag = uploadFlag;
// }
//
// public String getReservedField1() {
// return ReservedField1;
// }
//
// public void setReservedField1(String reservedField1) {
// ReservedField1 = reservedField1;
// }
//
// public String getReservedField2() {
// return ReservedField2;
// }
//
// public void setReservedField2(String reservedField2) {
// ReservedField2 = reservedField2;
// }
//
// public String getReservedField3() {
// return ReservedField3;
// }
//
// public void setReservedField3(String reservedField3) {
// ReservedField3 = reservedField3;
// }
}
... ...
package com.xdy.commonlibrary.entity;
/**
* @author 蒋洪波
* @file ResultEntity.java
* @brief 检查数据是否正常
* @date 2017/1/8
* Copyright (c) 2017
* All rights reserved.
*/
public class ResultEntity{
//返回码
public String code;
//返回信息
public String errorMessage;
//是否解析成功标识
public boolean isSuccess;
}
... ...
package com.xdy.commonlibrary.entity;
/**
* @author Administrator
* @version 1.0
* @file UserEntity.java
* @brief 用户实体类
* @date 2017/1/8
* Copyright (c) 2017
* All rights reserved.
*/
public class UserEntity implements Cloneable {
@Override
public Object clone() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
//用户头像,暂时没有
public String userPic; // //暂时没有返回
//用户会员等级 1:v1会员,2:v2会员,3:v3会员
public String mType;
//用户积分
public long nowPoint;
public String memberSid;//用户id
public String answer;
public String nickName;
public String question;
public String realName;
public String registFrom;
public String registTime;
public String sid;
public String idCard;
public String profession;
public String memberAddress;
public String completeDate;
public String income;
public String birthdate;
public String gender;
public String optUid;
public String ipAddress;
public String mobile;
public String getMemberSid() {
return memberSid;
}
public void setMemberSid(String memberSid) {
this.memberSid = memberSid;
}
public String getUserPic() {
return userPic;
}
public void setUserPic(String userPic) {
this.userPic = userPic;
}
public String getmType() {
return mType;
}
public void setmType(String mType) {
this.mType = mType;
}
public long getNowPoint() {
return nowPoint;
}
public void setNowPoint(long nowPoint) {
this.nowPoint = nowPoint;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
public String getRegistFrom() {
return registFrom;
}
public void setRegistFrom(String registFrom) {
this.registFrom = registFrom;
}
public String getRegistTime() {
return registTime;
}
public void setRegistTime(String registTime) {
this.registTime = registTime;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public String getMemberAddress() {
return memberAddress;
}
public void setMemberAddress(String memberAddress) {
this.memberAddress = memberAddress;
}
public String getCompleteDate() {
return completeDate;
}
public void setCompleteDate(String completeDate) {
this.completeDate = completeDate;
}
public String getIncome() {
return income;
}
public void setIncome(String income) {
this.income = income;
}
public String getBirthdate() {
return birthdate;
}
public void setBirthdate(String birthdate) {
this.birthdate = birthdate;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getOptUid() {
return optUid;
}
public void setOptUid(String optUid) {
this.optUid = optUid;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
}
... ...
package com.xdy.commonlibrary.entity;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.lang.reflect.Type;
/**
* @author 蒋洪波
* @version 2.0
* @file ReplenishDeserializer.java
* @brief 补货商品反序列化对象,样板对象有可能为空
* @date 2017/1/8
* Copyright (c) 2017, 商品折扣
* All rights reserved.
*/
public class UserMayBeEmptyStringDeserializer implements JsonDeserializer<UserEntity> {
@Override
public UserEntity deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
UserEntity defValue = null;
try {
if (json.isJsonObject()) {
JsonObject jsonObject = json.getAsJsonObject();
JsonElement memberSid = jsonObject.get("memberSid");
JsonElement answer = jsonObject.get("answer");
JsonElement nickName = jsonObject.get("nickName");
JsonElement question = jsonObject.get("question");
JsonElement realName = jsonObject.get("realName");
JsonElement registFrom = jsonObject.get("registFrom");
JsonElement registTime = jsonObject.get("registTime");
JsonElement sid = jsonObject.get("sid");
JsonElement idCard = jsonObject.get("idCard");
JsonElement profession = jsonObject.get("profession");
JsonElement memberAddress = jsonObject.get("memberAddress");
JsonElement completeDate = jsonObject.get("completeDate");
JsonElement income = jsonObject.get("income");
JsonElement birthdate = jsonObject.get("birthdate");
JsonElement gender = jsonObject.get("gender");
JsonElement optUid = jsonObject.get("optUid");
JsonElement ipAddress = jsonObject.get("ipAddress");
JsonElement mobile = jsonObject.get("mobile");
JsonElement userPic = jsonObject.get("userPic");
JsonElement mType = jsonObject.get("mType");
long nowPoint = jsonObject.get("nowPoints").getAsLong();
defValue = new UserEntity();
if (userPic != null && !userPic.isJsonNull()) {
defValue.userPic = userPic.getAsString();
}
if (mType != null && !mType.isJsonNull()) {
defValue.mType = mType.getAsString();
}
if (String.valueOf(nowPoint) != null ) {
defValue.setNowPoint(nowPoint);
}
if (memberSid != null&& !memberSid.isJsonNull()) {
defValue.setMemberSid(memberSid.getAsString());
}
if (answer != null && !answer.isJsonNull()) {
defValue.answer = answer.getAsString();
}
if (nickName != null && !nickName.isJsonNull()) {
defValue.nickName = nickName.getAsString();
}
if (question != null&& !question.isJsonNull()) {
defValue.question = question.getAsString();
}
if (realName != null && !realName.isJsonNull()) {
defValue.realName = realName.getAsString();
}
if (registFrom != null && !registFrom.isJsonNull()) {
defValue.registFrom = registFrom.getAsString();
}
if (registTime != null && !registTime.isJsonNull()) {
defValue.registTime = registTime.getAsString();
}
if (sid != null && !sid.isJsonNull()) {
defValue.sid = sid.getAsString();
}
if (idCard != null && !idCard.isJsonNull()) {
defValue.idCard = idCard.getAsString();
}
if (profession != null && !profession.isJsonNull()) {
defValue.profession = profession.getAsString();
}
if (memberAddress != null && !memberAddress.isJsonNull()) {
defValue.memberAddress = memberAddress.getAsString();
}
if (completeDate != null && !completeDate.isJsonNull()) {
defValue.completeDate = completeDate.getAsString();
}
if (income != null && !income.isJsonNull()) {
defValue.income = income.getAsString();
}
if (birthdate != null && !birthdate.isJsonNull()) {
defValue.birthdate = birthdate.getAsString();
}
if (gender != null && !gender.isJsonNull()) {
defValue.gender = gender.getAsString();
}
if (optUid != null && !optUid.isJsonNull()) {
defValue.optUid = optUid.getAsString();
}
if (ipAddress != null && !ipAddress.isJsonNull()) {
defValue.ipAddress = ipAddress.getAsString();
}
if (mobile != null && !mobile.isJsonNull()) {
defValue.mobile = mobile.getAsString();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return defValue;
}
}
... ...
package com.xdy.commonlibrary.event;
/**
* @author 蒋洪波
* @version 3.0
* @file CheckUpgradeEvent.java
* @brief 检查更新事件
* @date 2017/3/19
* Copyright (c) 2017, 上品折扣[]
* All rights reserved.
*/
public class CheckUpgradeEvent {
public CheckUpgradeEvent() {
}
}
... ...
package com.xdy.commonlibrary.exception;
/**
* @author jianghongbo
* @version 1.0
* @file ResultException.java
* @brief 服务器返回结果异常
* @date 2017/12/21
* Copyright (c) 2017, 上品折扣[]
* All rights reserved.
*/
public class ResultException extends RuntimeException {
private String resultCode;
private String errorMessage;
public ResultException(String message) {
super(message);
}
public String getResultCode() {
return resultCode;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
... ...
package com.xdy.commonlibrary.imageloader;
import android.content.Context;
/**
* Created by jess on 8/5/16 15:50
* contact with jess.yan.effort@gmail.com
*/
public interface BaseImageLoaderStrategy<T extends ImageConfig> {
void loadImage(Context ctx, T config);
}
... ...
package com.xdy.commonlibrary.imageloader;
import android.widget.ImageView;
/**
* Created by jess on 8/5/16 15:19
* contact with jess.yan.effort@gmail.com
* 这里是图片加载配置信息的基类,可以定义一些所有图片加载框架都可以用的通用参数
*/
public class ImageConfig {
protected String url;
protected ImageView imageView;
protected int placeholder;
protected int errorPic;
public String getUrl() {
return url;
}
public ImageView getImageView() {
return imageView;
}
public int getPlaceholder() {
return placeholder;
}
public int getErrorPic() {
return errorPic;
}
}
... ...
package com.xdy.commonlibrary.imageloader;
import android.content.Context;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Created by jess on 8/5/16 15:57
* contact with jess.yan.effort@gmail.com
*/
@Singleton
public class ImageLoader {
private BaseImageLoaderStrategy mStrategy;
@Inject
public ImageLoader(BaseImageLoaderStrategy strategy) {
setLoadImgStrategy(strategy);
}
public <T extends ImageConfig> void loadImage(Context context, T config) {
this.mStrategy.loadImage(context, config);
}
public void setLoadImgStrategy(BaseImageLoaderStrategy strategy) {
this.mStrategy = strategy;
}
}
... ...
package com.xdy.commonlibrary.imageloader.glide;
import android.content.Context;
import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool;
import com.bumptech.glide.load.engine.cache.DiskCache;
import com.bumptech.glide.load.engine.cache.DiskLruCacheWrapper;
import com.bumptech.glide.load.engine.cache.LruResourceCache;
import com.bumptech.glide.load.engine.cache.MemorySizeCalculator;
import com.bumptech.glide.module.GlideModule;
import com.xdy.util.DataHelper;
import com.xdy.commonlibrary.core.CommonAppLike;
/**
* Created by jess on 16/4/15.
*/
public class GlideConfiguration implements GlideModule {
public static final int IMAGE_DISK_CACHE_MAX_SIZE = 100 * 1024 * 1024;//图片缓存文件最大值为100Mb
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDiskCache(new DiskCache.Factory() {
@Override
public DiskCache build() {
// Careful: the external cache directory doesn't enforce permissions
return DiskLruCacheWrapper.get(DataHelper.getCacheFile(CommonAppLike.getContext()), IMAGE_DISK_CACHE_MAX_SIZE);
}
});
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize));
builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize));
}
@Override
public void registerComponents(Context context, Glide glide) {
}
}
... ...
package com.xdy.commonlibrary.imageloader.glide;
import android.widget.ImageView;
import com.bumptech.glide.load.Transformation;
import com.xdy.commonlibrary.imageloader.ImageConfig;
/**
* Created by jess on 8/5/16 15:19
* contact with jess.yan.effort@gmail.com
* 这里放Glide专属的配置信息,可以一直扩展字段,如果外部调用时想让图片加载框架
* 做一些操作,比如清除或则切换缓存策略,则可以定义一个int类型的变量,内部根据int做不同过的操作
* 其他操作同理
*/
public class GlideImageConfig extends ImageConfig {
private int cacheStrategy;//0对应DiskCacheStrategy.all,1对应DiskCacheStrategy.NONE,2对应DiskCacheStrategy.SOURCE,3对应DiskCacheStrategy.RESULT
private Transformation transformation;//glide用它来改变图形的形状
private GlideImageConfig(Buidler builder) {
this.url = builder.url;
this.imageView = builder.imageView;
this.placeholder = builder.placeholder;
this.errorPic = builder.errorPic;
this.cacheStrategy = builder.cacheStrategy;
this.transformation = builder.transformation;
}
public int getCacheStrategy() {
return cacheStrategy;
}
public Transformation getTransformation() {
return transformation;
}
public static Buidler builder() {
return new Buidler();
}
public static final class Buidler {
private String url;
private ImageView imageView;
private int placeholder;
private int errorPic;
private int cacheStrategy;//0对应DiskCacheStrategy.all,1对应DiskCacheStrategy.NONE,2对应DiskCacheStrategy.SOURCE,3对应DiskCacheStrategy.RESULT
private Transformation transformation;//glide用它来改变图形的形状
private Buidler() {
}
public Buidler url(String url) {
this.url = url;
return this;
}
public Buidler placeholder(int placeholder) {
this.placeholder = placeholder;
return this;
}
public Buidler errorPic(int errorPic){
this.errorPic = errorPic;
return this;
}
public Buidler imagerView(ImageView imageView) {
this.imageView = imageView;
return this;
}
public Buidler cacheStrategy(int cacheStrategy) {
this.cacheStrategy = cacheStrategy;
return this;
}
public Buidler transformation(Transformation transformation) {
this.transformation = transformation;
return this;
}
public GlideImageConfig build() {
if (url == null) throw new IllegalStateException("url is required");
if (imageView == null) throw new IllegalStateException("imageview is required");
return new GlideImageConfig(this);
}
}
}
... ...
package com.xdy.commonlibrary.imageloader.glide;
import android.app.Activity;
import android.content.Context;
import com.bumptech.glide.DrawableRequestBuilder;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.xdy.commonlibrary.imageloader.BaseImageLoaderStrategy;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Created by jess on 8/5/16 16:28
* contact with jess.yan.effort@gmail.com
*/
@Singleton
public class GlideImageLoaderStrategy implements BaseImageLoaderStrategy<GlideImageConfig> {
@Inject
public GlideImageLoaderStrategy() {
}
@Override
public void loadImage(Context ctx, GlideImageConfig config) {
RequestManager manager;
if (ctx instanceof Activity)//如果是activity则可以使用Activity的生命周期
manager = Glide.with((Activity) ctx);
else
manager = Glide.with(ctx);
DrawableRequestBuilder<String> requestBuilder = manager.load(config.getUrl())
.crossFade()
.centerCrop();
switch (config.getCacheStrategy()) {//缓存策略
case 0:
requestBuilder.diskCacheStrategy(DiskCacheStrategy.ALL);
break;
case 1:
requestBuilder.diskCacheStrategy(DiskCacheStrategy.NONE);
break;
case 2:
requestBuilder.diskCacheStrategy(DiskCacheStrategy.SOURCE);
break;
case 3:
requestBuilder.diskCacheStrategy(DiskCacheStrategy.RESULT);
break;
}
if (config.getTransformation() != null) {//glide用它来改变图形的形状
requestBuilder.transform(config.getTransformation());
}
if (config.getPlaceholder() != 0)//设置占位符
requestBuilder.placeholder(config.getPlaceholder());
if (config.getErrorPic() != 0)//设置错误的图片
requestBuilder.error(config.getErrorPic());
requestBuilder
.into(config.getImageView());
}
}
... ...
package com.xdy.commonlibrary.mvp;
import com.xdy.network.http.BaseCacheManager;
import com.xdy.network.http.BaseServiceManager;
/**
* Created by jess on 8/5/16 12:55
* contact with jess.yan.effort@gmail.com
*/
public class BaseModel<S extends BaseServiceManager, C extends BaseCacheManager> implements IModel{
protected S mServiceManager;//服务管理类,用于网络请求
protected C mCacheManager;//缓存管理类,用于管理本地或者内存缓存
public BaseModel(S serviceManager, C cacheManager) {
this.mServiceManager = serviceManager;
this.mCacheManager = cacheManager;
}
@Override
public void onDestory() {
if (mServiceManager != null) {
mServiceManager = null;
}
if (mCacheManager != null) {
mCacheManager = null;
}
}
}
... ...