diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser
deleted file mode 100644
index 9e15848a1..000000000
Binary files a/.idea/caches/gradle_models.ser and /dev/null differ
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index ae78c113f..681f41ae2 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,6 +1,9 @@
+
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 10b5291fa..317a96c49 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,48 +1,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/android-sdk.iml b/android-sdk.iml
index ad4065b84..74149ab95 100644
--- a/android-sdk.iml
+++ b/android-sdk.iml
@@ -13,7 +13,7 @@
-
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index e8e190f32..e7ae1bf48 100644
--- a/build.gradle
+++ b/build.gradle
@@ -10,7 +10,6 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
-
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
diff --git a/library/src/main/java/com/qiniu/android/common/Constants.java b/library/src/main/java/com/qiniu/android/common/Constants.java
index 810ce638a..7345431e1 100644
--- a/library/src/main/java/com/qiniu/android/common/Constants.java
+++ b/library/src/main/java/com/qiniu/android/common/Constants.java
@@ -2,7 +2,7 @@
public final class Constants {
- public static final String VERSION = "7.5.0";
+ public static final String VERSION = "7.5.1";
public static final String UTF_8 = "utf-8";
}
diff --git a/library/src/main/java/com/qiniu/android/http/DnsPrefetcher.java b/library/src/main/java/com/qiniu/android/http/DnsPrefetcher.java
index fe27293a6..34b8f72fb 100644
--- a/library/src/main/java/com/qiniu/android/http/DnsPrefetcher.java
+++ b/library/src/main/java/com/qiniu/android/http/DnsPrefetcher.java
@@ -23,6 +23,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
/**
*
@@ -33,9 +34,11 @@ public class DnsPrefetcher {
public static DnsPrefetcher dnsPrefetcher = null;
private static String token;
+ private static Configuration config;
private static ConcurrentHashMap> mConcurrentHashMap = new ConcurrentHashMap>();
private static List mHosts = new ArrayList();
+ private static AtomicReference mDnsCacheKey = new AtomicReference();
private DnsPrefetcher() {
@@ -52,10 +55,33 @@ public static DnsPrefetcher getDnsPrefetcher() {
return dnsPrefetcher;
}
- public DnsPrefetcher init(String token) throws UnknownHostException {
+ /**
+ * 不用判断是否预取,每次调用UploadManager都直接预取一次。
+ * uploadManager只会new一次,但是uploadManager.put方法有多次,如果期间网络发生变化
+ * 这个方法预取的结果应该被ConcurrentHashMap自动覆盖
+ */
+ public void localFetch() {
+ List localHosts = new ArrayList();
+ //local
+ List listZoneinfo = getLocalZone();
+ for (ZoneInfo zone : listZoneinfo) {
+ for (String host : zone.upDomainsList) {
+ localHosts.add(host);
+ }
+ }
+ localHosts.add(Config.preQueryHost);
+
+ if (localHosts != null && localHosts.size() > 0)
+ preFetch(localHosts);
+ }
+
+
+ public DnsPrefetcher init(String token, Configuration config) throws UnknownHostException {
this.token = token;
- preHosts();
- preFetch();
+ this.config = config;
+ List preHosts = preHosts();
+ if (preHosts != null && preHosts.size() > 0)
+ preFetch(preHosts);
return this;
}
@@ -86,43 +112,47 @@ public List getInetAddressByHost(String host) {
return mConcurrentHashMap.get(host);
}
- private void preHosts() {
+ private List preHosts() {
HashSet set = new HashSet();
-
+ List preHosts = new ArrayList<>();
//preQuery sync
ZoneInfo zoneInfo = getPreQueryZone();
if (zoneInfo != null) {
for (String host : zoneInfo.upDomainsList) {
if (set.add(host))
- mHosts.add(host);
+ preHosts.add(host);
}
}
+
//local
List listZoneinfo = getLocalZone();
for (ZoneInfo zone : listZoneinfo) {
for (String host : zone.upDomainsList) {
if (set.add(host))
- mHosts.add(host);
+ preHosts.add(host);
}
}
if (set.add(Config.preQueryHost))
- mHosts.add(Config.preQueryHost);
+ preHosts.add(Config.preQueryHost);
+ return preHosts;
}
- private void preFetch() {
+ private void preFetch(List fetchHost) {
List rePreHosts = new ArrayList();
- for (String host : mHosts) {
+ for (String host : fetchHost) {
List inetAddresses = null;
try {
inetAddresses = okhttp3.Dns.SYSTEM.lookup(host);
mConcurrentHashMap.put(host, inetAddresses);
+ mHosts.add(host);
} catch (UnknownHostException e) {
e.printStackTrace();
rePreHosts.add(host);
}
}
- rePreFetch(rePreHosts, null);
+ if (rePreHosts.size() > 0)
+ rePreFetch(rePreHosts, null);
}
/**
@@ -151,6 +181,7 @@ private boolean rePreFetch(String host, Dns customeDns) {
inetAddresses = customeDns.lookup(host);
}
mConcurrentHashMap.put(host, inetAddresses);
+ mHosts.add(host);
return true;
} catch (UnknownHostException e) {
e.printStackTrace();
@@ -214,7 +245,11 @@ ZoneInfo preQueryIndex(DnsPrefetcher.ZoneIndex index) {
ResponseInfo getZoneJsonSync(DnsPrefetcher.ZoneIndex index) {
Client client = new Client();
- String address = "http://" + Config.preQueryHost + "/v2/query?ak=" + index.accessKey + "&bucket=" + index.bucket;
+ String schema = "https://";
+ if (!config.useHttps) {
+ schema = "http://";
+ }
+ String address = schema + Config.preQueryHost + "/v2/query?ak=" + index.accessKey + "&bucket=" + index.bucket;
return client.syncGet(address, null);
}
@@ -264,6 +299,33 @@ public boolean equals(Object obj) {
* @return true:重新预期并缓存, false:不需要重新预取和缓存
*/
public static boolean checkRePrefetchDns(String token, Configuration config) {
+ if (mDnsCacheKey.get() == null)
+ return true;
+
+ String currentTime = String.valueOf(System.currentTimeMillis());
+ String localip = AndroidNetwork.getHostIP();
+ String akScope = StringUtils.getAkAndScope(token);
+
+ if (currentTime == null || localip == null || akScope == null)
+ return true;
+ DnsCacheKey dnsCacheKey = (DnsCacheKey) mDnsCacheKey.get();
+ if (dnsCacheKey == null || dnsCacheKey.getCurrentTime() == null)
+ return true;
+ long cacheTime = (Long.parseLong(currentTime) - Long.parseLong(dnsCacheKey.getCurrentTime())) / 1000;
+ if (!localip.equals(dnsCacheKey.getLocalIp()) || cacheTime > config.dnsCacheTimeMs || !akScope.equals(dnsCacheKey.getAkScope())) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * uploadManager初始化时,加载本地缓存到内存
+ *
+ * @param config
+ * @return 如果不存在缓存返回true,需要重新预取;如果存在且满足使用,返回false
+ */
+ public static boolean recoverCache(Configuration config) {
Recorder recorder = null;
try {
recorder = new DnsCacheFile(Config.dnscacheDir);
@@ -285,15 +347,14 @@ public static boolean checkRePrefetchDns(String token, Configuration config) {
String currentTime = String.valueOf(System.currentTimeMillis());
String localip = AndroidNetwork.getHostIP();
- String akScope = StringUtils.getAkAndScope(token);
- if (currentTime == null || localip == null || akScope == null)
+ if (currentTime == null || localip == null)
return true;
long cacheTime = (Long.parseLong(currentTime) - Long.parseLong(cacheKey.getCurrentTime())) / 1000;
- if (!cacheKey.getLocalIp().equals(localip) || cacheTime > config.dnsCacheTimeMs || !cacheKey.getAkScope().equals(akScope)) {
+ if (!cacheKey.getLocalIp().equals(localip) || cacheTime > config.dnsCacheTimeMs) {
return true;
}
-
+ mDnsCacheKey.set(cacheKey);
return recoverDnsCache(data);
}
@@ -308,12 +369,16 @@ public static void startPrefetchDns(String token, Configuration config) {
String akScope = StringUtils.getAkAndScope(token);
if (currentTime == null || localip == null || akScope == null)
return;
- String cacheKey = new DnsCacheKey(currentTime, localip, akScope).toString();
+ DnsCacheKey dnsCacheKey = new DnsCacheKey(currentTime, localip, akScope);
+ String cacheKey = dnsCacheKey.toString();
+
Recorder recorder = null;
DnsPrefetcher dnsPrefetcher = null;
try {
recorder = new DnsCacheFile(Config.dnscacheDir);
- dnsPrefetcher = DnsPrefetcher.getDnsPrefetcher().init(token);
+ dnsPrefetcher = DnsPrefetcher.getDnsPrefetcher().init(token, config);
+ //确认预取结束后,需要更新缓存mDnsCacheKey
+ mDnsCacheKey.set(dnsCacheKey);
} catch (IOException e) {
e.printStackTrace();
return;
diff --git a/library/src/main/java/com/qiniu/android/storage/UploadManager.java b/library/src/main/java/com/qiniu/android/storage/UploadManager.java
index 78b6f0da9..d4f122821 100644
--- a/library/src/main/java/com/qiniu/android/storage/UploadManager.java
+++ b/library/src/main/java/com/qiniu/android/storage/UploadManager.java
@@ -28,7 +28,7 @@ public final class UploadManager {
/**
* 保证代码只执行一次,防止多个uploadManager同时开始预取dns
*/
- static AtomicBoolean atomicStruct = new AtomicBoolean(false);
+ static AtomicBoolean atomicLocalPrefetch = new AtomicBoolean(false);
/**
* default 3 Threads
@@ -44,6 +44,7 @@ public UploadManager(Configuration config) {
this.config = config;
this.client = new Client(config.proxy, config.connectTimeout, config.responseTimeout,
config.urlConverter, config.dns);
+ startLocalPrefetch(config);
}
public UploadManager(Configuration config, int multitread) {
@@ -51,6 +52,7 @@ public UploadManager(Configuration config, int multitread) {
this.multithreads = multitread >= 1 ? multitread : DEF_THREAD_NUM;
this.client = new Client(config.proxy, config.connectTimeout, config.responseTimeout,
config.urlConverter, config.dns);
+ startLocalPrefetch(config);
}
public UploadManager(Recorder recorder) {
@@ -69,6 +71,20 @@ public UploadManager(Recorder recorder, KeyGenerator keyGen, int multitread) {
this(new Configuration.Builder().recorder(recorder, keyGen).build(), multitread);
}
+ //初始化一个UploadManager只允许执行一次,开启一个线程,对sdk内置host进行预取
+ private void startLocalPrefetch(final Configuration config) {
+ if (atomicLocalPrefetch.compareAndSet(false, true)) {
+ if (DnsPrefetcher.recoverCache(config)) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ DnsPrefetcher.getDnsPrefetcher().localFetch();
+ }
+ }).start();
+ }
+ }
+ }
+
private static boolean areInvalidArg(final String key, byte[] data, File f, String token,
UpToken decodedToken, final UpCompletionHandler complete) {
if (complete == null) {
@@ -98,7 +114,8 @@ private static boolean areInvalidArg(final String key, byte[] data, File f, Stri
return false;
}
- private static ResponseInfo areInvalidArg(final String key, byte[] data, File f, String token,
+ private static ResponseInfo areInvalidArg(final String key, byte[] data, File f, String
+ token,
UpToken decodedToken) {
String message = null;
if (f == null && data == null) {
@@ -141,17 +158,16 @@ public void put(final byte[] data, final String key, final String token,
if (areInvalidArg(key, data, null, token, decodedToken, complete)) {
return;
}
-
- if (atomicStruct.compareAndSet(false, true)) {
- if (DnsPrefetcher.checkRePrefetchDns(token, config)) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- DnsPrefetcher.startPrefetchDns(token, config);
- }
- }).start();
- }
+ //此处是对uc.qbox.me接口获取的域名进行预取
+ if (DnsPrefetcher.checkRePrefetchDns(token, config)) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ DnsPrefetcher.startPrefetchDns(token, config);
+ }
+ }).start();
}
+
Zone z = config.zone;
z.preQuery(token, new Zone.QueryHandler() {
@Override
@@ -179,7 +195,8 @@ public void onFailure(int reason) {
* @param completionHandler 上传完成的后续处理动作
* @param options 上传数据的可选参数
*/
- public void put(String filePath, String key, String token, UpCompletionHandler completionHandler,
+ public void put(String filePath, String key, String token, UpCompletionHandler
+ completionHandler,
final UploadOptions options) {
put(new File(filePath), key, token, completionHandler, options);
}
@@ -194,23 +211,23 @@ public void put(String filePath, String key, String token, UpCompletionHandler c
* @param complete 上传完成的后续处理动作
* @param options 上传数据的可选参数
*/
- public void put(final File file, final String key, final String token, final UpCompletionHandler complete,
+ public void put(final File file, final String key, final String token,
+ final UpCompletionHandler complete,
final UploadOptions options) {
final UpToken decodedToken = UpToken.parse(token);
if (areInvalidArg(key, null, file, token, decodedToken, complete)) {
return;
}
-
- if (atomicStruct.compareAndSet(false, true)) {
- if (DnsPrefetcher.checkRePrefetchDns(token, config)) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- DnsPrefetcher.startPrefetchDns(token, config);
- }
- }).start();
- }
+ //此处是每次上传时判断,对uc.qbox.me接口获取的host+sdk内置的host进行预取(去重)
+ if (DnsPrefetcher.checkRePrefetchDns(token, config)) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ DnsPrefetcher.startPrefetchDns(token, config);
+ }
+ }).start();
}
+
Zone z = config.zone;
z.preQuery(token, new Zone.QueryHandler() {
@Override
diff --git a/library/src/main/java/com/qiniu/android/storage/UploadOptions.java b/library/src/main/java/com/qiniu/android/storage/UploadOptions.java
index 7550467ab..92b1f6d6f 100644
--- a/library/src/main/java/com/qiniu/android/storage/UploadOptions.java
+++ b/library/src/main/java/com/qiniu/android/storage/UploadOptions.java
@@ -15,6 +15,7 @@ public final class UploadOptions {
/**
* 扩展参数,以x:开头的用户自定义参数
+ * 可添加网络检测次数:netCheckTime,int类型,默认600,每增加1,检测时间增加500ms
*/
final Map params;
@@ -48,8 +49,18 @@ public UploadOptions(Map params, String mimeType, boolean checkC
this(params, mimeType, checkCrc, progressHandler, cancellationSignal, null);
}
- public UploadOptions(Map params, String mimeType, boolean checkCrc,
+ public UploadOptions(final Map params, String mimeType, boolean checkCrc,
UpProgressHandler progressHandler, UpCancellationSignal cancellationSignal, NetReadyHandler netReadyHandler) {
+ int netReadyCheckTime = 6;
+ try {
+ String netCheckTime = params.get("netCheckTime");
+ if (netCheckTime != null) {
+ netReadyCheckTime = Integer.parseInt(netCheckTime);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Log.e("qiniutest","netCheckTime:"+netReadyCheckTime);
this.params = filterParam(params);
this.mimeType = mime(mimeType);
this.checkCrc = checkCrc;
@@ -65,13 +76,14 @@ public boolean isCancelled() {
return false;
}
};
+ final int finalNetReadyCheckTime = netReadyCheckTime;
this.netReadyHandler = netReadyHandler != null ? netReadyHandler : new NetReadyHandler() {
@Override
public void waitReady() {
if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
return;
}
- for (int i = 0; i < 6; i++) {
+ for (int i = 0; i < finalNetReadyCheckTime; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {