一 . 前言
我个人认为一个好的项目离不开一个好的框架。
二 . 用到的知识点
1.rxjava2
2.retrofit2
3.rxlifecycle2
4.mvp
5.eventBus
6.glide
7.屏幕适配
BaseActivity如下:
public abstract class BaseActivity extends RxFragmentActivity implements RxPermissionHelper.PermissionCallbacks, IView {
protected Unbinder unBinder;//butterknife 绑定控件
/**
* 获取布局Id
*
* @return
*/
protected abstract int getContentViewId();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ScreenAdaptation.setCustomDensity(this, getApplication());//修改屏幕密度
setContentView(getContentViewId());
unBinder = ButterKnife.bind(this);//butterKnife绑定view
if (useEventBus()) {
EventBus.getDefault().register(this);//注册eventBus
}
}
/**
* 初始化view
*/
protected abstract void initView();
/**
* 初始化数据
*/
protected abstract void initData();
/**
* 是否使用eventBus
*
* @return
*/
protected boolean useEventBus() {
return false;
}
/**
* 动态申请权限成功回调
*/
@Override
public void onPermissionsGranted() {
}
/**
* 动态申请权限失败回调
*/
@Override
public void onPermissionsDenied() {
}
@Override
public void showLoading() {
}
@Override
public void hideLoading() {
}
/**
* bind rxlifecycle
*
* @return
*/
@Override
public <T> LifecycleTransformer<T> bindLifecycle() {
return this.bindUntilEvent(ActivityEvent.PAUSE);
}
@Override
protected void onDestroy() {
if (unBinder != null) {
unBinder.unbind();//butterKnife解绑view
}
if (useEventBus()) {
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this);//注销eventBus
}
}
CustomToast.INSTANCE.cancelToast();//销毁 自定义toast
super.onDestroy();
MyApplication.getRefWatcher(this).watch(this);//内存泄漏检测
}
/**
* 统一封装toast
*
* @param text
*/
protected void showToast(String text) {
CustomToast.INSTANCE.showToast(this, text);
}
}
RxService代码如下:
public enum RxService {
RETROFIT;
private Retrofit mRetrofit;
private static final int READ_TIMEOUT = 60;//读取超时时间,单位秒
private static final int CONN_TIMEOUT = 50;//连接超时时间,单位秒
/**
* 初始化一个client,不然retrofit会自己默认添加一个
*/
private static OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
builder.addHeader("Content-Type", "application/json");
return chain.proceed(builder.build());
}
})
.connectTimeout(CONN_TIMEOUT, TimeUnit.SECONDS)//设置连接时间为50s
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)//设置读取时间为一分钟
.build();
/**
* @description 创建Retrofit对象
* @author ydc
* @createDate
* @version 1.0
*/
public Retrofit createRetrofit() {
if (mRetrofit == null) {
mRetrofit = new Retrofit.Builder()
.client(httpClient)
.baseUrl(APIConstant.BASE_PATH) //api base path
.addConverterFactory(GsonConverterFactory.create())//返回值为Gson的支持(以实体类返回)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//返回值为Oservable<T>的支持
.build();
}
return mRetrofit;
}
/**
* @description 返回服务接口对象实例
* @author ydc
* @createDate
* @version 1.0
*/
public <T> T createService(final Class<T> service) {
validateServiceInterface(service);//校验接口合法性
return RxService.RETROFIT.createRetrofit().create(service);
}
/**
* @description 校验接口合法性
* @author ydc
* @createDate
public abstract class APICallBack<M> implements Observer<M> {
private static final String TAG = APICallBack.class.getSimpleName();
public abstract void onStart(@NonNull Disposable d);
public abstract void onSuccess(M modelBean);
public abstract void onFailure(String errorMsg);
public abstract void onFinished();
@Override
public void onSubscribe(@NonNull Disposable d) {
onStart(d);
}
@Override
public void onNext(@NonNull M modelBean) {
Logger.d(TAG, modelBean.toString());
BaseResponse<M> response = (BaseResponse<M>) modelBean;
if ("200".equals(response.getCode())) {
onSuccess(modelBean);
} else {
onFailure(response.getMessage());
}
}
@Override
public void onError(@NonNull Throwable e) {
e.printStackTrace();
if (e instanceof HttpException) {
HttpException httpException = (HttpException) e;
int exceptionCode = httpException.code();
String msg = httpException.getMessage();
if (exceptionCode == 401) {
msg = "用户名密码错误,请重新登录!";
}
if (exceptionCode == 403 || exceptionCode == 404 || exceptionCode == 407 || exceptionCode == 408) {
msg = "网络链接超时,请稍后再试!";
}
if (exceptionCode == 501 || exceptionCode == 502 || exceptionCode == 504) {
msg = "服务器无响应,请稍后再试!";
}
onFailure(msg);
} else {
onFailure(e.getMessage());
}
onFinished();
}
@Override
public void onComplete() {
onFinished();
}
}
* @version 1.0 */ public <T> void validateServiceInterface(Class<T> service) { if (service == null) { //Toast.ShowToast("服务接口不能为空!"); } if (!service.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces."); } if (service.getInterfaces().length > 0) { throw new IllegalArgumentException("API interfaces must not extend other interfaces."); } }}
presenter 网络请求:
mLoginModel.getUserInfo()
.compose(RxTransformer.<BaseResponse<UserInfo>>transformer(getMvpView()))
.subscribe(new APICallBack<BaseResponse<UserInfo>>() {
@Override
public void onStart(@NonNull Disposable d) {
}
@Override
public void onSuccess(BaseResponse<UserInfo> modelBean) {
getMvpView().getUserInfoSuccess();
Logger.d(TAG, modelBean.getContent() + "");
}
@Override
public void onFailure(String errorMsg) {
getMvpView().getUserInfoFailure();
}
@Override
public void onFinished() {
getMvpView().hideLoading();
}
});
}
最近更新了一个今日头条的屏幕适配方法 今日头条
适配代码是写在BaseActivity内
/**
* 通过修改density值,强行把所有不同尺寸分辨率的手机的宽度dp值改成一个统一的值,这样就解决了所有的适配问题
*
* @param activity
* @param application
*/
public static void setCustomDensity(@NonNull Activity activity, @NonNull final Application application) {
DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
if (sNoncompatDensity == 0) {
sNoncompatDensity = appDisplayMetrics.density;
sNoncompatScaledDensity = appDisplayMetrics.scaledDensity;
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig != null && newConfig.fontScale > 0) {
sNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
}
// float targetDensity=appDisplayMetrics.widthPixels/360;
float targetDensity = (float) appDisplayMetrics.widthPixels / 360;
float targetScaleDensity = targetDensity * (sNoncompatScaledDensity / sNoncompatDensity);
int targetDensityDpi = (int) (160 * targetDensity);
appDisplayMetrics.density = targetDensity;
appDisplayMetrics.scaledDensity = targetScaleDensity;
appDisplayMetrics.densityDpi = targetDensityDpi;
final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
activityDisplayMetrics.density = targetDensity;
activityDisplayMetrics.scaledDensity = targetScaleDensity;
activityDisplayMetrics.densityDpi = targetDensityDpi;
}
实在不怎么会写文章,源码代码传送门
喜欢或不喜欢都请star一下,感谢