getSplashImage(@Query("type") int type);
18 |
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/http/HttpClient.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.http;
2 |
3 |
4 | import android.content.Context;
5 | import android.support.annotation.NonNull;
6 |
7 | import com.example.wsj.splashdemo.ColumnApplication;
8 | import com.example.wsj.splashdemo.http.interceptor.CacheInterceptor;
9 | import com.example.wsj.splashdemo.http.interceptor.LoggingInterceptor;
10 |
11 | import java.io.File;
12 | import java.util.concurrent.TimeUnit;
13 |
14 | import okhttp3.Cache;
15 | import okhttp3.OkHttpClient;
16 | import retrofit2.Retrofit;
17 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
18 | import retrofit2.converter.gson.GsonConverterFactory;
19 |
20 | import static com.example.wsj.splashdemo.entity.Constants.API_DEBUG_SERVER_URL;
21 |
22 |
23 | /**
24 | * Created by wangshijia on 2017/2/4 下午3:33.
25 | * Copyright (c) 2017. alpha, Inc. All rights reserved.
26 | *
27 | * eg: 全局 单利网络请求Client 请求方法 调用静态方法getInstance().***(); 其中*** 为ApiStore中定义的请求方法
28 | */
29 |
30 | public class HttpClient {
31 |
32 | private static final int CONNECT_TIME_OUT = 3000;
33 | private static final int READ_TIME_OUT = 5000;
34 | private static final int WRITE_TIME_OUT = 5000;
35 |
36 | private static Retrofit retrofit = null;
37 |
38 | private Context mContext;
39 |
40 | public HttpClient(Context context) {
41 | mContext = context;
42 | }
43 |
44 | public static ApiStores getInstance() {
45 | Retrofit retrofit = getClient();
46 | return retrofit.create(ApiStores.class);
47 | }
48 |
49 |
50 | private static Retrofit getClient() {
51 | if (retrofit == null) {
52 | OkHttpClient.Builder builder = new OkHttpClient.Builder();
53 | // 缓存设置
54 | setCacheConfig(builder);
55 | // 公共参数
56 | // builder.addInterceptor(new AddQueryParameterInterceptor());
57 | // https设置
58 | setHttpsConfig(builder);
59 | //设置超时和重连
60 | setTimeOutConfig(builder);
61 | //错误重连
62 | builder.retryOnConnectionFailure(true);
63 | //Log信息拦截器,debug模式下打印log
64 | String BASE_URL = setLogConfig(builder);
65 | OkHttpClient okHttpClient = builder.build();
66 | retrofit = new Retrofit.Builder()
67 | .baseUrl(BASE_URL)
68 | .addConverterFactory(GsonConverterFactory.create())
69 | .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
70 | .client(okHttpClient)
71 | .build();
72 | }
73 |
74 | return retrofit;
75 | }
76 |
77 | private static void setHttpsConfig(OkHttpClient.Builder builder) {
78 | HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);
79 | builder.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager);
80 | }
81 |
82 | @NonNull
83 | private static String setLogConfig(OkHttpClient.Builder builder) {
84 | String BASE_URL;
85 | BASE_URL = API_DEBUG_SERVER_URL;
86 | LoggingInterceptor interceptor = new LoggingInterceptor();
87 | interceptor.setLevel(LoggingInterceptor.Level.BODY);
88 | builder.addInterceptor(interceptor);
89 | return BASE_URL;
90 | }
91 |
92 | private static void setCacheConfig(OkHttpClient.Builder builder) {
93 | File cacheFile = new File(ColumnApplication.getContext().getExternalCacheDir(), "ColumnCache");
94 | Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
95 | builder.cache(cache).addInterceptor(new CacheInterceptor());
96 | }
97 |
98 | private static void setTimeOutConfig(OkHttpClient.Builder builder) {
99 | builder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.MILLISECONDS);
100 | builder.readTimeout(READ_TIME_OUT, TimeUnit.MILLISECONDS);
101 | builder.writeTimeout(WRITE_TIME_OUT, TimeUnit.MILLISECONDS);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/http/HttpsUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.http;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.security.KeyManagementException;
6 | import java.security.KeyStore;
7 | import java.security.KeyStoreException;
8 | import java.security.NoSuchAlgorithmException;
9 | import java.security.UnrecoverableKeyException;
10 | import java.security.cert.CertificateException;
11 | import java.security.cert.CertificateFactory;
12 | import java.security.cert.X509Certificate;
13 |
14 | import javax.net.ssl.HostnameVerifier;
15 | import javax.net.ssl.KeyManager;
16 | import javax.net.ssl.KeyManagerFactory;
17 | import javax.net.ssl.SSLContext;
18 | import javax.net.ssl.SSLSession;
19 | import javax.net.ssl.SSLSocketFactory;
20 | import javax.net.ssl.TrustManager;
21 | import javax.net.ssl.TrustManagerFactory;
22 | import javax.net.ssl.X509TrustManager;
23 |
24 | /**
25 | * Created by wangshijia on 15/12/14 上午10:45.
26 | * Copyright (c) 2017. alpha, Inc. All rights reserved.
27 | * ex: 鸿洋关于Https的封装 默认采用无证书验证
28 | */
29 | public class HttpsUtils {
30 |
31 | public static class SSLParams {
32 | public SSLSocketFactory sSLSocketFactory;
33 | public X509TrustManager trustManager;
34 | }
35 |
36 | public static SSLParams getSslSocketFactory(InputStream[] certificates, InputStream bksFile, String password) {
37 | SSLParams sslParams = new SSLParams();
38 | try {
39 | TrustManager[] trustManagers = prepareTrustManager(certificates);
40 | KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
41 | SSLContext sslContext = SSLContext.getInstance("TLS");
42 | X509TrustManager trustManager = null;
43 | if (trustManagers != null) {
44 | trustManager = new MyTrustManager(chooseTrustManager(trustManagers));
45 | } else {
46 | trustManager = new UnSafeTrustManager();
47 | }
48 | sslContext.init(keyManagers, new TrustManager[]{trustManager}, null);
49 | sslParams.sSLSocketFactory = sslContext.getSocketFactory();
50 | sslParams.trustManager = trustManager;
51 | return sslParams;
52 | } catch (NoSuchAlgorithmException e) {
53 | throw new AssertionError(e);
54 | } catch (KeyManagementException e) {
55 | throw new AssertionError(e);
56 | } catch (KeyStoreException e) {
57 | throw new AssertionError(e);
58 | }
59 | }
60 |
61 | private class UnSafeHostnameVerifier implements HostnameVerifier {
62 | @Override
63 | public boolean verify(String hostname, SSLSession session) {
64 | return true;
65 | }
66 | }
67 |
68 | private static class UnSafeTrustManager implements X509TrustManager {
69 | @Override
70 | public void checkClientTrusted(X509Certificate[] chain, String authType)
71 | throws CertificateException {
72 | }
73 |
74 | @Override
75 | public void checkServerTrusted(X509Certificate[] chain, String authType)
76 | throws CertificateException {
77 | }
78 |
79 | @Override
80 | public X509Certificate[] getAcceptedIssuers() {
81 | return new X509Certificate[]{};
82 | }
83 | }
84 |
85 | private static TrustManager[] prepareTrustManager(InputStream... certificates) {
86 | if (certificates == null || certificates.length <= 0) return null;
87 | try {
88 |
89 | CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
90 | KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
91 | keyStore.load(null);
92 | int index = 0;
93 | for (InputStream certificate : certificates) {
94 | String certificateAlias = Integer.toString(index++);
95 | keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
96 | try {
97 | if (certificate != null)
98 | certificate.close();
99 | } catch (IOException e) {
100 | }
101 | }
102 | TrustManagerFactory trustManagerFactory = null;
103 |
104 | trustManagerFactory = TrustManagerFactory.
105 | getInstance(TrustManagerFactory.getDefaultAlgorithm());
106 | trustManagerFactory.init(keyStore);
107 |
108 | TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
109 |
110 | return trustManagers;
111 | } catch (NoSuchAlgorithmException e) {
112 | e.printStackTrace();
113 | } catch (CertificateException e) {
114 | e.printStackTrace();
115 | } catch (KeyStoreException e) {
116 | e.printStackTrace();
117 | } catch (Exception e) {
118 | e.printStackTrace();
119 | }
120 | return null;
121 |
122 | }
123 |
124 | private static KeyManager[] prepareKeyManager(InputStream bksFile, String password) {
125 | try {
126 | if (bksFile == null || password == null) return null;
127 |
128 | KeyStore clientKeyStore = KeyStore.getInstance("BKS");
129 | clientKeyStore.load(bksFile, password.toCharArray());
130 | KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
131 | keyManagerFactory.init(clientKeyStore, password.toCharArray());
132 | return keyManagerFactory.getKeyManagers();
133 |
134 | } catch (KeyStoreException e) {
135 | e.printStackTrace();
136 | } catch (NoSuchAlgorithmException e) {
137 | e.printStackTrace();
138 | } catch (UnrecoverableKeyException e) {
139 | e.printStackTrace();
140 | } catch (CertificateException e) {
141 | e.printStackTrace();
142 | } catch (IOException e) {
143 | e.printStackTrace();
144 | } catch (Exception e) {
145 | e.printStackTrace();
146 | }
147 | return null;
148 | }
149 |
150 | private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) {
151 | for (TrustManager trustManager : trustManagers) {
152 | if (trustManager instanceof X509TrustManager) {
153 | return (X509TrustManager) trustManager;
154 | }
155 | }
156 | return null;
157 | }
158 |
159 |
160 | private static class MyTrustManager implements X509TrustManager {
161 | private X509TrustManager defaultTrustManager;
162 | private X509TrustManager localTrustManager;
163 |
164 | public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException {
165 | TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
166 | var4.init((KeyStore) null);
167 | defaultTrustManager = chooseTrustManager(var4.getTrustManagers());
168 | this.localTrustManager = localTrustManager;
169 | }
170 |
171 |
172 | @Override
173 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
174 |
175 | }
176 |
177 | @Override
178 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
179 | try {
180 | defaultTrustManager.checkServerTrusted(chain, authType);
181 | } catch (CertificateException ce) {
182 | localTrustManager.checkServerTrusted(chain, authType);
183 | }
184 | }
185 |
186 |
187 | @Override
188 | public X509Certificate[] getAcceptedIssuers() {
189 | return new X509Certificate[0];
190 | }
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/http/callback/CommonCallback.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.http.callback;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | import com.example.wsj.splashdemo.ColumnApplication;
8 | import com.example.wsj.splashdemo.UserCenter;
9 | import com.example.wsj.splashdemo.activities.LoginActivity;
10 | import com.example.wsj.splashdemo.entity.Attachment;
11 | import com.example.wsj.splashdemo.entity.Common;
12 |
13 | import java.net.ConnectException;
14 | import java.net.SocketTimeoutException;
15 |
16 | import retrofit2.Call;
17 | import retrofit2.Callback;
18 | import retrofit2.Response;
19 |
20 | import static com.example.wsj.splashdemo.entity.Constants.EXTRA_KEY_EXIT;
21 |
22 | /**
23 | * Created by wangshijia on 2017/2/3 下午2:37.
24 | * Copyright (c) 2017. alpha, Inc. All rights reserved.
25 | */
26 |
27 | public abstract class CommonCallback implements Callback {
28 |
29 | @Override
30 | public void onResponse(Call call, Response response) {
31 | if (response.raw().code() == 200) {
32 | T body = response.body();
33 | if (body != null) {
34 | if (body.isValid()) {
35 | if (body.attachment != null) {
36 | onSuccess(body.attachment);
37 | } else {
38 | onError("Attachment 对象为空");
39 | }
40 | } else {
41 | if (body.isNeedOut()) {//token过期重新登录
42 | gotoLogInActivity();
43 |
44 | } else if (body.isServiceBlock()) {
45 | } else {
46 | onError(body.message);
47 | }
48 | }
49 | } else {
50 | onError(response.message());
51 | }
52 | } else {
53 | onFailure(call, new RuntimeException("response error,detail = " + response.raw().toString()));
54 | }
55 | }
56 |
57 | private void gotoLogInActivity() {
58 | Context context = ColumnApplication.getContext();
59 | UserCenter.getInstance().setToken(null);//清楚token
60 | Intent intent = new Intent(context, LoginActivity.class);
61 | intent.putExtra(EXTRA_KEY_EXIT, true);
62 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
63 | context.startActivity(intent);
64 | }
65 |
66 | @Override
67 | public void onFailure(Call call, Throwable t) {
68 | if (t instanceof SocketTimeoutException) {
69 | return;
70 | } else if (t instanceof ConnectException) {
71 | onError(t.getMessage());
72 | } else if (t instanceof RuntimeException) {
73 | onError(t.getMessage());
74 | } else {
75 | onError(t.getMessage());
76 | }
77 | call.cancel();
78 | }
79 |
80 | public abstract void onSuccess(Attachment attachment);
81 |
82 | public void onError(String message) {
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/http/interceptor/AddQueryParameterInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.http.interceptor;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.example.wsj.splashdemo.UserCenter;
6 |
7 | import java.io.IOException;
8 |
9 | import okhttp3.HttpUrl;
10 | import okhttp3.Interceptor;
11 | import okhttp3.Request;
12 | import okhttp3.Response;
13 |
14 | /**
15 | * Created by wangshijia on 2017/2/3 下午3:54.
16 | * Copyright (c) 2017. alpha, Inc. All rights reserved.
17 | */
18 |
19 | public class AddQueryParameterInterceptor implements Interceptor {
20 | @Override
21 | public Response intercept(Chain chain) throws IOException {
22 | Request originalRequest = chain.request();
23 | Request request;
24 | //String method = originalRequest.method();
25 | // Headers headers = originalRequest.headers();
26 | String token = UserCenter.getInstance().getToken();
27 | String uid = String.valueOf(UserCenter.getInstance().getCurrentUser().uid);
28 | HttpUrl modifiedUrl = originalRequest.url().newBuilder()
29 | .addQueryParameter("token", TextUtils.isEmpty(UserCenter.getInstance().getToken()) ? "" : token)
30 | .addQueryParameter("uid", UserCenter.getInstance().getCurrentUser().uid == 0 ? "" : uid)
31 | .build();
32 | request = originalRequest.newBuilder().url(modifiedUrl).build();
33 |
34 | return chain.proceed(request);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/http/interceptor/CacheInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.http.interceptor;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.example.wsj.splashdemo.ColumnApplication;
6 | import com.example.wsj.splashdemo.utils.NetWorkUtils;
7 |
8 | import java.io.IOException;
9 |
10 | import okhttp3.CacheControl;
11 | import okhttp3.Interceptor;
12 | import okhttp3.Request;
13 | import okhttp3.Response;
14 |
15 | /**
16 | * Created by wangshijia on 2017/2/3 下午3:55.
17 | * Copyright (c) 2017. alpha, Inc. All rights reserved.
18 | */
19 | //该缓存方案是有网的时候从服务器取没网的时候就从本地取,如果并未从服务器取过,那么就
20 | public class CacheInterceptor implements Interceptor {
21 | @Override
22 | public Response intercept(Chain chain) throws IOException {
23 | Request request = chain.request();
24 | if (!NetWorkUtils.isNetWorkAvailable(ColumnApplication.getContext())) {//如果网络不可用
25 | request = request.newBuilder()
26 | .cacheControl(CacheControl.FORCE_CACHE)//强制从缓存取 对应的强制从网络取为CacheControl.FORCE_NETWORK();
27 | .build();
28 | }
29 |
30 | Response response = chain.proceed(request);
31 |
32 | if (NetWorkUtils.isNetWorkAvailable(ColumnApplication.getContext()) ) {
33 | int maxAge = 0;
34 | // 有网络时 设置缓存超时时间0个小时
35 | // String cacheControl = request.cacheControl().toString();
36 | // 如果单个请求不同请在请求中写上Cache-control头则按照对应的配置进行本地缓存时间配置
37 | String cacheControl = request.cacheControl().toString();
38 | if (TextUtils.isEmpty(cacheControl)) {
39 | response.newBuilder()
40 | .header("Cache-Control", "public, max-age=" + maxAge)
41 | .removeHeader("Pragma")// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
42 | .build();
43 | } else {
44 | response.newBuilder()
45 | .header("Cache-Control", cacheControl)
46 | .removeHeader("Pragma")// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
47 | .build();
48 | }
49 | } else {
50 | // 无网络时,设置超时为4周
51 | int maxStale = 60 * 60 * 24 * 28;
52 | response.newBuilder()
53 | .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
54 | .removeHeader("Pragma")
55 | .build();
56 | }
57 | return response;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/http/interceptor/LoggingInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.http.interceptor;
2 |
3 | import java.io.EOFException;
4 | import java.io.IOException;
5 | import java.nio.charset.Charset;
6 | import java.nio.charset.UnsupportedCharsetException;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | import okhttp3.Headers;
10 | import okhttp3.Interceptor;
11 | import okhttp3.MediaType;
12 | import okhttp3.MultipartBody;
13 | import okhttp3.Protocol;
14 | import okhttp3.Request;
15 | import okhttp3.RequestBody;
16 | import okhttp3.Response;
17 | import okhttp3.ResponseBody;
18 | import okhttp3.internal.http.HttpHeaders;
19 | import okhttp3.internal.platform.Platform;
20 | import okio.Buffer;
21 | import okio.BufferedSource;
22 |
23 | import static okhttp3.internal.platform.Platform.INFO;
24 |
25 |
26 | /**
27 | * Created by wangshijia on 2017/2/4 下午4:02.
28 | * Copyright (c) 2017. alpha, Inc. All rights reserved.
29 | */
30 |
31 | public class LoggingInterceptor implements Interceptor {
32 | private static final Charset UTF8 = Charset.forName("UTF-8");
33 |
34 | public enum Level {
35 | /** * No logs. */
36 | NONE,
37 | /** * Logs request and response lines. * * Example: *
{@code * --> POST /greeting HTTP/1.1 (3-byte body) * * <-- HTTP/1.1 200 OK (22ms, 6-byte body) * }
*/
38 | BASIC,
39 | /** * Logs request and response lines and their respective headers. * * Example: *
{@code * --> POST /greeting HTTP/1.1 * Host: example.com * Content-Type: plain/text * Content-Length: 3 * --> END POST * * <-- HTTP/1.1 200 OK (22ms) * Content-Type: plain/text * Content-Length: 6 * <-- END HTTP * }
*/
40 | HEADERS,
41 | /** * Logs request and response lines and their respective headers and bodies (if present). * * Example: *
{@code * --> POST /greeting HTTP/1.1 * Host: example.com * Content-Type: plain/text * Content-Length: 3 * * Hi? * --> END GET * * <-- HTTP/1.1 200 OK (22ms) * Content-Type: plain/text * Content-Length: 6 * * Hello! * <-- END HTTP * }
*/
42 | BODY
43 | }
44 |
45 | public interface Logger {
46 | void log(String message);
47 |
48 | /** * A {@link Logger} defaults output appropriate for the current platform. */
49 |
50 | Logger DEFAULT = new Logger() {
51 | @Override public void log(String message) {
52 | Platform.get().log(INFO, message, null);
53 | }
54 | };
55 | }
56 |
57 | public LoggingInterceptor() {
58 | this(Logger.DEFAULT);
59 | }
60 |
61 | public LoggingInterceptor(Logger logger) {
62 | this.logger = logger;
63 | }
64 |
65 | private final Logger logger;
66 |
67 | private volatile Level level = Level.BODY;
68 |
69 | /** * Change the level at which this interceptor logs. */
70 | public LoggingInterceptor setLevel(Level level) {
71 | if (level == null)
72 | throw new NullPointerException("level == null. Use Level.NONE instead.");
73 | this.level = level;
74 | return this;
75 | }
76 |
77 | @Override
78 | public Response intercept(Chain chain) throws IOException {
79 | Level level = this.level;
80 |
81 | Request request = chain.request();
82 | if (level == Level.NONE) {
83 | return chain.proceed(request);
84 | }
85 |
86 | boolean logBody = level == Level.BODY;
87 | boolean logHeaders = logBody || level == Level.HEADERS;
88 |
89 | RequestBody requestBody = request.body();
90 | boolean hasRequestBody = requestBody != null;
91 |
92 | String requestStartMessage = request.method() + ' ' + request.url();
93 | if (!logHeaders && hasRequestBody) {
94 | requestStartMessage += " (" + requestBody.contentLength() + "-byte body)";
95 | }
96 | logger.log("----------------request start----------------");
97 | logger.log(requestStartMessage);
98 |
99 | if (logHeaders) {
100 | if (hasRequestBody) {
101 | // Request body headers are only present when installed as a network interceptor.
102 | // Forcethem to be included (when available) so there values are known.
103 | if (requestBody.contentType() != null) {
104 | logger.log("Content-Type: " + requestBody.contentType());
105 | }
106 | if (requestBody.contentLength() != -1) {
107 | logger.log("Content-Length: " + requestBody.contentLength());
108 | }
109 | }
110 |
111 | Headers headers = request.headers();
112 | for (int i = 0, count = headers.size(); i < count; i++) {
113 | String name = headers.name(i);
114 | // Skip headers from the request body as they are explicitly logged above.
115 | if (skipHeader(name)) {
116 | logger.log(name + ": " + headers.value(i));
117 | }
118 | }
119 |
120 | if (!logBody || !hasRequestBody) {
121 | } else if (bodyEncoded(request.headers())) {
122 | } else if (request.body() instanceof MultipartBody) {
123 | logger.log("content: " + "too many bytes, ignored");
124 | } else {
125 | Buffer buffer = new Buffer();
126 | requestBody.writeTo(buffer);
127 |
128 | Charset charset = UTF8;
129 | MediaType contentType = requestBody.contentType();
130 | if (contentType != null) {
131 | contentType.charset(UTF8);
132 | }
133 | logger.log("content: " + buffer.readString(charset));
134 | }
135 | logger.log("----------------request end------------------");
136 | }
137 |
138 | long startNs = System.nanoTime();
139 | Response response;
140 | try {
141 | response = chain.proceed(request);
142 | logger.log("----------------response start---------------");
143 | } catch (Exception e) {
144 | logger.log("HTTP FAILED: " + e);
145 | logger.log("----------------response end-----------------");
146 | throw e;
147 | }
148 | long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
149 | ResponseBody responseBody = response.body();
150 | long contentLength = responseBody.contentLength();
151 | logger.log(protocol(response.protocol()) + " " + response.request().url());
152 | logger.log("info: " + "code:" + response.code() + " " + "result:" + response.message() +
153 | " times:" + tookMs + "ms");
154 |
155 | if (logHeaders) {
156 |
157 | if (!logBody || !HttpHeaders.hasBody(response)) {
158 | } else if (bodyEncoded(response.headers())) {
159 | } else {
160 | BufferedSource source = responseBody.source();
161 | source.request(Long.MAX_VALUE); // Buffer the entire body.
162 | Buffer buffer = source.buffer();
163 |
164 | Charset charset = UTF8;
165 | MediaType contentType = responseBody.contentType();
166 | if (contentType != null) {
167 | try {
168 | charset = contentType.charset(UTF8);
169 | } catch (UnsupportedCharsetException e) {
170 | logger.log("");
171 | logger.log("Couldn't decode the response body; charset is likely " +
172 | "malformed.");
173 | logger.log("----------------response end-----------------");
174 | return response;
175 | }
176 | }
177 |
178 | if (!isPlaintext(buffer)) {
179 | logger.log("");
180 | logger.log("----------------response end-----------------");
181 | return response;
182 | }
183 |
184 | if (contentLength != 0) {
185 | logger.log("");
186 | logger.log("content: " + buffer.clone().readString(charset));
187 | }
188 | }
189 | }
190 | logger.log("----------------response end-----------------");
191 | return response;
192 | }
193 |
194 | private boolean skipHeader(String name) {
195 | return !"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase
196 | (name) && !"Host".equalsIgnoreCase(name) && !"Accept-Encoding"
197 | .equalsIgnoreCase(name) && !"User-Agent".equalsIgnoreCase(name) &&
198 | !"Connection".equalsIgnoreCase(name);
199 | }
200 |
201 | private boolean bodyEncoded(Headers headers) {
202 | String contentEncoding = headers.get("Content-Encoding");
203 | return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity");
204 | }
205 |
206 | private static String protocol(Protocol protocol) {
207 | return protocol == Protocol.HTTP_1_0 ? "HTTP/1.0" : "HTTP/1.1";
208 | }
209 |
210 | /** * Returns true if the body in question probably contains human readable text. Uses a small * sample * of code points to detect unicode control characters commonly used in binary file signatures. */
211 | private static boolean isPlaintext(Buffer buffer) {
212 | try {
213 | Buffer prefix = new Buffer();
214 | long byteCount = buffer.size() < 64 ? buffer.size() : 64;
215 | buffer.copyTo(prefix, 0, byteCount);
216 | for (int i = 0; i < 16; i++) {
217 | if (prefix.exhausted()) {
218 | break;
219 | }
220 | int codePoint = prefix.readUtf8CodePoint();
221 | if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
222 | return false;
223 | }
224 | }
225 | return true;
226 | } catch (EOFException e) {
227 | return false; // Truncated UTF-8 sequence.
228 | }
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/service/SplashDownLoadService.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.service;
2 |
3 | import android.app.IntentService;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.text.TextUtils;
9 | import android.util.Log;
10 |
11 | import com.example.wsj.splashdemo.entity.Common;
12 | import com.example.wsj.splashdemo.entity.Constants;
13 | import com.example.wsj.splashdemo.entity.Splash;
14 | import com.example.wsj.splashdemo.http.HttpClient;
15 | import com.example.wsj.splashdemo.utils.DownLoadUtils;
16 | import com.example.wsj.splashdemo.utils.SerializableUtils;
17 |
18 | import java.io.File;
19 | import java.io.IOException;
20 | import java.util.ArrayList;
21 |
22 | import io.reactivex.android.schedulers.AndroidSchedulers;
23 | import io.reactivex.functions.Consumer;
24 | import io.reactivex.schedulers.Schedulers;
25 |
26 | import static com.example.wsj.splashdemo.utils.SerializableUtils.readObject;
27 |
28 | public class SplashDownLoadService extends IntentService {
29 |
30 | private Splash mScreen;
31 | public static final int TYPE_ANDROID = 1;
32 | private static final String SPLASH_FILE_NAME = "splash.srr";
33 | public SplashDownLoadService() {
34 | super("SplashDownLoad");
35 | }
36 |
37 | public static void startDownLoadSplashImage(Context context, String action) {
38 | Intent intent = new Intent(context, SplashDownLoadService.class);
39 | intent.putExtra(Constants.EXTRA_DOWNLOAD, action);
40 | context.startService(intent);
41 | }
42 |
43 | @Override
44 | protected void onHandleIntent(@Nullable Intent intent) {
45 | if (intent != null) {
46 | String action = intent.getStringExtra(Constants.EXTRA_DOWNLOAD);
47 | if (action.equals(Constants.DOWNLOAD_SPLASH)) {
48 | loadSplashNetDate();
49 | }
50 | }
51 | }
52 |
53 | private void loadSplashNetDate() {
54 | HttpClient.getInstance()
55 | .getSplashImage(TYPE_ANDROID)
56 | .subscribeOn(Schedulers.io())
57 | .observeOn(AndroidSchedulers.mainThread())
58 | .subscribe(new Consumer() {
59 | @Override
60 | public void accept(@NonNull Common common) throws Exception {
61 | if (common.isValid() && common.attachment != null) {
62 | mScreen = common.attachment.flashScreen;
63 | Splash splashLocal = getSplashLocal();
64 | if (mScreen != null) {
65 | if (splashLocal == null) {
66 | Log.d("SplashDemo","splashLocal 为空导致下载");
67 | startDownLoadSplash(Constants.SPLASH_PATH, mScreen.burl);
68 | } else if (isNeedDownLoad(splashLocal.savePath, mScreen.burl)) {
69 | Log.d("SplashDemo","isNeedDownLoad 导致下载");
70 | startDownLoadSplash(Constants.SPLASH_PATH, mScreen.burl);
71 | }
72 | } else {
73 | if (splashLocal != null) {
74 | File splashFile = SerializableUtils.getSerializableFile(Constants.SPLASH_PATH, Constants.SPLASH_FILE_NAME);
75 | if (splashFile.exists()) {
76 | splashFile.delete();
77 | Log.d("SplashDemo","mScreen为空删除本地文件");
78 | }
79 | }
80 | }
81 | }
82 | }
83 | }, new Consumer() {
84 | @Override
85 | public void accept(@NonNull Throwable throwable) throws Exception {
86 |
87 | }
88 | });
89 | }
90 |
91 | private Splash getSplashLocal() {
92 | Splash splash = null;
93 | try {
94 | File splashFile = SerializableUtils.getSerializableFile(Constants.SPLASH_PATH, SPLASH_FILE_NAME);
95 | splash = (Splash) readObject(splashFile);
96 | } catch (IOException e) {
97 | e.printStackTrace();
98 | }
99 | return splash;
100 | }
101 |
102 | /**
103 | * @param path 本地存储的图片绝对路径
104 | * @param url 网络获取url
105 | * @return 比较储存的 图片名称的哈希值与 网络获取的哈希值是否相同
106 | */
107 | private boolean isNeedDownLoad(String path, String url) {
108 | if (TextUtils.isEmpty(path)) {
109 | Log.d("SplashDemo","本地url " + TextUtils.isEmpty(path));
110 | Log.d("SplashDemo","本地url " + TextUtils.isEmpty(url));
111 | return true;
112 | }
113 | File file = new File(path);
114 | if (!file.exists()) {
115 | Log.d("SplashDemo","本地file " + file.exists());
116 | return true;
117 | }
118 | if (getImageName(path).hashCode() != getImageName(url).hashCode()) {
119 | Log.d("SplashDemo","path hashcode " + getImageName(path) + " " + getImageName(path).hashCode());
120 | Log.d("SplashDemo","url hashcode " + getImageName(url) + " " + getImageName(url).hashCode());
121 | return true;
122 | }
123 | return false;
124 | }
125 |
126 |
127 | private String getImageName(String url) {
128 | if (TextUtils.isEmpty(url)) {
129 | return "";
130 | }
131 | String[] split = url.split("/");
132 | String nameWith_ = split[split.length - 1];
133 | String[] split1 = nameWith_.split("\\.");
134 | return split1[0];
135 | }
136 |
137 | private void startDownLoadSplash(String splashPath, String burl) {
138 | DownLoadUtils.downLoad(splashPath, new DownLoadUtils.DownLoadInterFace() {
139 | @Override
140 | public void afterDownLoad(ArrayList savePaths) {
141 | if (savePaths.size() == 1) {
142 | Log.d("SplashDemo","闪屏页面下载完成" + savePaths);
143 | if (mScreen != null) {
144 | mScreen.savePath = savePaths.get(0);
145 | }
146 | SerializableUtils.writeObject(mScreen, Constants.SPLASH_PATH + "/" + SPLASH_FILE_NAME);
147 | } else {
148 | Log.d("SplashDemo","闪屏页面下载失败" + savePaths);
149 | }
150 | }
151 | }, burl);
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/utils/DownLoadUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.utils;
2 |
3 | import android.os.AsyncTask;
4 | import android.os.Environment;
5 | import android.text.TextUtils;
6 |
7 | import java.io.File;
8 | import java.io.FileOutputStream;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.net.HttpURLConnection;
12 | import java.net.URL;
13 | import java.util.ArrayList;
14 |
15 | /**
16 | * Created by wangshijia on 2017/6/12 下午3:29.
17 | * Copyright (c) 2017. alpha, Inc. All rights reserved.
18 | */
19 |
20 | public class DownLoadUtils {
21 |
22 | public interface DownLoadInterFace {
23 | void afterDownLoad(ArrayList savePaths);
24 | }
25 |
26 | public static void downLoad(String savePath, DownLoadInterFace downLoadInterFace, String... download) {
27 | new DownLoadTask(savePath, downLoadInterFace).execute(download);
28 | }
29 |
30 | private static class DownLoadTask extends AsyncTask> {
31 | private String mSavePath;
32 | private DownLoadInterFace mDownLoadInterFace;
33 |
34 | private DownLoadTask(String savePath, DownLoadInterFace downLoadTask) {
35 | this.mSavePath = savePath;
36 | this.mDownLoadInterFace = downLoadTask;
37 | }
38 |
39 | @Override
40 | protected ArrayList doInBackground(String... params) {
41 | ArrayList names = new ArrayList<>();
42 | for (String url : params) {
43 | if (!TextUtils.isEmpty(url)) {
44 | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
45 | // 获得存储卡的路径
46 | FileOutputStream fos = null;
47 | InputStream is = null;
48 | try {
49 | URL downUrl = new URL(url);
50 | // 创建连接
51 | HttpURLConnection conn = (HttpURLConnection) downUrl.openConnection();
52 | conn.connect();
53 | // 创建输入流
54 | is = conn.getInputStream();
55 | File file = new File(mSavePath);
56 | // 判断文件目录是否存在
57 | if (!file.exists()) {
58 | file.mkdirs();
59 | }
60 |
61 | String[] split = url.split("/");
62 | String fileName = split[split.length - 1];
63 | File mApkFile = new File(mSavePath, fileName);
64 | names.add(mApkFile.getAbsolutePath());
65 | fos = new FileOutputStream(mApkFile, false);
66 | int count = 0;
67 | // 缓存
68 | byte buf[] = new byte[1024];
69 | while (true) {
70 | int read = is.read(buf);
71 | if (read == -1) {
72 | break;
73 | }
74 | fos.write(buf, 0, read);
75 | count += read;
76 | publishProgress(count);
77 | }
78 | fos.flush();
79 |
80 | } catch (Exception e) {
81 | e.printStackTrace();
82 | } finally {
83 | try {
84 | if (is != null) {
85 | is.close();
86 | }
87 | if (fos != null) {
88 | fos.close();
89 | }
90 | } catch (IOException e1) {
91 | e1.printStackTrace();
92 | }
93 | }
94 | }
95 | }
96 | }
97 | return names;
98 | }
99 |
100 | @Override
101 | protected void onPostExecute(ArrayList strings) {
102 | super.onPostExecute(strings);
103 | if (mDownLoadInterFace != null) {
104 | mDownLoadInterFace.afterDownLoad(strings);
105 | }
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/utils/NetWorkUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.utils;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 |
7 | /**
8 | * Created by wangshijia on 2017/2/3 下午4:00.
9 | * Copyright (c) 2017. alpha, Inc. All rights reserved.
10 | */
11 |
12 | public class NetWorkUtils {
13 |
14 | public static boolean isNetWorkAvailable(Context context) {
15 | ConnectivityManager connectivity = (ConnectivityManager) context
16 | .getSystemService(Context.CONNECTIVITY_SERVICE);
17 | NetworkInfo info = connectivity.getActiveNetworkInfo();
18 | return !(info == null || info.getState() != NetworkInfo.State.CONNECTED);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/wsj/splashdemo/utils/SerializableUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo.utils;
2 |
3 | import android.util.Log;
4 |
5 | import java.io.EOFException;
6 | import java.io.File;
7 | import java.io.FileInputStream;
8 | import java.io.FileOutputStream;
9 | import java.io.IOException;
10 | import java.io.ObjectInputStream;
11 | import java.io.ObjectOutputStream;
12 | import java.io.Serializable;
13 |
14 | /**
15 | * Created by wangshijia on 2017/6/12 下午1:18.
16 | * Copyright (c) 2017. alpha, Inc. All rights reserved.
17 | */
18 |
19 | public class SerializableUtils {
20 |
21 | public static Object readObject(File file) {
22 | ObjectInputStream in = null;
23 | T t = null;
24 | try {
25 | in = new ObjectInputStream(new FileInputStream(file));
26 | t = (T) in.readObject();
27 | } catch (EOFException e) {
28 | // ... this is fine
29 | } catch (IOException | ClassNotFoundException e) {
30 | e.printStackTrace();
31 | } finally {
32 | try {
33 | if (in != null) in.close();
34 | } catch (IOException e) {
35 | e.printStackTrace();
36 | }
37 | }
38 | return t;
39 | }
40 |
41 | public static boolean writeObject(T t, String fileName) {
42 | ObjectOutputStream out = null;
43 | try {
44 | out = new ObjectOutputStream(new FileOutputStream(fileName));
45 | out.writeObject(t);
46 | Log.d("SplashDemo","序列化成功 " + t.toString());
47 | return true;
48 | } catch (IOException e) {
49 | e.printStackTrace();
50 | Log.d("SplashDemo","序列化失败 " + e.getMessage());
51 | return false;
52 | } finally {
53 | try {
54 | if (out != null) out.close();
55 | } catch (IOException e) {
56 | e.printStackTrace();
57 | }
58 | }
59 | }
60 |
61 | public static File getSerializableFile(String rootPath, String fileName) throws IOException {
62 | File file = new File(rootPath);
63 | if (!file.exists()) file.mkdirs();
64 | File serializable = new File(file, fileName);
65 | if (!serializable.exists()) serializable.createNewFile();
66 | return serializable;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_splash_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
4 |
10 |
11 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/gank10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xxhdpi/gank10.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/gank15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xxhdpi/gank15.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/gank8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xxhdpi/gank8.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/icon_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xxhdpi/icon_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/splash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xxhdpi/splash.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SplashDemo
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/test/java/com/example/wsj/splashdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.wsj.splashdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | mavenCentral()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:2.3.3'
10 | classpath 'com.jakewharton:butterknife-gradle-plugin:8.5.1'
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | jcenter()
19 | maven { url "https://jitpack.io" }
20 | }
21 | }
22 |
23 | task clean(type: Delete) {
24 | delete rootProject.buildDir
25 | }
26 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jun 21 12:03:07 CST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/效果图.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImportEffort/SplashActivityDemo/084fdab4f03fd5781c7f90a4af005be89c47d1e6/效果图.gif
--------------------------------------------------------------------------------