提交 6a836a06 编写于 作者: B Blankj

see 07/26 log

上级 8f1c5227
* `19/07/26` [add] ContainerUtils. Publish v1.25.2.
* `19/07/25` [fix] PermissionUtils' NullPointException.
* `19/07/24` [fix] ZipUtils#unzipFile.
* `19/07/23` [fix] ThreadUtils of cache pool. Publish v1.25.1.
* `19/07/18` [add] README of ApiUtils and BusUtils.
* `19/07/15` [add] Publish v1.25.0.
......
......@@ -45,7 +45,7 @@
[frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame.png
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.1-brightgreen.svg
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.2-brightgreen.svg
[auc]: https://github.com/Blankj/AndroidUtilCode
[apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
......
......@@ -45,7 +45,7 @@ If this project helps you a lot and you want to support the project's developmen
[frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame.png
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.1-brightgreen.svg
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.2-brightgreen.svg
[auc]: https://github.com/Blankj/AndroidUtilCode
[apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
......
......@@ -16,7 +16,7 @@ configApkName()
android {
compileSdkVersion Config.compileSdkVersion
defaultConfig {
minSdkVersion Config.minSdkVersion
minSdkVersion 16
versionCode Config.versionCode
versionName Config.versionName
applicationId Config.applicationId + suffix
......@@ -55,6 +55,9 @@ dependencies {
debugImplementation Config.depConfig.leakcanary.support_fragment.dep
releaseImplementation Config.depConfig.leakcanary.android_no_op.dep
debugImplementation 'com.didichuxing.doraemonkit:doraemonkit:1.1.8'
releaseImplementation 'com.didichuxing.doraemonkit:doraemonkit-no-op:1.1.8'
// 根据 Config.pkgConfig 来依赖所有 pkg
for (def entrySet : ConfigUtils.getApplyPkgs().entrySet()) {
api entrySet.value.dep
......
......@@ -14,8 +14,8 @@ class Config {
static compileSdkVersion = 27
static minSdkVersion = 14
static targetSdkVersion = 27
static versionCode = 1_025_001
static versionName = '1.25.1'// E.g. 1.9.72 => 1,009,072
static versionCode = 1_025_002
static versionName = '1.25.2'// E.g. 1.9.72 => 1,009,072
// lib version
static kotlin_version = '1.3.10'
......@@ -71,10 +71,11 @@ class Config {
],
lib : [
base : new DepConfig(":lib:base"),
common : new DepConfig(":lib:common"),
subutil : new DepConfig(":lib:subutil"),
utilcode: new DepConfig(true/*是否本地调试*/, ":lib:utilcode", "com.blankj:utilcode:$versionName"),
base : new DepConfig(":lib:base"),
common : new DepConfig(":lib:common"),
subutil : new DepConfig(":lib:subutil"),
utilcode : new DepConfig(true/*是否本地调试*/, ":lib:utilcode", "com.blankj:utilcode:$versionName"),
utildebug: new DepConfig(true/*是否本地调试*/, ":lib:utildebug", "com.blankj:utildebug:$versionName"),
],
support : [
......
......@@ -88,7 +88,6 @@ class ConfigUtils {
void beforeEvaluate(Project project) {
if (project.subprojects.isEmpty()) {
if (project.path.contains(":plugin:")) {
// 插件的话自己写 build.gradle
return
}
if (project.name == "app") {
......
......@@ -12,4 +12,5 @@ dependencies {
api Config.depConfig.swipe_panel.dep
api Config.depConfig.eventbus.lib.dep
compileOnly Config.depConfig.leakcanary.android_no_op.dep
compileOnly 'com.didichuxing.doraemonkit:doraemonkit-no-op:1.1.8'
}
\ No newline at end of file
......@@ -8,6 +8,7 @@ import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.CrashUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ProcessUtils;
import com.didichuxing.doraemonkit.DoraemonKit;
import com.squareup.leakcanary.LeakCanary;
import java.util.ArrayList;
......@@ -41,6 +42,7 @@ public class BaseApplication extends Application {
public void onCreate() {
super.onCreate();
sInstance = this;
DoraemonKit.install(this);
initLeakCanary();
initLog();
initCrash();
......
......@@ -2,10 +2,10 @@
Gradle:
```groovy
implementation 'com.blankj:utilcode:1.25.1'
implementation 'com.blankj:utilcode:1.25.2'
// if u use AndroidX, use the following
implementation 'com.blankj:utilcodex:1.25.1'
implementation 'com.blankj:utilcodex:1.25.2'
```
......
......@@ -2,10 +2,10 @@
Gradle:
```groovy
implementation 'com.blankj:utilcode:1.25.1'
implementation 'com.blankj:utilcode:1.25.2'
// if u use AndroidX, use the following
implementation 'com.blankj:utilcodex:1.25.1'
implementation 'com.blankj:utilcodex:1.25.2'
```
......
package com.blankj.utilcode.util;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v4.util.SimpleArrayMap;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.SparseLongArray;
import java.util.Collection;
import java.util.Collections;
/**
* <pre>
* author: blankj
* blog : http://blankj.com
* time : 2019/07/26
* desc : utils about container
* </pre>
*/
public final class ContainerUtils {
private ContainerUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
public static <T> boolean isEmpty(T[] arr) {
return arr == null || arr.length == 0;
}
public static boolean isEmpty(final Collection obj) {
return obj == null || obj.isEmpty();
}
public static boolean isEmpty(final java.util.Map obj) {
return obj == null || obj.isEmpty();
}
public static boolean isEmpty(final SimpleArrayMap obj) {
return obj == null || obj.isEmpty();
}
public static boolean isEmpty(final SparseArray obj) {
return obj == null || obj.size() == 0;
}
public static boolean isEmpty(final SparseBooleanArray obj) {
return obj == null || obj.size() == 0;
}
public static boolean isEmpty(final SparseIntArray obj) {
return obj == null || obj.size() == 0;
}
public static boolean isEmpty(final android.support.v4.util.LongSparseArray obj) {
return obj == null || obj.size() == 0;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public static boolean isEmpty(final android.util.LongSparseArray obj) {
return obj == null || obj.size() == 0;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public static boolean isEmpty(final SparseLongArray obj) {
return obj == null || obj.size() == 0;
}
public static <V> boolean isNotEmpty(V[] obj) {
return !isEmpty(obj);
}
public static boolean isNotEmpty(final Collection obj) {
return !isEmpty(obj);
}
public static boolean isNotEmpty(final java.util.Map obj) {
return !isEmpty(obj);
}
public static boolean isNotEmpty(final SimpleArrayMap obj) {
return !isEmpty(obj);
}
public static boolean isNotEmpty(final SparseArray obj) {
return !isEmpty(obj);
}
public static boolean isNotEmpty(final SparseBooleanArray obj) {
return !isEmpty(obj);
}
public static boolean isNotEmpty(final SparseIntArray obj) {
return !isEmpty(obj);
}
public static boolean isNotEmpty(final android.support.v4.util.LongSparseArray obj) {
return !isEmpty(obj);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public static boolean isNotEmpty(final android.util.LongSparseArray obj) {
return !isEmpty(obj);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public static boolean isNotEmpty(final SparseLongArray obj) {
return !isEmpty(obj);
}
public static final class Array {
private Array() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
public static <T> int getSize(final T[] arr) {
if (isEmpty(arr)) return 0;
return arr.length;
}
public static <T> void reverse(final T[] arr) {
int size = getSize(arr);
if (size <= 1) return;
int mid = size >> 1;
T tmp;
for (int i = 0; i < mid; i++) {
tmp = arr[i];
arr[i] = arr[size - i - 1];
arr[size - i - 1] = tmp;
}
}
}
public static final class List {
private List() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
public static <T> int getSize(java.util.List<T> list) {
if (isEmpty(list)) return 0;
return list.size();
}
public static <V> void reverse(java.util.List<V> list) {
if (getSize(list) <= 1) return;
Collections.reverse(list);
}
}
public static final class Map {
private Map() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
public static <K, V> int getSize(java.util.Map<K, V> map) {
if (isEmpty(map)) return 0;
return map.size();
}
}
}
......@@ -410,7 +410,9 @@ public final class PermissionUtils {
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
sInstance.onRequestPermissionsResult(this);
if (sInstance != null && sInstance.mPermissionsRequest != null) {
sInstance.onRequestPermissionsResult(this);
}
finish();
}
......
package com.blankj.utilcode.util;
import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.util.Log;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
......@@ -33,7 +33,7 @@ import java.util.concurrent.atomic.AtomicLong;
*/
public final class ThreadUtils {
private static final Map<Integer, Map<Integer, ExecutorService>> TYPE_PRIORITY_POOLS = new ConcurrentHashMap<>();
private static final Map<Integer, Map<Integer, ExecutorService>> TYPE_PRIORITY_POOLS = new HashMap<>();
private static final Map<Task, TimerTask> TASK_TIMERTASK_MAP = new ConcurrentHashMap<>();
......@@ -944,23 +944,24 @@ public final class ThreadUtils {
return getPoolByTypeAndPriority(type, Thread.NORM_PRIORITY);
}
@SuppressLint("UseSparseArrays")
private synchronized static ExecutorService getPoolByTypeAndPriority(final int type, final int priority) {
ExecutorService pool;
Map<Integer, ExecutorService> priorityPools = TYPE_PRIORITY_POOLS.get(type);
if (priorityPools == null) {
priorityPools = new ConcurrentHashMap<>();
pool = ThreadPoolExecutor4Util.createPool(type, priority);
priorityPools.put(priority, pool);
TYPE_PRIORITY_POOLS.put(type, priorityPools);
} else {
pool = priorityPools.get(priority);
if (pool == null) {
private static ExecutorService getPoolByTypeAndPriority(final int type, final int priority) {
synchronized (TYPE_PRIORITY_POOLS) {
ExecutorService pool;
Map<Integer, ExecutorService> priorityPools = TYPE_PRIORITY_POOLS.get(type);
if (priorityPools == null) {
priorityPools = new ConcurrentHashMap<>();
pool = ThreadPoolExecutor4Util.createPool(type, priority);
priorityPools.put(priority, pool);
TYPE_PRIORITY_POOLS.put(type, priorityPools);
} else {
pool = priorityPools.get(priority);
if (pool == null) {
pool = ThreadPoolExecutor4Util.createPool(type, priority);
priorityPools.put(priority, pool);
}
}
return pool;
}
return pool;
}
static final class ThreadPoolExecutor4Util extends ThreadPoolExecutor {
......@@ -986,9 +987,9 @@ public final class ThreadUtils {
new UtilsThreadFactory("io", priority)
);
case TYPE_CPU:
return new ThreadPoolExecutor4Util(CPU_COUNT + 1, CPU_COUNT + 1,
return new ThreadPoolExecutor4Util(CPU_COUNT + 1, 2 * CPU_COUNT + 1,
30, TimeUnit.SECONDS,
new LinkedBlockingQueue4Util(),
new LinkedBlockingQueue4Util(true),
new UtilsThreadFactory("cpu", priority)
);
default:
......@@ -1046,7 +1047,7 @@ public final class ThreadUtils {
private volatile ThreadPoolExecutor4Util mPool;
private boolean mIsAddSubThreadFirstThenAddQueue = false;
private int mCapacity = Integer.MAX_VALUE;
LinkedBlockingQueue4Util() {
super();
......@@ -1054,12 +1055,19 @@ public final class ThreadUtils {
LinkedBlockingQueue4Util(boolean isAddSubThreadFirstThenAddQueue) {
super();
mIsAddSubThreadFirstThenAddQueue = isAddSubThreadFirstThenAddQueue;
if (isAddSubThreadFirstThenAddQueue) {
mCapacity = 0;
}
}
LinkedBlockingQueue4Util(int capacity) {
super();
mCapacity = capacity;
}
@Override
public boolean offer(@NonNull Runnable runnable) {
if (mIsAddSubThreadFirstThenAddQueue &&
if (mCapacity <= size() &&
mPool != null && mPool.getPoolSize() < mPool.getMaximumPoolSize()) {
// create a non-core thread
return false;
......
......@@ -293,7 +293,7 @@ public final class ZipUtils {
if (isSpace(keyword)) {
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
String entryName = entry.getName();
String entryName = entry.getName().replace("\\", "/");
if (entryName.contains("../")) {
Log.e("ZipUtils", "entryName: " + entryName + " is dangerous!");
continue;
......@@ -303,7 +303,7 @@ public final class ZipUtils {
} else {
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
String entryName = entry.getName();
String entryName = entry.getName().replace("\\", "/");
if (entryName.contains("../")) {
Log.e("ZipUtils", "entryName: " + entryName + " is dangerous!");
continue;
......@@ -378,7 +378,7 @@ public final class ZipUtils {
ZipFile zip = new ZipFile(zipFile);
Enumeration<?> entries = zip.entries();
while (entries.hasMoreElements()) {
String entryName = ((ZipEntry) entries.nextElement()).getName();
String entryName = ((ZipEntry) entries.nextElement()).getName().replace("\\", "/");;
if (entryName.contains("../")) {
Log.e("ZipUtils", "entryName: " + entryName + " is dangerous!");
paths.add(entryName);
......
......@@ -10,9 +10,7 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLog;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
/**
* <pre>
......@@ -39,25 +37,6 @@ public class BaseTest {
@Test
public void test() throws Exception {
CountDownLatch latch = new CountDownLatch(1);
for (int i = 0; i < 100; i++) {
final int finalI = i;
ThreadUtils.executeByCpu(new ThreadUtils.SimpleTask<Void>() {
@Override
public Void doInBackground() throws Throwable {
System.out.println("" + Thread.currentThread() + finalI);
Thread.sleep(100);
return null;
}
@Override
public void onSuccess(Void result) {
}
});
}
latch.await(1, TimeUnit.SECONDS);
}
}
package com.blankj.utilcode.util;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
......@@ -59,8 +58,8 @@ public class ZipUtilsTest extends BaseTest {
System.out.println(ZipUtils.getComments(zipFile));
}
@After
public void tearDown() {
FileUtils.deleteAllInDir(PATH_TEMP);
}
// @After
// public void tearDown() {
// FileUtils.deleteAllInDir(PATH_TEMP);
// }
}
\ No newline at end of file
apply {
plugin "com.github.dcendents.android-maven"
plugin "com.jfrog.bintray"
from "${rootDir.path}/gradle/upload/bintrayUploadAndroid.gradle"
}
dependencies {
implementation Config.depConfig.lib.utilcode.dep
compileOnly Config.depConfig.support.appcompat_v7.dep
compileOnly Config.depConfig.support.design.dep
testImplementation Config.depConfig.test.junit.dep
testImplementation Config.depConfig.test.robolectric.dep
testImplementation Config.depConfig.support.appcompat_v7.dep
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# 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
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blankj.utildebug" />
package com.blankj.utildebug;
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() {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
......@@ -45,7 +45,7 @@ apply plugin: "com.blankj.api"
api "com.blankj:utilcode:latest_version"
```
如果你单纯只想引入 `ApiUtils` 也是可以的,需要你自己拷贝一份这个类放到你工程里,然后在 app 下的 `build.gradle` 中 配置 api 的 SDL 域如下所示:
如果你单纯只想引入 `ApiUtils` 也是可以的,需要你自己拷贝一份这个类放到你工程里,然后在 app 下的 `build.gradle` 中 配置 api 的 DSL 域如下所示:
```groovy
api {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册