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