Commit 60be48b9 by 罗翻

增加provider

parent 00356c56
Showing with 3939 additions and 0 deletions
apply plugin: 'com.android.library'
android {
compileSdkVersion compile_sdk_version
buildToolsVersion build_tools_version
defaultConfig {
minSdkVersion min_sdk_version
targetSdkVersion target_sdk_version
versionCode version_code
versionName verson_name
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
dataBinding {
enabled = true
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:design:26.1.0'
//mutidex
compile 'com.android.support:multidex:1.0.2'
//eventBus
compile 'org.greenrobot:eventbus:3.1.1'
//retrofit
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
//图片选择
compile 'com.github.LuckSiege.PictureSelector:picture_library:v2.1.5'
//ARouter
compile "com.alibaba:arouter-api:$arouter_api_version"
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\AndroidSDK/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
package com.dayu.baselibrary;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.dayu.baselibrary.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dayu.baselibrary">
</manifest>
package com.dayu.base.api;
import android.net.ParseException;
import com.dayu.baselibrary.R;
import com.dayu.common.BaseApplication;
import com.google.gson.JsonParseException;
import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;
import java.net.ConnectException;
import retrofit2.HttpException;
import static com.dayu.base.api.APIException.ERROR.SERVER_ERROR;
/**
* Created by luofan on 2017/11/15.
*/
public class APIException {
public static final int UNAUTHORIZED = 401;
public static final int FORBIDDEN = 403;
public static final int NOT_FOUND = 404;
public static final int REQUEST_TIMEOUT = 408;
public static final int INTERNAL_SERVER_ERROR = 500;
public static final int BAD_GATEWAY = 502;
public static final int SERVICE_UNAVAILABLE = 503;
public static final int GATEWAY_TIMEOUT = 504;
public static ResponeThrowable APIException(Throwable e) {
ResponeThrowable ex;
if (e instanceof HttpException) {
HttpException httpException = (HttpException) e;
ex = new ResponeThrowable(e, ERROR.HTTP_ERROR);
switch (httpException.code()) {
case FORBIDDEN:
ex.message = BaseApplication.getContext().getString(R.string.error_token);
ex.code = FORBIDDEN;
break;
case UNAUTHORIZED:
case NOT_FOUND:
case REQUEST_TIMEOUT:
ex.message = BaseApplication.getContext().getString(R.string.error_time_out);
ex.code = REQUEST_TIMEOUT;
break;
case GATEWAY_TIMEOUT:
case INTERNAL_SERVER_ERROR:
ex.message = BaseApplication.getContext().getString(R.string.error_connect);
ex.code = INTERNAL_SERVER_ERROR;
break;
case BAD_GATEWAY:
case SERVICE_UNAVAILABLE:
default:
ex.message = BaseApplication.getContext().getString(R.string.error_internet);
break;
}
return ex;
} else if (e instanceof ServerException) {
ServerException resultException = (ServerException) e;
ex = new ResponeThrowable(resultException, SERVER_ERROR, resultException.code);
ex.message = resultException.message;
return ex;
} else if (e instanceof JsonParseException
|| e instanceof JSONException
|| e instanceof ParseException) {
ex = new ResponeThrowable(e, ERROR.PARSE_ERROR);
ex.message = BaseApplication.getContext().getString(R.string.error_parse);
return ex;
} else if (e instanceof ConnectException) {
ex = new ResponeThrowable(e, ERROR.NETWORD_ERROR);
ex.message = BaseApplication.getContext().getString(R.string.error_connect);
return ex;
} else if (e instanceof javax.net.ssl.SSLHandshakeException) {
ex = new ResponeThrowable(e, ERROR.SSL_ERROR);
ex.message = BaseApplication.getContext().getString(R.string.error_ssl);
return ex;
} else if (e instanceof ConnectTimeoutException) {
ex = new ResponeThrowable(e, ERROR.TIMEOUT_ERROR);
ex.message = BaseApplication.getContext().getString(R.string.error_time_out);
return ex;
} else if (e instanceof java.net.SocketTimeoutException) {
ex = new ResponeThrowable(e, ERROR.TIMEOUT_ERROR);
ex.message = BaseApplication.getContext().getString(R.string.error_time_out);
return ex;
} else {
ex = new ResponeThrowable(e, ERROR.UNKNOWN);
ex.message = BaseApplication.getContext().getString(R.string.error_unknow);
return ex;
}
}
/**
* 约定异常
*/
class ERROR {
/**
* 接口返回错误
*/
public static final int SERVER_ERROR = 999;
/**
* 未知错误
*/
public static final int UNKNOWN = 1000;
/**
* 解析错误
*/
public static final int PARSE_ERROR = 1001;
/**
* 网络错误
*/
public static final int NETWORD_ERROR = 1002;
/**
* 协议出错
*/
public static final int HTTP_ERROR = 1003;
/**
* 证书出错
*/
public static final int SSL_ERROR = 1005;
/**
* 连接超时
*/
public static final int TIMEOUT_ERROR = 1006;
}
public static class ResponeThrowable extends Exception {
public int code;
public String message;
public String subCode;
public ResponeThrowable(Throwable throwable, int code) {
super(throwable);
this.code = code;
}
public ResponeThrowable(Throwable throwable, int code, String subCode) {
super(throwable);
this.code = code;
this.subCode = subCode;
}
}
}
package com.dayu.base.api;
import io.reactivex.Observable;
import okhttp3.ResponseBody;
import retrofit2.http.GET;
import retrofit2.http.Streaming;
import retrofit2.http.Url;
/**
* Created by luofan on 2017/11/09.
*/
public interface APIService {
@Streaming
@GET
Observable<ResponseBody> download(@Url String url);
}
package com.dayu.base.api;
import android.text.TextUtils;
import com.dayu.base.api.protocol.BaseResponse;
import com.dayu.common.BaseConstant;
import com.dayu.common.Constants;
import com.dayu.utils.LogUtils;
import com.dayu.utils.SPUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by luofan on 2017/11/09.
*/
public class Api {
private static Retrofit mRetrofit;
private static final int DEFAULT_TIMEOUT = 60;
private static Retrofit mDownloadRetrofit;
/**
* 普通retrofit.
*
* @return
*/
public static <T> T getService(Class<T> cls) {
return getmRetrofit().create(cls);
}
/**
* 下载的retrofit.
*
* @return
*/
public static <T> T getDownloadService(Class<T> cls) {
return getmDownloadRetrofit().create(cls);
}
private static Retrofit getmRetrofit() {
if (mRetrofit == null) {
mRetrofit = getRetrofit("");
}
return mRetrofit;
}
private static Retrofit getmDownloadRetrofit() {
if (mDownloadRetrofit == null) {
mDownloadRetrofit = getRetrofit("download");
}
return mDownloadRetrofit;
}
private static Retrofit getRetrofit(String type) {
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.create();
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(m -> LogUtils.i("request", m));
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
TokenInterceptord tokenInterceptord = new TokenInterceptord();
OkHttpClient.Builder build = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.addInterceptor(tokenInterceptord)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
if ("download".equals(type)) {
build.addNetworkInterceptor(chain -> {
Response response = chain.proceed(chain.request());
return response
.newBuilder()
.body(new FileResponseBody(response.body()))//将自定义的ResposeBody设置给它
.build();
});
}
return new Retrofit.Builder()
.client(build.build())
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
/**
* 统一加上token.
*/
public static class TokenInterceptord implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String token = (String) SPUtils.get(BaseConstant.TOKEN, "");
if (!TextUtils.isEmpty(token) && !request.url().toString().contains(Constants.BASE_URL + Constants.LOGIN_URL)) {
request = request.newBuilder()
.header(BaseConstant.TOKEN, token)
.build();
}
return chain.proceed(request);
}
}
public static <T> ObservableTransformer<BaseResponse<T>, T> applySchedulers() {
return (ObservableTransformer<BaseResponse<T>, T>) transformer;
}
final static ObservableTransformer transformer = new ObservableTransformer() {
@Override
public ObservableSource apply(Observable upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap((response) -> flatResponse((BaseResponse<Object>) response));
}
};
/**
* 对网络接口返回的Response进行分割操作
*
* @param response
* @param <T>
* @return
*/
public static <T> Observable<T> flatResponse(final BaseResponse<T> response) {
return Observable.create(e -> {
if (response.isSuccess()) {
if (!e.isDisposed()) {
e.onNext(response.getData());
}
} else {
if (!e.isDisposed()) {
e.onError(new ServerException(response.getSubCode(), response.getMsg()));
}
return;
}
if (!e.isDisposed()) {
e.onComplete();
}
});
}
}
package com.dayu.base.api;
import android.app.IntentService;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import com.dayu.utils.DownloadManager;
import com.dayu.widgets.listener.onDownloadListener;
import io.reactivex.disposables.CompositeDisposable;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p>
*/
public class DownloadService extends IntentService {
private static final String ACTION_DOWNLOAD = "intentservice.action.download";
private static final String DOWNLOAD_URL = "downloadUrl";
private static final String APK_PATH = "apkPath";
private static onDownloadListener mListener;
private CompositeDisposable cd = new CompositeDisposable();
private NotificationCompat.Builder builder;
private NotificationManager notificationManager;
public DownloadService() {
super("DownloadService");
}
public static void startUpdateService(Context context, String url, String apkPath, onDownloadListener listener) {
Intent intent = new Intent(context, DownloadService.class);
intent.setAction(ACTION_DOWNLOAD);
intent.putExtra(DOWNLOAD_URL, url);
intent.putExtra(APK_PATH, apkPath);
context.startService(intent);
mListener = listener;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
String action = intent.getAction();
if (ACTION_DOWNLOAD.equals(action)) {
String url = intent.getStringExtra(DOWNLOAD_URL);
String apkPath = intent.getStringExtra(APK_PATH);
handleUpdate(url, apkPath);
}
}
}
private void handleUpdate(String url, String apkPath) {
DownloadManager.download(this, url, apkPath, cd, mListener);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
package com.dayu.base.api;
import com.dayu.event.DownloadBean;
import org.greenrobot.eventbus.EventBus;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
/**
* 下载文件
* Created by luofan on 2017/11/27.
*/
public class FileResponseBody extends ResponseBody {
private ResponseBody responseBody;
private BufferedSource bufferedSource;
public FileResponseBody(ResponseBody responseBody) {
this.responseBody = responseBody;
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@Override
public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
// read() returns the number of bytes read, or -1 if this source is exhausted.
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
EventBus.getDefault().post(new DownloadBean(contentLength(), totalBytesRead));
return bytesRead;
}
};
}
}
package com.dayu.base.api;
import com.dayu.baselibrary.R;
import com.dayu.common.BaseApplication;
import com.dayu.common.Constants;
/**
* Created by luofan on 2017/11/15.
* 错误码统一处理类.
*/
public class ServerException extends Exception {
public String code;
public String message;
public ServerException(String code, String message) {
this.code = code;
this.message = message;
processCode(code);
}
private void processCode(String code) {
if (code == null) {
message = BaseApplication.getContext().getString(R.string.get_info_failed);
return;
}
switch (code) {
/** order相关错误*/
case "ORDER0001":
message = BaseApplication.getContext().getString(R.string.order_not_exite);
break;
case "ORDER0002":
message = BaseApplication.getContext().getString(R.string.order_receive_already);
break;
case "ORDER0003":
message = BaseApplication.getContext().getString(R.string.order_cancle_not_receive);
break;
case "ORDER0004":
message = BaseApplication.getContext().getString(R.string.order_cancle_not_subcribe);
break;
case "ORDER0005":
message = BaseApplication.getContext().getString(R.string.order_cancle_not_begin);
break;
case "ORDER0006":
message = BaseApplication.getContext().getString(R.string.order_cancle_not_process);
break;
case "LOGISTICS0001":
message = BaseApplication.getContext().getString(R.string.query_logistics_failed);
break;
/** 用户相关错误*/
case "USER0002":
message = BaseApplication.getContext().getString(R.string.sms_code_unsend_or_expire);
break;
case "USER0004":
message = BaseApplication.getContext().getString(R.string.not_engineer);
break;
case "USER0005":
message = BaseApplication.getContext().getString(R.string.account_frozen);
break;
case "USER0020":
message = BaseApplication.getContext().getString(R.string.sms_code_unsend_or_expire);
break;
case "USER0021":
message = BaseApplication.getContext().getString(R.string.sms_code_error);
break;
case "USER0003":
case "USER0023":
message = BaseApplication.getContext().getString(R.string.engineer_acount_notavialibe);
break;
case "USER0024":
message = BaseApplication.getContext().getString(R.string.engineer_not_have_site);
break;
case "USER0062":
message = BaseApplication.getContext().getString(R.string.identity_is_error);
break;
case "USER0051":
message = BaseApplication.getContext().getString(R.string.not_audite_aviliable);
break;
/** 账户相关*/
case "SETTLEMENT0015":
message = Constants.NOT_SHOW;
break;
case "SETTLEMENT0001":
message = BaseApplication.getContext().getString(R.string.perameter_is_null);
break;
/**全局错误*/
case "GLOBAL0001":
message = "未知错误GLOBAL0001"; //参数错误
break;
case "GLOBAL0002":
message = "未知错误GLOBAL0002"; //格式化序列化错误
break;
case "GLOBAL0003":
message = "未知错误GLOBAL0003"; //业务错误
break;
case "GLOBAL0004":
message = "未知错误GLOBAL0004"; //全局错误
break;
case "GLOBAL0100":
message = "未知错误GLOBAL0100"; //远程调用失败
break;
case "GLOBAL0101":
message = "验证码错误"; //短信验证失败
break;
case "GLOBAL0102":
message = "未知错误GLOBAL0102"; // unknowable error type
break;
case "GLOBAL0103":
message = "验证码错误";
break;
case "GLOBAL0104":
message = "用户名和密码错误";
break;
case "GLOBAL0400":
message = "未知错误GLOBAL0400"; //Bad Request!
break;
case "GLOBAL0406":
message = "未知错误GLOBAL0406"; //not Acceptable
break;
case "GLOBAL0405":
message = "未知错误GLOBAL0405"; //Method Not Allowed
break;
case "GLOBAL0500":
message = "未知错误GLOBAL0500"; //Method Not Allowed
break;
case "GLOBAL1001":
message = "未知错误GLOBAL1001"; //空指针异常
break;
case "GLOBAL1002":
message = "未知错误GLOBAL1002"; //类型转换异
break;
case "GLOBAL1003":
message = "未知错误GLOBAL1003"; //IO异常
break;
case "GLOBAL1004":
message = "未知错误GLOBAL1004"; //未知方法异
break;
case "GLOBAL1005":
message = "未知错误GLOBAL1005"; //数据越界异
break;
default:
message = BaseApplication.getContext().getString(R.string.get_info_failed);
break;
}
}
}
package com.dayu.base.api.protocol;
import java.util.List;
/**
* 分页的basebean.
* Created by luofan on 2017/11/14.
*/
public class BasePageBean<T>{
private int pageNo;
private int pageSize;
private int totalRows;
private int totalPages;
private int previousPageNo;
private int nextPageNo;
private List<T> data;
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalRows() {
return totalRows;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public int getPreviousPageNo() {
return previousPageNo;
}
public void setPreviousPageNo(int previousPageNo) {
this.previousPageNo = previousPageNo;
}
public int getNextPageNo() {
return nextPageNo;
}
public void setNextPageNo(int nextPageNo) {
this.nextPageNo = nextPageNo;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}
package com.dayu.base.api.protocol;
/**
* Created by luofan on 2016/07/14.
*/
public class BaseResponse<T> {
private int code;
private String subCode;
private String msg;
private T data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public boolean isSuccess() {
return code == 0;
}
public String getSubCode() {
return subCode;
}
public void setSubCode(String subCode) {
this.subCode = subCode;
}
}
package com.dayu.base.ui.activity;
import android.content.Intent;
import android.databinding.ViewDataBinding;
import android.os.Bundle;
import com.alibaba.android.arouter.launcher.ARouter;
import com.dayu.base.ui.presenter.BasePresenter;
import com.dayu.baselibrary.R;
import com.dayu.common.BaseApplication;
import com.dayu.common.BaseConstant;
import com.dayu.common.BaseView;
import com.dayu.common.Constants;
import com.dayu.utils.ProgressUtil;
import com.dayu.utils.TUtil;
import com.dayu.utils.ToastUtils;
import com.dayu.widgets.CustomDialog;
import java.lang.reflect.ParameterizedType;
;
/**
* Created by luofan on 17/11/02.
*/
public abstract class BaseActivity<P extends BasePresenter, B extends ViewDataBinding> extends DataBindingActivity<B>
implements BaseView {
public P mPresenter;
private boolean isDialogShow = false;
@Override
protected void initPresenter() {
super.initPresenter();
if (this.getClass().getGenericSuperclass() instanceof ParameterizedType &&
((ParameterizedType) (this.getClass().getGenericSuperclass())).getActualTypeArguments().length > 0) {
mPresenter = TUtil.getT(this, 0);
if (mPresenter != null) {
mPresenter.setView(this);
setPresenter();
}
}
ARouter.getInstance().inject(this);
}
/**
* databing设置presenter.
*/
public abstract void setPresenter();
@Override
protected void onDestroy() {
super.onDestroy();
if (mPresenter != null) {
mPresenter.onDetached();
}
}
public void showToast(String msg) {
ToastUtils.showShortToast(msg);
}
public void showToast(int resId) {
ToastUtils.showShortToast(resId);
}
public void showDialog() {
ProgressUtil.startLoad(this);
}
public void showDialog(String str) {
ProgressUtil.startLoad(this, str);
}
public void hideDialog() {
ProgressUtil.stopLoad();
}
public void dumpBack() {
mActivity.finish();
}
public void dumpBack(int requestCode, Intent intent) {
mActivity.setResult(requestCode, intent);
mActivity.finish();
}
public void startActivity(Class cls) {
mActivity.startActivity(new Intent(mActivity, cls));
}
public void startActivityForIntent(Intent intent) {
mActivity.startActivity(intent);
}
public void startActivity(Class<?> clz, Bundle bundle) {
Intent intent = new Intent(mActivity, clz);
if (bundle != null) {
intent.putExtra(Constants.BUNDLE, bundle);
}
mActivity.startActivity(intent);
}
public void startActivityForReult(Class<?> clz, Bundle bundle, int requestCode) {
Intent intent = new Intent(mActivity, clz);
if (bundle != null) {
intent.putExtra(Constants.BUNDLE, bundle);
}
mActivity.startActivityForResult(intent, requestCode);
}
public void startActivityForReult(Class<?> clz, int requestCode) {
mActivity.startActivityForResult(new Intent(mActivity, clz), requestCode);
}
public void startActvityAndFinish(Class<?> clz) {
mActivity.startActivity(new Intent(mActivity, clz));
mActivity.finish();
}
public void startActivityAndFinish(Class<?> clz, Bundle bundle) {
Intent intent = new Intent(mActivity, clz);
if (bundle != null) {
intent.putExtra(Constants.BUNDLE, bundle);
}
mActivity.startActivity(intent);
mActivity.finish();
}
public Bundle getBundle() {
return getIntent().getBundleExtra(Constants.BUNDLE);
}
/**
* token超时提示重新登录.
*/
public void showLoginDialog() {
if (isDialogShow) {
return;
}
CustomDialog mDialog = new CustomDialog(mActivity, R.style.CustomDialog, getString(R.string.login_state_no)
, (dialog, confirm) -> {
if (confirm) {
// EMClient.getInstance().logout(true);
// UserManager.getInstance().clearUserInfo();
BaseApplication.getBaseApp().exiteAllActivity();
ARouter.getInstance().build(BaseConstant.PATH_LOGIN).navigation();
}
dialog.dismiss();
isDialogShow = false;
});
mDialog.setTitle(getString(R.string.notice))
.setPositiveButton(getString(R.string.login_again))
.setOneButton(true);
mDialog.show();
isDialogShow = true;
}
}
package com.dayu.base.ui.activity;
import android.app.Activity;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import com.umeng.analytics.MobclickAgent;
public abstract class DataBindingActivity<B extends ViewDataBinding> extends AppCompatActivity {
public Activity mActivity;
public B mBind;
private String mClassName;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View rootView = getLayoutInflater().inflate(this.getLayoutId(), null, false);
mBind = DataBindingUtil.bind(rootView);
this.setContentView(rootView);
mActivity = this;
mClassName = mActivity.getClass().getSimpleName();
initPresenter();
initView();
}
@Override
public void onResume() {
super.onResume();
if (!"MainActivity".equals(mActivity.getClass().getSimpleName())
&& !"OrderDetailsActivity".equals(mActivity.getClass().getSimpleName())) {
MobclickAgent.onPageStart(mClassName);
}
MobclickAgent.onResume(mActivity);
}
@Override
public void onPause() {
super.onPause();
if (!"MainActivity".equals(mActivity.getClass().getSimpleName())
&& !"OrderDetailsActivity".equals(mActivity.getClass().getSimpleName())) {
MobclickAgent.onPageEnd(mClassName);
}
MobclickAgent.onPause(mActivity);
}
protected void initPresenter() {
}
public abstract int getLayoutId();
public abstract void initView();
}
package com.dayu.base.ui.adapter;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
/**
* Created by luofan on 2017/12/9.
*/
public class BaseViewHolder<B extends ViewDataBinding> extends RecyclerView.ViewHolder {
public final B mBind;
public BaseViewHolder(B t) {
super(t.getRoot());
mBind = t;
}
}
package com.dayu.base.ui.adapter;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.support.annotation.LayoutRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import com.dayu.base.api.protocol.BasePageBean;
import com.dayu.base.ui.presenter.BaseListPresenter;
import com.dayu.baselibrary.BR;
import com.dayu.baselibrary.R;
import com.dayu.common.Constants;
import com.dayu.widgets.listener.OnChildClickListener;
import com.dayu.widgets.listener.OnItemClickListener;
import java.util.ArrayList;
import java.util.List;
/**
* Created by luofan on 2017/12/9.
*/
@SuppressWarnings("unchecked")
public class CoreAdapter<M, B> extends RecyclerView.Adapter<BaseViewHolder> {
private TypeSelector<M> mTypeSelector;
private List<M> mItemList = new ArrayList<>();
public boolean isHasMore = true;
private List<Item> mHeadTypeDatas = new ArrayList<>();
private List<Item> mFootTypeDatas = new ArrayList<>();
private int viewType;
private int mFooterViewType = R.layout.lrecycler_foot;
protected Context mContext;
private int mTotalPage = 0;
private int mPage = 1;
public boolean isLoadFial = false;
private OnItemClickListener mOnItemClickListener;
protected BaseListPresenter mPresenter;
protected OnChildClickListener mOnChildClickListener;
private List<M> mOldDatas = new ArrayList<>();
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
this.mContext = parent.getContext();
return new BaseViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), viewType, parent, false));
}
public CoreAdapter(boolean needFoot) {
if (needFoot) {
mFootTypeDatas.add(new Item(mFooterViewType, true));
}
}
public CoreAdapter(boolean needFoot, int viewType) {
if (needFoot) {
mFootTypeDatas.add(new Item(mFooterViewType, true));
}
this.viewType = viewType;
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
Object item = getItem(position);
holder.mBind.setVariable(BR.item, item);
holder.mBind.executePendingBindings();
if (position >= mHeadTypeDatas.size() && position < (mHeadTypeDatas.size() + mFootTypeDatas.size() + mItemList.size())) {
if (item != null && !(item instanceof Boolean)) {
onBind((B) holder.mBind, (M) item, position);
holder.mBind.getRoot().setOnClickListener(v -> {
if (mOnItemClickListener != null) {
mOnItemClickListener.OnItemClick(item, holder.mBind);
}
});
}
}
}
public void setViewType(@LayoutRes int type) {
this.viewType = type;
}
public void setTypeSelector(TypeSelector mTypeSelector) {
this.mTypeSelector = mTypeSelector;
this.viewType = Constants.FLAG_MULTI_VH;
}
public void addHeadViewType(@LayoutRes int i, Object data) {
for (Item a : mHeadTypeDatas) {
if (a.type == i) {
return;
}
}
mHeadTypeDatas.add(new Item(i, data));
}
public void addFooterViewType(@LayoutRes int i, Object data) {
mFootTypeDatas.add(mFootTypeDatas.size() - 1, new Item(i, data));
}
public Object getItem(int position) {
if (position < mHeadTypeDatas.size()) {
return mHeadTypeDatas.get(position).data;
} else if (position >= (mHeadTypeDatas.size() + mItemList.size())) {
int index = position - (mHeadTypeDatas.size() + mItemList.size());
if (mFootTypeDatas.get(index).type == mFooterViewType && !isHasMore) {
if (isLoadFial) {
return null;
} else {
return false;
}
} else {
if (isLoadFial) {
return null;
} else {
return mFootTypeDatas.get(index).data;
}
}
} else {
return mItemList.get(position - mHeadTypeDatas.size());
}
}
@Override
public int getItemViewType(int position) {
if (position < mHeadTypeDatas.size()) {
return mHeadTypeDatas.get(position).type;
} else if (position >= (mHeadTypeDatas.size() + mItemList.size())) {
return mFootTypeDatas.get(position - (mHeadTypeDatas.size() + mItemList.size())).type;
} else {
return viewType == Constants.FLAG_MULTI_VH ?
mTypeSelector.getType((M) getItem(position)) :
viewType;
}
}
public void addPageData(BasePageBean<M> data) {
if (data == null) {
isHasMore = false;
notifyDataSetChanged();
return;
}
mPage += 1;
mTotalPage = data.getTotalPages();
if (mPage >= mTotalPage) {
isHasMore = false;
} else {
isHasMore = true;
}
this.mItemList.addAll(data.getData());
notifyDataSetChanged();
}
public void setPageData(BasePageBean<M> data) {
mOldDatas = mItemList;
mPage = 1;
mTotalPage = data.getTotalPages();
if (mPage >= mTotalPage) {
isHasMore = false;
} else {
isHasMore = true;
}
this.mItemList = data.getData();
// DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffCallBack(mOldDatas, mItemList), true);
// diffResult.dispatchUpdatesTo(this);
notifyDataSetChanged();
}
public void setData(List<M> data) {
this.mItemList = data;
notifyDataSetChanged();
}
/**
* 是否允许加载更多.
*
* @param flag
*/
public void setLoadMore(boolean flag) {
isHasMore = flag;
if (mPage >= mTotalPage || mTotalPage == 0) {
isHasMore = false;
}
}
@Override
public int getItemCount() {
return mItemList.size() + mHeadTypeDatas.size() + mFootTypeDatas.size();
}
public void setPresenter(BaseListPresenter presenter) {
mPresenter = presenter;
}
public class Item {
int type;
Object data;
public Item(int type, Object data) {
this.type = type;
this.data = data;
}
}
/**
* 继承coreadapter需要重写此方法.
*
* @param holder
* @param item
* @param position
*/
protected void onBind(B holder, M item, int position) {
}
public void setOnItemClickListener(OnItemClickListener<M, B> listener) {
mOnItemClickListener = listener;
}
public void setOnChildClickListener(OnChildClickListener listener) {
mOnChildClickListener = listener;
}
/**
* 获取数据源.
*
* @return
*/
public List<M> getDatas() {
return mItemList;
}
public Context getContext() {
return mContext;
}
}
\ No newline at end of file
package com.dayu.base.ui.adapter;
/**
* Created by luofan on 2017/12/9.
*/
public interface TypeSelector<M> {
int getType(M m);
}
package com.dayu.base.ui.fragment;
import android.content.Intent;
import android.databinding.ViewDataBinding;
import android.os.Bundle;
import com.alibaba.android.arouter.launcher.ARouter;
import com.dayu.base.ui.presenter.BasePresenter;
import com.dayu.baselibrary.R;
import com.dayu.common.BaseApplication;
import com.dayu.common.BaseConstant;
import com.dayu.common.BaseView;
import com.dayu.common.Constants;
import com.dayu.utils.ProgressUtil;
import com.dayu.utils.TUtil;
import com.dayu.utils.ToastUtils;
import com.dayu.widgets.CustomDialog;
import java.lang.reflect.ParameterizedType;
/**
* Created by luo on 2017/11/14.
*/
public abstract class BaseFragment<P extends BasePresenter, B extends ViewDataBinding> extends DataBindingFragment<B>
implements BaseView {
public P mPresenter;
private boolean isDialogShow = false;
@Override
protected void initPresenter() {
super.initPresenter();
if (this.getClass().getGenericSuperclass() instanceof ParameterizedType &&
((ParameterizedType) (this.getClass().getGenericSuperclass())).getActualTypeArguments().length > 0) {
mPresenter = TUtil.getT(this, 0);
if (mPresenter != null) {
mPresenter.setView(this);
setPresenter();
// mBind.setVariable(BR.presenter, mPresenter);
}
}
ARouter.getInstance().inject(this);
}
/**
* databing设置presenter.
*/
public abstract void setPresenter();
@Override
public void onDestroy() {
super.onDestroy();
if (mPresenter != null) mPresenter.onDetached();
}
public void dumpBack() {
mActivity.finish();
}
public void dumpBack(int requestCode, Intent intent) {
mActivity.setResult(requestCode, intent);
mActivity.finish();
}
public void showToast(int resId) {
ToastUtils.showShortToast(resId);
}
public void showToast(String msg) {
ToastUtils.showShortToast(msg);
}
public void showDialog() {
ProgressUtil.startLoad(mActivity);
}
public void showDialog(String str) {
ProgressUtil.startLoad(mActivity, str);
}
public void hideDialog() {
ProgressUtil.stopLoad();
}
public void startActivity(Class cls) {
mActivity.startActivity(new Intent(mActivity, cls));
}
public void startActivityForIntent(Intent intent) {
mActivity.startActivity(intent);
}
public void startActivity(Class<?> clz, Bundle bundle) {
Intent intent = new Intent(mActivity, clz);
if (bundle != null) {
intent.putExtra(Constants.BUNDLE, bundle);
}
mActivity.startActivity(intent);
}
public void startActivityForReult(Class<?> clz, int requestCode) {
mActivity.startActivityForResult(new Intent(mActivity, clz), requestCode);
}
public void startActivityForReult(Class<?> clz, Bundle bundle, int requestCode) {
Intent intent = new Intent(mActivity, clz);
if (bundle != null) {
intent.putExtra(Constants.BUNDLE, bundle);
}
mActivity.startActivityForResult(intent, requestCode);
}
public void startActvityAndFinish(Class<?> clz) {
mActivity.startActivity(new Intent(mActivity, clz));
mActivity.finish();
}
public void startActivityAndFinish(Class<?> clz, Bundle bundle) {
Intent intent = new Intent(mActivity, clz);
if (bundle != null) {
intent.putExtra(Constants.BUNDLE, bundle);
}
mActivity.startActivity(intent);
mActivity.finish();
}
public Bundle getBundle() {
return getArguments();
}
public void showLoginDialog() {
if (isDialogShow) {
return;
}
CustomDialog mDialog = new CustomDialog(mActivity, R.style.CustomDialog, getString(R.string.login_state_no)
, (dialog, confirm) -> {
if (confirm) {
// UserManager.getInstance().clearUserInfo();
// EMClient.getInstance().logout(true);
// UserManager.getInstance().clearUserInfo();
BaseApplication.getBaseApp().exiteAllActivity();
ARouter.getInstance().build(BaseConstant.PATH_LOGIN).navigation();
}
dialog.dismiss();
isDialogShow = false;
});
mDialog.setTitle(getString(R.string.notice))
.setPositiveButton(getString(R.string.login_again))
.setOneButton(true);
mDialog.show();
isDialogShow = true;
}
}
package com.dayu.base.ui.fragment;
import android.app.Activity;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
public abstract class DataBindingFragment<B extends ViewDataBinding> extends Fragment {
public B mBind;
protected Activity mActivity;
private boolean isVisible; //是否可见状态
private boolean isPrepared; //标志位,View已经初始化完成。
private boolean isFirstLoad = true;
protected CompositeDisposable mDisposable = new CompositeDisposable();
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
onAttachToContext((Activity) context);
}
}
@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
onAttachToContext(activity);
}
}
private void onAttachToContext(Activity context) {
mActivity = context;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isFirstLoad = true;
isPrepared = true;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(getLayoutId(), container, false);
mBind = DataBindingUtil.bind(view);
initPresenter();
initView();
return view;
}
public abstract void initView();
public abstract int getLayoutId();
protected void initPresenter() {
}
/**
* 如果是与ViewPager一起使用,调用的是setUserVisibleHint
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (getUserVisibleHint()) {
isVisible = true;
//显示加载效果,延时
mDisposable.add(Observable.timer(300, TimeUnit.MILLISECONDS).subscribe(aLong -> onVisible()));
} else {
isVisible = false;
onInvisible();
}
}
/**
* 如果是通过FragmentTransaction的show和hide的方法来控制显示,调用的是onHiddenChanged.
* 若是初始就show的Fragment 为了触发该事件 需要先hide再show
*/
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden) {
isVisible = true;
onVisible();
} else {
isVisible = false;
onInvisible();
}
}
protected void onVisible() {
doInit();
}
protected void onInvisible() {
}
protected void doInit() {
if (!isPrepared || !isVisible || !isFirstLoad) {
return;
}
isFirstLoad = false;
lazyLoad();
}
protected void lazyLoad() {
}
@Override
public void onDetach() {
super.onDetach();
mDisposable.dispose();
}
}
package com.dayu.base.ui.presenter;
import android.databinding.ObservableField;
/**
* Created by luofan on 2017/12/23.
*/
public abstract class BaseListPresenter<V> extends BasePresenter<V> {
/**
* 如果有下拉刷新,子类必须重写此方法.
*/
public void refresh() {
}
/**
* 如果有上拉加载,子类必须重写此方法.
*/
public void loadMore() {
}
/**
* 如果有头布局,子类重写此方法.
*
* @return 头布局数据源.
*/
public ObservableField<Object> getHeaderDatas() {
return null;
}
/**
*
* @return recy数据源.
*/
public abstract ObservableField<Object> getSourceDatas();
}
package com.dayu.base.ui.presenter;
import android.util.Log;
import com.dayu.base.api.APIException;
import com.dayu.base.ui.activity.BaseActivity;
import com.dayu.base.ui.fragment.BaseFragment;
import com.dayu.common.BaseView;
import com.dayu.common.Constants;
import com.dayu.utils.ProgressUtil;
import io.reactivex.Observer;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
/**
* Created by luofan on 17/11/02.
*/
public abstract class BasePresenter<V> {
protected static final String TAG = "BasePresenter";
protected V mView;
protected CompositeDisposable mComDisposable = new CompositeDisposable();
public void setView(V v) {
this.mView = v;
this.onAttached();
}
public abstract void onAttached();
public void onDetached() {
mComDisposable.dispose();
}
/**
* 创建观察者
*
* @param consumer
* @return
*/
public <M> Observer<M> baseObserver(final Consumer<? super M> consumer) {
return new Observer<M>() {
@Override
public void onSubscribe(Disposable d) {
mComDisposable.add(d);
}
@Override
public void onNext(M o) {
ProgressUtil.stopLoad();
try {
consumer.accept(o);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
ProgressUtil.stopLoad();
processException(e);
}
@Override
public void onComplete() {
}
};
}
/**
* 创建带错误的观察者
*
* @param consumer
* @return
*/
public <M> Observer<M> baseObserver(final Consumer<? super M> consumer, final Consumer<APIException.ResponeThrowable> tconsumer) {
return new Observer<M>() {
@Override
public void onSubscribe(Disposable d) {
mComDisposable.add(d);
}
@Override
public void onNext(M o) {
ProgressUtil.stopLoad();
try {
consumer.accept(o);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
Log.d("reguest+error", e.toString());
APIException.ResponeThrowable exception = processException(e);
ProgressUtil.stopLoad();
try {
tconsumer.accept(exception);
} catch (Exception e1) {
e1.printStackTrace();
}
}
@Override
public void onComplete() {
}
};
}
private APIException.ResponeThrowable processException(Throwable e) {
APIException.ResponeThrowable exception = APIException.APIException(e);
int code = exception.code;
String message = exception.message;
if (code == APIException.FORBIDDEN) {
showLoginDialog();
return exception;
}
if (!Constants.NOT_SHOW.equals(message) && mView instanceof BaseView) {
((BaseView) mView).showToast(message);
}
return exception;
}
/**
* 重新登录的提示框.
*/
private void showLoginDialog() {
if (mView instanceof BaseActivity) {
((BaseActivity) mView).showLoginDialog();
} else if (mView instanceof BaseFragment) {
((BaseFragment) mView).showLoginDialog();
}
}
public void dumpBack() {
if (mView instanceof BaseActivity) {
((BaseActivity) mView).dumpBack();
}
}
}
package com.dayu.common;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.support.multidex.MultiDex;
import android.support.multidex.MultiDexApplication;
import com.alibaba.android.arouter.launcher.ARouter;
import java.util.Stack;
/**
* Created by luofan
* on 2018/2/6.
*/
public class BaseApplication extends MultiDexApplication {
private static Context mContext;
private Stack<Activity> store;
private static BaseApplication myApplication;
@Override
public void onCreate() {
super.onCreate();
MultiDex.install(this);
myApplication = this;
mContext = this.getApplicationContext();
store = new Stack<>();
registerActivityLifecycleCallbacks(new SwitchBackgroundCallbacks());
//ARouter初始化
ARouter.openLog(); // 打印日志
ARouter.openDebug();
ARouter.init(this);
}
/**
* 退出所有activity.
*/
public void exiteAllActivity() {
for (Activity activity : store) {
activity.finish();
}
}
/**
* 获取当前的Activity
*
* @return
*/
public Activity getCurActivity() {
return store.lastElement();
}
public static Context getContext() {
return mContext;
}
public static BaseApplication getBaseApp() {
return myApplication;
}
private class SwitchBackgroundCallbacks implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
store.add(activity);
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
store.remove(activity);
}
}
}
package com.dayu.common;
/**
* Created by luofan
* on 2018/2/7.
*/
public class BaseConstant {
public static final String TOKEN ="token";
public static final String PATH_LOGIN ="/user/login";
}
package com.dayu.common;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.StringRes;
/**
* Created by luofan on 17/11/02.
*/
public interface BaseView {
void showToast(@StringRes int resId);
void showToast(String str);
void showDialog();
void showDialog(String str);
void hideDialog();
void dumpBack();
void dumpBack(int requestCode, Intent intent);
void startActivity(Class cls);
void startActivityForIntent(Intent intent);
void startActivity(Class<?> clz, Bundle bundle);
void startActvityAndFinish(Class<?> clz);
void startActivityForReult(Class<?> clz, int requestCode);
void startActivityForReult(Class<?> clz, Bundle bundle, int requestCode);
void startActivityAndFinish(Class<?> clz, Bundle bundle);
Bundle getBundle();
}
package com.dayu.event;
/**
* Created by luofan on 2017/11/27.
* 下载进度.
*/
public class DownloadBean {
private long total;
private long bytesReaded;
public DownloadBean(long total, long bytesReaded) {
this.total = total;
this.bytesReaded = bytesReaded;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
public long getBytesReaded() {
return bytesReaded;
}
public void setBytesReaded(long bytesReaded) {
this.bytesReaded = bytesReaded;
}
}
package com.dayu.utils;
import android.content.Context;
import com.dayu.base.api.APIService;
import com.dayu.base.api.Api;
import com.dayu.widgets.listener.onDownloadListener;
import java.io.File;
import java.io.IOException;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
/**
* app更新管理类
* Created by luofan on 2017/11/27.
*/
public class DownloadManager {
/**
* 是否需要更新,需要则下载
*
* @param context 上下文
* @param url 新版本地址
* @param apkPath 本地apk保存路径
* @param cd 订阅关系集合,在数据传输完毕时解除订阅
*/
public static void download(final Context context, final String url, final String apkPath, final CompositeDisposable cd, onDownloadListener listener) {
Api.getDownloadService(APIService.class).download(url)
.map(ResponseBody::source)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.doOnNext(bufferedSource -> {
try {
writeFile(bufferedSource, new File(apkPath));
} catch (IOException e) {
e.printStackTrace();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<BufferedSource>() {
@Override
public void onSubscribe(Disposable d) {
cd.add(d);
}
@Override
public void onNext(BufferedSource bufferedSource) {
}
@Override
public void onError(Throwable e) {
listener.onDownloadFail();
unSubscribe(cd);
}
@Override
public void onComplete() {
listener.onDownloadSuccess(new File(apkPath));
unSubscribe(cd);
}
});
}
/**
* 写入文件
*/
private static void writeFile(BufferedSource source, File file) throws IOException {
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
if (file.exists())
file.delete();
BufferedSink bufferedSink = Okio.buffer(Okio.sink(file));
bufferedSink.writeAll(source);
bufferedSink.close();
source.close();
}
/**
* 解除订阅
*
* @param cd 订阅关系集合
*/
private static void unSubscribe(CompositeDisposable cd) {
if (cd != null && !cd.isDisposed())
cd.dispose();
}
}
package com.dayu.utils;
import android.text.TextUtils;
import android.util.Log;
import com.dayu.common.Constants;
import java.util.List;
/**
* @author itheima
* @time 2017-8-20 上午11:33:49
* @des 日志级别是LEVEL_ALL显示所有信息,包括System.out.println信息
* @des 日志级别是LEVEL_OFF关闭所有信息,包括System.out.println信息
*/
public class LogUtils {
/** 日志输出时的TAG */
private static String mTag = "BigFish";
/** 日志输出级别NONE */
public static final int LEVEL_OFF = 0;
/** 日志输出级别NONE */
public static final int LEVEL_ALL = 7;
/** 日志输出级别V */
public static final int LEVEL_VERBOSE = 1;
/** 日志输出级别D */
public static final int LEVEL_DEBUG = 2;
/** 日志输出级别I */
public static final int LEVEL_INFO = 3;
/** 日志输出级别W */
public static final int LEVEL_WARN = 4;
/** 日志输出级别E */
public static final int LEVEL_ERROR = 5;
/** 日志输出级别S,自定义定义的一个级别 */
public static final int LEVEL_SYSTEM = 6;
/** 是否允许输出log */
private static int mDebuggable = Constants.DEBUGLEVEL;
/** 用于记时的变量 */
private static long mTimestamp = 0;
/** 写文件的锁对象 */
private static final Object mLogLock = new Object();
/**---------------日志输出,已固定TAG begin---------------**/
/** 以级别为 d 的形式输出LOG */
public static void v(String msg) {
if (mDebuggable >= LEVEL_VERBOSE) {
Log.v(mTag, msg);
}
}
/** 以级别为 d 的形式输出LOG */
public static void d(String msg) {
if (mDebuggable >= LEVEL_DEBUG) {
Log.d(mTag, msg);
}
}
/** 以级别为 i 的形式输出LOG */
public static void i(String msg) {
if (mDebuggable >= LEVEL_INFO) {
Log.i(mTag, msg);
}
}
/** 以级别为 w 的形式输出LOG */
public static void w(String msg) {
if (mDebuggable >= LEVEL_WARN) {
Log.w(mTag, msg);
}
}
/** 以级别为 w 的形式输出Throwable */
public static void w(Throwable tr) {
if (mDebuggable >= LEVEL_WARN) {
Log.w(mTag, "", tr);
}
}
/** 以级别为 w 的形式输出LOG信息和Throwable */
public static void w(String msg, Throwable tr) {
if (mDebuggable >= LEVEL_WARN && null != msg) {
Log.w(mTag, msg, tr);
}
}
/** 以级别为 e 的形式输出LOG */
public static void e(String msg) {
if (mDebuggable >= LEVEL_ERROR) {
Log.e(mTag, msg);
}
}
/** 以级别为 s 的形式输出LOG,主要是为了System.out.println,稍微格式化了一下 */
public static void sf(String msg) {
if (mDebuggable >= LEVEL_ERROR) {
System.out.println("----------" + msg + "----------");
}
}
/** 以级别为 s 的形式输出LOG,主要是为了System.out.println */
public static void s(String msg) {
if (mDebuggable >= LEVEL_ERROR) {
System.out.println(msg);
}
}
/** 以级别为 e 的形式输出Throwable */
public static void e(Throwable tr) {
if (mDebuggable >= LEVEL_ERROR) {
Log.e(mTag, "", tr);
}
}
/** 以级别为 e 的形式输出LOG信息和Throwable */
public static void e(String msg, Throwable tr) {
if (mDebuggable >= LEVEL_ERROR && null != msg) {
Log.e(mTag, msg, tr);
}
}
/**---------------日志输出,已固定TAG end---------------**/
/**---------------日志输出,未固定TAG begin---------------**/
/** 以级别为 d 的形式输出LOG */
public static void v(String tag, String msg) {
if (mDebuggable >= LEVEL_VERBOSE) {
Log.v(tag, msg);
}
}
/** 以级别为 d 的形式输出LOG */
public static void d(String tag, String msg) {
if (mDebuggable >= LEVEL_DEBUG) {
Log.d(tag, msg);
}
}
/** 以级别为 i 的形式输出LOG */
public static void i(String tag, String msg) {
if (mDebuggable >= LEVEL_INFO) {
Log.i(tag, msg);
}
}
/** 以级别为 w 的形式输出LOG */
public static void w(String tag, String msg) {
if (mDebuggable >= LEVEL_WARN) {
Log.w(tag, msg);
}
}
/** 以级别为 e 的形式输出LOG */
public static void e(String tag, String msg) {
if (mDebuggable >= LEVEL_ERROR) {
Log.e(tag, msg);
}
}
/**---------------日志输出,未固定TAG end---------------**/
/**
* 以级别为 e 的形式输出msg信息,附带时间戳,用于输出一个时间段起始点
*
* @param msg
* 需要输出的msg
*/
public static void msgStartTime(String msg) {
mTimestamp = System.currentTimeMillis();
if (!TextUtils.isEmpty(msg)) {
e("[Started:" + mTimestamp + "]" + msg);
}
}
/** 以级别为 e 的形式输出msg信息,附带时间戳,用于输出一个时间段结束点* @param msg 需要输出的msg */
public static void elapsed(String msg) {
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - mTimestamp;
mTimestamp = currentTime;
e("[Elapsed:" + elapsedTime + "]" + msg);
}
public static <T> void printList(List<T> list) {
if (list == null || list.size() < 1) {
return;
}
int size = list.size();
i("---begin---");
for (int i = 0; i < size; i++) {
i(i + ":" + list.get(i).toString());
}
i("---end---");
}
public static <T> void printArray(T[] array) {
if (array == null || array.length < 1) {
return;
}
int length = array.length;
i("---begin---");
for (int i = 0; i < length; i++) {
i(i + ":" + array[i].toString());
}
i("---end---");
}
}
package com.dayu.utils;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import com.dayu.baselibrary.R;
import java.util.List;
/**
* Created by luofan on 16/7/20.
*/
public class ProgressUtil {
private static final int START_DIALOG = 0;//开始对话框
private static final int UPDATE_DIALOG = 1;//更新对话框
private static final int STOP_DIALOG = 2;//销毁对话框
private static AlertDialog dialog = null;
private static TextView title = null;
private static Context context = null;
private static Handler handler = new Handler(Looper.getMainLooper()) {
public void handleMessage(Message msg) {
String message = "";
switch (msg.what) {
case START_DIALOG:// 启动加载框
message = (String) msg.obj;
if (dialog != null) {
stopLoad();
startLoad(context, message);
return;
}
init(context, message);
isTouchDismiss(true);
break;
case UPDATE_DIALOG:// 更新加载框
message = (String) msg.obj;
if (title.VISIBLE == View.VISIBLE) {
if (TextUtils.isEmpty(message)) {
title.setVisibility(View.GONE);
} else {
title.setText(message);
}
} else {
if (!TextUtils.isEmpty(message)) {
title.setText(message);
title.setVisibility(View.VISIBLE);
}
}
break;
case STOP_DIALOG:// 停止加载框
if (dialog != null) {
dialog.dismiss();
dialog.cancel();
dialog = null;
title = null;
}
break;
}
}
;
};
/**
* @方法说明:加载控件与布局
* @方法名称:init
* @返回值:void
*/
private static void init(Context context, String mssg) {
if (isBackground(context)) {// 如果程序在后台,则不加载
return;
}
if (null != context) {
LayoutInflater flat = LayoutInflater.from(context);
View v = flat.inflate(R.layout.dialog_loading_layout, null);
// v.setBackgroundColor(mContext.getResources().getColor(android.R.color.transparent));
// 创建对话
dialog = new AlertDialog.Builder(context, R.style.Dialog).create();
// 设置返回键点击消失对话框
dialog.setCancelable(true);
// 设置点击返回框外边不消失
dialog.setCanceledOnTouchOutside(true);
// 给该对话框增加系统权限
// dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
// 显示对话
dialog.show();
// 加载控件
title = (TextView) v.findViewById(R.id.loading_text);
if (TextUtils.isEmpty(mssg)) {
title.setVisibility(View.GONE);
} else {
title.setVisibility(View.VISIBLE);
title.setText(mssg);
}
// 必须放到显示对话框下面,否则显示不出效果
Window window = dialog.getWindow();
// window.getAttributes().x = 0;
// window.getAttributes().y = 0;//设置y坐标
WindowManager.LayoutParams params = window.getAttributes();
params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
params.gravity = Gravity.CENTER;
// params.alpha = 0.6f;
window.setAttributes(params); // 加载布局组件
dialog.getWindow().setContentView(v);
}
}
/**
* @param
* @param msg
* @方法说明:启动对话框
* @方法名称:startLoad
* @返回值:void
*/
public static void startLoad(Context activity, String msg) {
context = activity;
if (context == null) {
return;
}
if (isBackground(context)) {// 如果程序在后台,则不加载
return;
}
Message mssage = new Message();
mssage.what = START_DIALOG;
mssage.obj = msg;
handler.sendMessage(mssage);
}
/**
* @param
* @方法说明:启动对话框
* @方法名称:startLoad
* @返回值:void
*/
public static void startLoad(Context activity) {
context = activity;
if (context == null) {
return;
}
if (isBackground(context)) {// 如果程序在后台,则不加载
return;
}
Message mssage = new Message();
mssage.what = START_DIALOG;
mssage.obj = "加载中...";
handler.sendMessage(mssage);
}
/**
* @param msg
* @方法说明:更新显示的内容
* @方法名称:UpdateMsg
* @返回值:void
*/
public static void UpdateMsg(String msg) {
Message message = new Message();
message.what = UPDATE_DIALOG;
message.obj = msg;
handler.sendMessage(message);
}
/**
* @param flag
* @方法说明:允许加载条转动的时候去点击系统返回键
* @方法名称:openCancelable
* @返回值:void
*/
public static void openCancelable(boolean flag) {
if (dialog != null) {
dialog.setCancelable(flag);
}
}
/**
* @param isdimiss
* @方法说明:允许点击对话框触摸消失
* @方法名称:isTouchDismiss
* @返回值:void
*/
public static void isTouchDismiss(boolean isdimiss) {
if (dialog != null) {
dialog.setCanceledOnTouchOutside(isdimiss);
}
}
/**
* @方法说明:让警告框消失
* @方法名称:dismiss
* @返回值:void
*/
public static void stopLoad() {
handler.sendEmptyMessage(STOP_DIALOG);
}
/**
* @param context
* @return
* @方法说明:判断当前应用程序是否后台运行
* @方法名称:isBackground
* @返回值:boolean
*/
public static boolean isBackground(Context context) {
ActivityManager activityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager
.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.processName.equals(context.getPackageName())) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
// 后台运行
return true;
} else {
// 前台运行
return false;
}
}
}
return false;
}
}
package com.dayu.utils;
import android.content.Context;
import android.content.SharedPreferences;
import com.dayu.common.BaseApplication;
import java.lang.reflect.Method;
import java.util.Map;
/**
* SharedPreferences的工具类
*/
public class SPUtils {
/**
* 保存在手机里面的文件名
*/
public static final String FILE_NAME = "big_fish";
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param key
* @param object 存储的数据类型
*/
public static void put(String key, Object object) {
SharedPreferences sp = BaseApplication.getContext().getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
editor.putInt(key, (Integer) object);
} else if (object instanceof Boolean) {
editor.putBoolean(key, (Boolean) object);
} else if (object instanceof Float) {
editor.putFloat(key, (Float) object);
} else if (object instanceof Long) {
editor.putLong(key, (Long) object);
} else {
editor.putString(key, object.toString());
}
SharedPreferencesCompat.apply(editor);
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*/
public static Object get(String key, Object defaultObject) {
return get(FILE_NAME, key, defaultObject);
}
public static Object get(String spName, String key, Object defaultObject) {
SharedPreferences sp = BaseApplication.getContext().getSharedPreferences(spName,
Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sp.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
return sp.getInt(key, (Integer) defaultObject);
} else if (defaultObject instanceof Boolean) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if (defaultObject instanceof Float) {
return sp.getFloat(key, (Float) defaultObject);
} else if (defaultObject instanceof Long) {
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
/**
* 移除某个key值已经对应的值
*/
public static void remove(String key) {
remove(FILE_NAME, key);
}
public static void remove(String spName, String key) {
SharedPreferences sp = BaseApplication.getContext().getSharedPreferences(spName,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
SharedPreferencesCompat.apply(editor);
}
/**
* 清除所有数据
*/
public static void clear() {
clear(FILE_NAME);
}
public static void clear(String spName) {
SharedPreferences sp = BaseApplication.getContext().getSharedPreferences(spName, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
SharedPreferencesCompat.apply(editor);
}
/**
* 查询某个key是否已经存在
*/
public static boolean contains(String key) {
return contains(FILE_NAME, key);
}
public static boolean contains(String spName, String key) {
SharedPreferences sp = BaseApplication.getContext().getSharedPreferences(spName, Context.MODE_PRIVATE);
return sp.contains(key);
}
/**
* 返回所有的键值对
*/
public static Map<String, ?> getAll() {
return getAll(FILE_NAME);
}
public static Map<String, ?> getAll(String spName) {
SharedPreferences sp = BaseApplication.getContext().getSharedPreferences(spName,
Context.MODE_PRIVATE);
return sp.getAll();
}
/**
* 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
*/
private static class SharedPreferencesCompat {
private static final Method sApplyMethod = findApplyMethod();
/**
* 反射查找apply的方法
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private static Method findApplyMethod() {
try {
Class clz = SharedPreferences.Editor.class;
return clz.getMethod("apply");
} catch (NoSuchMethodException e) {
}
return null;
}
/**
* 如果找到则使用apply执行,否则使用commit
*/
public static void apply(SharedPreferences.Editor editor) {
try {
if (sApplyMethod != null) {
sApplyMethod.invoke(editor);
return;
}
} catch (Exception e) {
}
editor.commit();
}
}
}
\ No newline at end of file
package com.dayu.utils;
import java.lang.reflect.ParameterizedType;
/**
* Created by luofan on 16/7/13.
*/
public class TUtil {
public static <T> T getT(Object o, int i) {
try {
return ((Class<T>) ((ParameterizedType) (o.getClass()
.getGenericSuperclass())).getActualTypeArguments()[i])
.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassCastException e) {
e.printStackTrace();
}
return null;
}
public static Class<?> forName(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
package com.dayu.utils;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.StringRes;
import android.widget.Toast;
/**
* 吐司工具类
* on 2017/8/22.
*/
public class ToastUtils {
private ToastUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
private static Toast sToast;
private static Handler sHandler = new Handler(Looper.getMainLooper());
private static boolean isJumpWhenMore;
/**
* 吐司初始化
*
* @param isJumpWhenMore 当连续弹出吐司时,是要弹出新吐司还是只修改文本内容
* <p>{@code true}: 弹出新吐司<br>{@code false}: 只修改文本内容</p>
* <p>如果为{@code false}的话可用来做显示任意时长的吐司</p>
*/
public static void init(boolean isJumpWhenMore) {
ToastUtils.isJumpWhenMore = isJumpWhenMore;
}
/**
* 安全地显示短时吐司
*
* @param text 文本
*/
public static void showShortToastSafe(final CharSequence text) {
sHandler.post(new Runnable() {
@Override
public void run() {
showToast(text, Toast.LENGTH_SHORT);
}
});
}
/**
* 安全地显示短时吐司
*
* @param resId 资源Id
*/
public static void showShortToastSafe(final @StringRes int resId) {
sHandler.post(new Runnable() {
@Override
public void run() {
showToast(resId, Toast.LENGTH_SHORT);
}
});
}
/**
* 安全地显示短时吐司
*
* @param resId 资源Id
* @param args 参数
*/
public static void showShortToastSafe(final @StringRes int resId, final Object... args) {
sHandler.post(new Runnable() {
@Override
public void run() {
showToast(resId, Toast.LENGTH_SHORT, args);
}
});
}
/**
* 安全地显示短时吐司
*
* @param format 格式
* @param args 参数
*/
public static void showShortToastSafe(final String format, final Object... args) {
sHandler.post(new Runnable() {
@Override
public void run() {
showToast(format, Toast.LENGTH_SHORT, args);
}
});
}
/**
* 安全地显示长时吐司
*
* @param text 文本
*/
public static void showLongToastSafe(final CharSequence text) {
sHandler.post(new Runnable() {
@Override
public void run() {
showToast(text, Toast.LENGTH_LONG);
}
});
}
/**
* 安全地显示长时吐司
*
* @param resId 资源Id
*/
public static void showLongToastSafe(final @StringRes int resId) {
sHandler.post(new Runnable() {
@Override
public void run() {
showToast(resId, Toast.LENGTH_LONG);
}
});
}
/**
* 安全地显示长时吐司
*
* @param resId 资源Id
* @param args 参数
*/
public static void showLongToastSafe(final @StringRes int resId, final Object... args) {
sHandler.post(new Runnable() {
@Override
public void run() {
showToast(resId, Toast.LENGTH_LONG, args);
}
});
}
/**
* 安全地显示长时吐司
*
* @param format 格式
* @param args 参数
*/
public static void showLongToastSafe(final String format, final Object... args) {
sHandler.post(new Runnable() {
@Override
public void run() {
showToast(format, Toast.LENGTH_LONG, args);
}
});
}
/**
* 显示短时吐司
*
* @param text 文本
*/
public static void showShortToast(CharSequence text) {
showToast(text, Toast.LENGTH_SHORT);
}
/**
* 显示短时吐司
*
* @param resId 资源Id
*/
public static void showShortToast(@StringRes int resId) {
showToast(resId, Toast.LENGTH_SHORT);
}
/**
* 显示短时吐司
*
* @param resId 资源Id
* @param args 参数
*/
public static void showShortToast(@StringRes int resId, Object... args) {
showToast(resId, Toast.LENGTH_SHORT, args);
}
/**
* 显示短时吐司
*
* @param format 格式
* @param args 参数
*/
public static void showShortToast(String format, Object... args) {
showToast(format, Toast.LENGTH_SHORT, args);
}
/**
* 显示长时吐司
*
* @param text 文本
*/
public static void showLongToast(CharSequence text) {
showToast(text, Toast.LENGTH_LONG);
}
/**
* 显示长时吐司
*
* @param resId 资源Id
*/
public static void showLongToast(@StringRes int resId) {
showToast(resId, Toast.LENGTH_LONG);
}
/**
* 显示长时吐司
*
* @param resId 资源Id
* @param args 参数
*/
public static void showLongToast(@StringRes int resId, Object... args) {
showToast(resId, Toast.LENGTH_LONG, args);
}
/**
* 显示长时吐司
*
* @param format 格式
* @param args 参数
*/
public static void showLongToast(String format, Object... args) {
showToast(format, Toast.LENGTH_LONG, args);
}
/**
* 显示吐司
*
* @param resId 资源Id
* @param duration 显示时长
*/
private static void showToast(@StringRes int resId, int duration) {
showToast(UIUtils.getContext().getResources().getText(resId).toString(), duration);
}
/**
* 显示吐司
*
* @param resId 资源Id
* @param duration 显示时长
* @param args 参数
*/
private static void showToast(@StringRes int resId, int duration, Object... args) {
showToast(String.format(UIUtils.getContext().getResources().getString(resId), args), duration);
}
/**
* 显示吐司
*
* @param format 格式
* @param duration 显示时长
* @param args 参数
*/
private static void showToast(String format, int duration, Object... args) {
showToast(String.format(format, args), duration);
}
/**
* 显示吐司
*
* @param text 文本
* @param duration 显示时长
*/
private static void showToast(CharSequence text, int duration) {
if (isJumpWhenMore) cancelToast();
if (sToast == null) {
sToast = Toast.makeText(UIUtils.getContext(), text, duration);
} else {
sToast.setText(text);
sToast.setDuration(duration);
}
sToast.show();
}
/**
* 取消吐司显示
*/
public static void cancelToast() {
if (sToast != null) {
sToast.cancel();
sToast = null;
}
}
}
package com.dayu.utils;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Paint;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import com.dayu.common.BaseApplication;
/**
* 封装和ui相关的操作
* MrWang on
* 2017/8/20.
*/
public class UIUtils {
/**
* 得到上下文
*/
public static Context getContext() {
return BaseApplication.getContext();
}
/**
* 得到Resources对象
*/
public static Resources getResources() {
return getContext().getResources();
}
/**
*
*
*/
public static String getString(int resId) {
return getResources().getString(resId);
}
/**
* 得到String.xml中的字符串数组信息
*/
public static String[] getStrings(int resId) {
return getResources().getStringArray(resId);
}
/**
* 得到Color.xml中的颜色信息
*/
public static int getColor(int resId) {
return getResources().getColor(resId);
}
/**
* 得到应用程序的包名
*/
public static String getPackageName() {
return getContext().getPackageName();
}
/**
* 把一个dp的值转换为px值
*
* @param dp
* @return
*/
public int dp2px(int dp) {
// 获取手机屏幕的密度
float density = getResources().getDisplayMetrics().density;
return (int) (dp * density + 0.5f); // 加0.5是为了四舍五入
}
/**
* 判断TextView的内容宽度是否超出其可用宽度
*
* @param tv
* @return
*/
public static boolean isOverFlowed(TextView tv) {
int availableWidth = tv.getWidth() - tv.getPaddingLeft() - tv.getPaddingRight();
Paint textViewPaint = tv.getPaint();
float textWidth = textViewPaint.measureText(tv.getText().toString()) / 2;
if (textWidth > availableWidth) {
return true;
} else {
return false;
}
}
public static void hideInput(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
}
package com.dayu.widgets;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import com.dayu.baselibrary.R;
import com.dayu.widgets.listener.OnCloseListener;
/**
* Created by luofan on 2017/11/10.
*/
public class CustomDialog extends Dialog implements View.OnClickListener {
private TextView contentTxt;
private TextView titleTxt;
private TextView submitTxt;
private TextView cancelTxt;
private Context mContext;
private String content;
private OnCloseListener listener;
private String positiveName;
private String negativeName;
private String title;
private int positiveColor;
private boolean flag;
private View line;
public CustomDialog(Context context) {
super(context);
this.mContext = context;
}
public CustomDialog(Context context, int themeResId, String content) {
super(context, themeResId);
this.mContext = context;
this.content = content;
}
public CustomDialog(Context context, int themeResId, String content, OnCloseListener listener) {
super(context, themeResId);
this.mContext = context;
this.content = content;
this.listener = listener;
}
protected CustomDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
this.mContext = context;
}
public CustomDialog setTitle(String title) {
this.title = title;
return this;
}
public CustomDialog setPositiveButton(String name) {
this.positiveName = name;
return this;
}
public CustomDialog setPositiveButtonColor(int colorId) {
this.positiveColor = colorId;
return this;
}
public CustomDialog setNegativeButton(String name) {
this.negativeName = name;
return this;
}
public CustomDialog setOneButton(boolean flag) {
this.flag = flag;
return this;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_custom);
setCanceledOnTouchOutside(false);
setCancelable(false);
initView();
}
private void initView() {
contentTxt = (TextView) findViewById(R.id.content);
titleTxt = (TextView) findViewById(R.id.title);
line = findViewById(R.id.v_line);
submitTxt = (TextView) findViewById(R.id.submit);
submitTxt.setOnClickListener(this);
cancelTxt = (TextView) findViewById(R.id.cancel);
cancelTxt.setOnClickListener(this);
contentTxt.setText(content);
if (!TextUtils.isEmpty(positiveName)) {
submitTxt.setText(positiveName);
}
if (positiveColor != 0) {
submitTxt.setTextColor(positiveColor);
}
if (!TextUtils.isEmpty(negativeName)) {
cancelTxt.setText(negativeName);
}
if (!TextUtils.isEmpty(title)) {
titleTxt.setText(title);
}
if (flag) {
line.setVisibility(View.GONE);
cancelTxt.setVisibility(View.GONE);
}
}
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.cancel) {
if (listener != null) {
listener.onClick(this, false);
}
this.dismiss();
} else if (i == R.id.submit) {
if (listener != null) {
listener.onClick(this, true);
}
this.dismiss();
}
}
}
package com.dayu.widgets.listener;
import android.view.View;
import com.dayu.base.ui.adapter.CoreAdapter;
/**
* LRecy的子view的点击事件
* Created by luofan on 2017/12/10.
*/
public interface OnChildClickListener {
void OnChildClick(View view, CoreAdapter adapter, int position);
}
package com.dayu.widgets.listener;
import android.app.Dialog;
/**
* Created by luofan
* on 2018/2/6.
*/
public interface OnCloseListener {
void onClick(Dialog dialog, boolean confirm);
}
package com.dayu.widgets.listener;
/**
* Created by luofan on 2017/12/10.
*/
public interface OnItemClickListener<M,B> {
void OnItemClick(M item,B bind);
}
package com.dayu.widgets.listener;
/**
* Created by luofan on 2017/12/8.
*/
public interface OnRefreshListener {
void refresh();
}
package com.dayu.widgets.listener;
import java.io.File;
/**
* Created by luofan on 2017/11/28.
*/
public interface onDownloadListener {
void onDownloadSuccess(File file);
void onDownloadFail();
}
package com.dayu.widgets.listener;
/**
* Created by luofan on 2017/12/8.
*/
public interface onLoadMoreListener {
void onLoadMore();
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="8dp"/>
<solid android:color="@color/cl_white"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="270.0"
android:centerColor="#99000000"
android:centerY="0.5"
android:endColor="#99000000"
android:startColor="#99000000" >
</gradient>
<corners android:radius="5dip" />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
</shape>
\ No newline at end of file
<animated-rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotX="50%" android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="720">
<shape
android:shape="ring"
android:innerRadiusRatio="3"
android:thicknessRatio="15"
android:useLevel="false">
<gradient
android:type="sweep"
android:useLevel="false"
android:startColor="#55c6c6c6"
android:centerColor="#c6c6c6"
android:centerY="0.50"
android:endColor="#c6c6c6" />
</shape>
</animated-rotate>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:background="@drawable/item_shape"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="20dp"
android:text="@string/notice"
android:textColor="#FF030303"
android:textSize="17sp" />
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:gravity="center"
android:lineSpacingExtra="3dp"
android:textColor="#FF030303"
android:textSize="13sp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/cl_selector_hui" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="@+id/cancel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:gravity="center"
android:text="@string/cancle"
android:textColor="@color/cl_receiving_order_item_data"
android:textSize="17sp" />
<View
android:id="@+id/v_line"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/cl_selector_hui" />
<TextView
android:id="@+id/submit"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:gravity="center"
android:text="@string/comfirm"
android:textColor="@color/cl_receiving_order_item_data"
android:textSize="17sp" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container_dialog"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="80dip"
android:layout_height="80dip"
android:layout_centerInParent="true"
android:background="@drawable/loading_progress_bg"
android:gravity="center"
android:orientation="vertical">
<ProgressBar
android:layout_width="45dp"
android:layout_height="45dp"
android:indeterminateDrawable="@drawable/progressbar"
android:layout_gravity="center"
/>
<TextView
android:id="@+id/loading_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="12sp"
android:text="@string/loading"
android:textColor="#9a9b98"/>
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="@null"
android:scrollbars="none" />
</android.support.v4.widget.SwipeRefreshLayout>
<LinearLayout
android:id="@+id/ll_emptyview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="@+id/iv_empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/yu" />
<TextView
android:id="@+id/tv_empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/iv_empty"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/dp_13"
android:text="暂无数据(点击刷新)"
android:textColor="@color/cl_selector_hui"
android:textSize="@dimen/sp_13.3" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_faileview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="@drawable/error" />
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="23dp"
android:text="加载出错啦"
android:textColor="#c9c9c9"
android:textSize="17.3sp" />
<TextView
android:id="@+id/retry_btn"
android:layout_width="115dp"
android:layout_height="30dp"
android:layout_marginTop="55dp"
android:gravity="center"
android:paddingBottom="4dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="4dp"
android:text="重新加载"
android:textSize="15.4sp" />
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<import type="android.view.View" />
<variable
name="item"
type="Boolean" />
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:orientation="horizontal">
<ProgressBar
android:id="@+id/progressbar"
style="@android:style/Widget.ProgressBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/progressbar"
android:visibility="@{item == null?View.GONE:(item?View.VISIBLE:View.GONE)}" />
<TextView
android:id="@+id/tv_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:clickable="@{item == null?true:false}"
android:text='@{item !=null? (item?"正在加载" :"没有更多数据"):"加载失败(再次上拉试试~)"}' />
</LinearLayout>
</layout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="LRecyclerView">
<attr name="isReverse" format="boolean" />
<attr name="isRefreshable" format="boolean" />
<attr name="needCoreAdapter" format="boolean" />
<attr name="needFoot" format="boolean" />
<attr name="itemType" format="reference" />
<attr name="headType" format="reference" />
<attr name="footType" format="reference" />
</declare-styleable>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="cl_white">#ffffff</color>
<color name="cl_primarydark">#303F9F</color>
<color name="cl_accent">#ff00</color>
<color name="cl_text">#8a8a8a</color>
<color name="cl_black">#88000000</color>
<color name="cl_login_clearedittext_hint">#BBBBBB</color>
<color name="cl_home_title_text_color">#3a3a3a</color>
<color name="cl_home_circleimageview_bg">#d7edff</color>
<color name="cl_home_listview_bg">#f5f5f5</color>
<color name="cl_order_item_line_bg">#e5e5e5</color>
<color name="cl_order_item_date">#00c45d</color>
<color name="cl_receiving_order_item_data">#3faafc</color>
<color name="cl_tab_yellow">#ffbe2d</color>
<color name="cl_tab_read">#ff5a4b</color>
<color name="cl_tab_init">#585858</color>
<color name="cl_tab_line">#8a8a8a</color>
<color name="cl_selector_hui">#bbbbbb</color>
<color name="cl_work_raiod">#d5d5d5</color>
<color name="cl_personal_center">#fafafa</color>
<color name="cl_home_button">#3e96e2</color>
<color name="cl_home_edit_text">#cccccc</color>
<color name="cl_order_text_title">#000000</color>
<color name="cl_order_text_one">#888888</color>
<color name="primary">#5C92FC</color>
<color name="line_color">#dddddd</color>
<color name="text_color">#8a8a8a</color>
<color name="default_text_color">#FF2D2D2D</color>
<color name="default_editext_color">#FF959595</color>
<color name="cl_line">#FFE3E3E3</color>
<color name="cl_bg">#FFF5F5F5</color>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="sp_1">12sp</dimen>
<dimen name="size_text_title">16sp</dimen>
<dimen name="sp_16">16sp</dimen>
<dimen name="size_login_clearedittext_text">15sp</dimen>
<dimen name="sp_15">15sp</dimen>
<dimen name="size_login_register_button_text">14sp</dimen>
<dimen name="sp_14">14sp</dimen>
<dimen name="size_login_hint_text">13.3sp</dimen>
<dimen name="sp_13.3">13.3sp</dimen>
<dimen name="sp_12">12sp</dimen>
<dimen name="size_order_item_data_text">24sp</dimen>
<dimen name="size_login_button_text">15sp</dimen>
<dimen name="size_main_title">60dp</dimen>
<dimen name="size_title_ml">13.3dp</dimen>
<dimen name="size_login_mlcircleimageview_width">80dp</dimen>
<dimen name="size_login_mlcircleimageview_height">80dp</dimen>
<dimen name="size_login_mlcircleimageview_mt">80dp</dimen>
<dimen name="size_login_linear_width">326dp</dimen>
<dimen name="size_login_linear_height">106dp</dimen>
<dimen name="size_login_linear_mt">210dp</dimen>
<dimen name="size_login_clearedittext_mr">15dp</dimen>
<dimen name="size_login_clearedittext_dp">12dp</dimen>
<dimen name="size_login_clearedittext_pl">17dp</dimen>
<dimen name="size_login_pwd_edittext_dp">12dp</dimen>
<dimen name="size_login_pwd_edittext_pl">17dp</dimen>
<dimen name="size_login_register_button_mb">15dp</dimen>
<dimen name="size_login_register_button_mr">10dp</dimen>
<dimen name="size_login_button_weidth">327dp</dimen>
<dimen name="size_login_button_mt">57dp</dimen>
<dimen name="size_login_hint_mt">17dp</dimen>
<dimen name="size_home_circleimageview_width">40dp</dimen>
<dimen name="size_home_circleimageview_height">40dp</dimen>
<dimen name="size_home_circleimageview_ml">20dp</dimen>
<dimen name="size_home_circleimageview_border">2dp</dimen>
<dimen name="size_home_circleimageview_image_width">32dp</dimen>
<dimen name="size_home_circleimageview_image_height">32dp</dimen>
<dimen name="size_home_circleimageview_image_mr">13dp</dimen>
<dimen name="size_order_item_width">333dp</dimen>
<dimen name="size_order_item_height">100dp</dimen>
<dimen name="size_order_item_mt">13dp</dimen>
<dimen name="size_order_item_line_width">0.7dp</dimen>
<dimen name="size_order_item_line_height">67dp</dimen>
<dimen name="size_order_item_line_ml">89dp</dimen>
<dimen name="size_order_item_time_mr">12dp</dimen>
<dimen name="size_order_item_time_mt">20dp</dimen>
<dimen name="size_order_item_data_mr">12dp</dimen>
<dimen name="size_order_item_tool_ml">14dp</dimen>
<dimen name="size_order_item_tool_mt">23dp</dimen>
<dimen name="size_order_item_gps_ml">14dp</dimen>
<dimen name="size_order_item_gps_mt">47dp</dimen>
<dimen name="size_order_item_tooltext_ml">8dp</dimen>
<dimen name="size_order_item_tooltext_mt">20dp</dimen>
<dimen name="size_order_item_gpstext_ml">8dp</dimen>
<dimen name="size_order_item_gpstext_mt">43dp</dimen>
<dimen name="_24">24dp</dimen>
<dimen name="size_order_item_time_text">12sp</dimen>
<dimen name="sp_30">30sp</dimen>
<dimen name="sp_10">10sp</dimen>
<dimen name="sp_8">8sp</dimen>
<dimen name="dp_0.23">0.23dp</dimen>
<dimen name="dp_0.7">1dp</dimen>
<dimen name="dp_40">40dp</dimen>
<dimen name="dp_21.3">21dp</dimen>
<dimen name="dp_20">20dp</dimen>
<dimen name="dp_30">30dp</dimen>
<dimen name="dp_13.3">13.3dp</dimen>
<dimen name="dp_16.7">17dp</dimen>
<dimen name="dp_14.3">14dp</dimen>
<dimen name="dp_105">106dp</dimen>
<dimen name="dp_160">160dp</dimen>
<dimen name="dp_333">333dp</dimen>
<dimen name="dp_6">6dp</dimen>
<dimen name="dp_10">10dp</dimen>
<dimen name="dp_54">54dp</dimen>
<dimen name="dp_183">183dp</dimen>
<dimen name="dp_27">27dp</dimen>
<dimen name="dp_33">33dp</dimen>
<dimen name="dp_267">267dp</dimen>
<dimen name="dp_147">147dp</dimen>
<dimen name="dp_3">3dp</dimen>
<dimen name="dp_8">8dp</dimen>
<dimen name="dp_17">17dp</dimen>
<dimen name="dp_314">314dp</dimen>
<dimen name="dp_163">163dp</dimen>
<dimen name="dp_11">11dp</dimen>
<dimen name="dp_13">13dp</dimen>
<dimen name="dp_15">15dp</dimen>
<dimen name="dp_0.3">0.3dp</dimen>
<dimen name="dp_12">12dp</dimen>
<dimen name="dp_26">26dp</dimen>
<dimen name="dp_125">125dp</dimen>
<dimen name="dp_61">61dp</dimen>
<dimen name="dp_205">205dp</dimen>
<dimen name="dp_57">57dp</dimen>
<dimen name="dp_31">31dp</dimen>
<dimen name="dp_29">29dp</dimen>
<dimen name="dp_41">41dp</dimen>
<dimen name="dp_7">7dp</dimen>
<dimen name="dp_18">18dp</dimen>
<dimen name="dp_53">53dp</dimen>
<dimen name="dp_16">16dp</dimen>
<dimen name="dp_14">14dp</dimen>
<dimen name="dp_162">162dp</dimen>
<dimen name="dp_327">327dp</dimen>
<dimen name="dp_197">197dp</dimen>
<dimen name="dp_50">50dp</dimen>
<dimen name="dp_34">34dp</dimen>
<dimen name="dp_60">60dp</dimen>
<dimen name="dp_65">65dp</dimen>
<dimen name="dp_70">70dp</dimen>
<dimen name="dp_9">9dp</dimen>
<dimen name="dp_89">89dp</dimen>
<dimen name="dp_80">80dp</dimen>
<dimen name="dp_111">111dp</dimen>
<dimen name="dp_133">133dp</dimen>
<dimen name="dp_23">23dp</dimen>
</resources>
\ No newline at end of file
<resources>
<style name="Dialog" parent="@android:style/Theme.Holo.Dialog">
<item name="android:windowSoftInputMode">stateHidden|adjustResize</item>
<!-- 边框 -->
<item name="android:windowFrame">@null</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">false</item>
<!-- 无标题 -->
<item name="android:windowNoTitle">true</item>
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 模糊 -->
<item name="android:backgroundDimEnabled">false</item>
</style>
<style name="CustomDialog" parent="@android:style/Theme.Dialog">
<item name="android:windowSoftInputMode">stateHidden|adjustResize</item>
<item name="android:windowFrame">@null</item>
<!-- Dialog的windowFrame框为无 -->
<item name="android:windowIsFloating">true</item>
<!-- 是否漂现在activity上 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 是否半透明 -->
<item name="android:windowNoTitle">true</item>
<item name="android:background">@null</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<!-- 去除黑色边框的关键设置项 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 屏幕背景是否变暗 -->
<item name="android:backgroundDimAmount">0.3</item>
</style>
</resources>
apply plugin: 'com.android.library'
android {
compileSdkVersion compile_sdk_version
buildToolsVersion build_tools_version
defaultConfig {
minSdkVersion min_sdk_version
targetSdkVersion target_sdk_version
versionCode version_code
versionName verson_name
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
useProguard true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
compile project(':baseLibrary')
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\AndroidSDK/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
package com.dayu.provider;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.dayu.provider.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dayu.provider" />
package com.dayu.provider.common;
/**
* Created by luofan
* on 2018/2/7.
*/
public class ProviderConstant {
}
package com.dayu.provider.router;
/**
* Created by luofan
* on 2018/2/7.
*/
public class RouterPath {
public final static String PATH_LOGIN = "/user/login";
}
<resources>
<string name="app_name">Provider</string>
</resources>
package com.dayu.provider;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment