diff --git a/README_CN.md b/README_CN.md
index 97c7090..6ec21c0 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -1,5 +1,8 @@
[English](https://github.com/markzhai/AndroidPerformanceMonitor/blob/master/README.md)
+# 修改说明
+本修正版删除了2个不需要的权限WRITE_EXTERNAL_STORAGE & READ_PHONE_STATE
+
# Android Performance Monitor [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.markzhai/blockcanary-android/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/com.github.markzhai/blockcanary-android)
BlockCanary是一个Android平台的一个非侵入式的性能监控组件,应用只需要实现一个抽象类,提供一些该组件需要的上下文环境,就可以在平时使用应用的时候检测主线程上的各种卡慢问题,并通过组件提供的各种信息分析出原因并进行修复。
diff --git a/blockcanary-analyzer/build.gradle b/blockcanary-analyzer/build.gradle
index 83af379..5e17a87 100644
--- a/blockcanary-analyzer/build.gradle
+++ b/blockcanary-analyzer/build.gradle
@@ -3,7 +3,6 @@ apply from: 'gradle-mvn-push.gradle'
android {
compileSdkVersion LIBRARY_COMPILE_SDK_VERSION
- buildToolsVersion LIBRARY_BUILD_TOOLS_VERSION
defaultConfig {
minSdkVersion LIBRARY_MIN_SDK_VERSION
@@ -14,11 +13,14 @@ android {
buildTypes {
release {
minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
+ lintOptions {
+ checkAllWarnings true
+ }
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
}
diff --git a/blockcanary-analyzer/src/main/AndroidManifest.xml b/blockcanary-analyzer/src/main/AndroidManifest.xml
index 36f52b2..bf633ac 100644
--- a/blockcanary-analyzer/src/main/AndroidManifest.xml
+++ b/blockcanary-analyzer/src/main/AndroidManifest.xml
@@ -3,8 +3,14 @@
xmlns:android="http://schemas.android.com/apk/res/android">
-
-
+
+
+
+
diff --git a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/AbstractSampler.java b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/AbstractSampler.java
index c1e3383..6b7e566 100644
--- a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/AbstractSampler.java
+++ b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/AbstractSampler.java
@@ -27,7 +27,7 @@ abstract class AbstractSampler {
protected AtomicBoolean mShouldSample = new AtomicBoolean(false);
protected long mSampleInterval;
- private Runnable mRunnable = new Runnable() {
+ private final Runnable mRunnable = new Runnable() {
@Override
public void run() {
doSample();
@@ -40,7 +40,7 @@ public void run() {
};
public AbstractSampler(long sampleInterval) {
- if (0 == sampleInterval) {
+ if ( sampleInterval <= 0 ) {
sampleInterval = DEFAULT_SAMPLE_INTERVAL;
}
mSampleInterval = sampleInterval;
@@ -53,8 +53,7 @@ public void start() {
mShouldSample.set(true);
HandlerThreadFactory.getTimerThreadHandler().removeCallbacks(mRunnable);
- HandlerThreadFactory.getTimerThreadHandler().postDelayed(mRunnable,
- BlockCanaryInternals.getInstance().getSampleDelay());
+ HandlerThreadFactory.getTimerThreadHandler().postDelayed(mRunnable, BlockCanaryInternals.getInstance().getSampleDelay());
}
public void stop() {
diff --git a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/BlockCanaryInternals.java b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/BlockCanaryInternals.java
index 895d0d6..0d9095e 100644
--- a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/BlockCanaryInternals.java
+++ b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/BlockCanaryInternals.java
@@ -15,6 +15,7 @@
*/
package com.github.moduth.blockcanary;
+import android.os.Build;
import android.os.Environment;
import android.os.Looper;
@@ -35,13 +36,11 @@ public final class BlockCanaryInternals {
private static BlockCanaryInternals sInstance;
private static BlockCanaryContext sContext;
- private List mInterceptorChain = new LinkedList<>();
+ private final List mInterceptorChain = new LinkedList<>();
public BlockCanaryInternals() {
- stackSampler = new StackSampler(
- Looper.getMainLooper().getThread(),
- sContext.provideDumpInterval());
+ stackSampler = new StackSampler(Looper.getMainLooper().getThread(), sContext.provideDumpInterval());
cpuSampler = new CpuSampler(sContext.provideDumpInterval());
@@ -59,6 +58,7 @@ public void onBlockEvent(long realTimeStart, long realTimeEnd,
.setCpuBusyFlag(cpuSampler.isCpuBusy(realTimeStart, realTimeEnd))
.setRecentCpuRate(cpuSampler.getCpuRateInfo())
.setThreadStackEntries(threadStackEntries)
+ .setStackTraceElements(stackSampler.getTraceElements())
.flushString();
LogWriter.save(blockInfo.toString());
@@ -117,12 +117,18 @@ long getSampleDelay() {
static String getPath() {
String state = Environment.getExternalStorageState();
- String logPath = BlockCanaryInternals.getContext()
- == null ? "" : BlockCanaryInternals.getContext().providePath();
+ String logPath = BlockCanaryInternals.getContext() == null ? "" :
+ BlockCanaryInternals.getContext().providePath();
- if (Environment.MEDIA_MOUNTED.equals(state)
- && Environment.getExternalStorageDirectory().canWrite()) {
- return Environment.getExternalStorageDirectory().getPath() + logPath;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ if (Environment.MEDIA_MOUNTED.equals(state) ) {
+ return BlockCanaryInternals.getContext().provideContext().getExternalFilesDir(logPath).getPath();
+ }
+ }else{
+ if (Environment.MEDIA_MOUNTED.equals(state)
+ && Environment.getExternalStorageDirectory().canWrite()) {
+ return Environment.getExternalStorageDirectory().getPath() + logPath;
+ }
}
return getContext().provideContext().getFilesDir() + BlockCanaryInternals.getContext().providePath();
}
@@ -145,7 +151,7 @@ public static File[] getLogFiles() {
private static class BlockLogFileFilter implements FilenameFilter {
- private String TYPE = ".log";
+ private final String TYPE = ".log";
BlockLogFileFilter() {
diff --git a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/CpuSampler.java b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/CpuSampler.java
index 86c966d..de89b2f 100644
--- a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/CpuSampler.java
+++ b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/CpuSampler.java
@@ -15,8 +15,8 @@
*/
package com.github.moduth.blockcanary;
+import android.os.Build;
import android.util.Log;
-
import com.github.moduth.blockcanary.internal.BlockInfo;
import java.io.BufferedReader;
@@ -56,8 +56,10 @@ public CpuSampler(long sampleInterval) {
@Override
public void start() {
- super.start();
- reset();
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+ super.start();
+ reset();
+ }
}
/**
diff --git a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/HandlerThreadFactory.java b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/HandlerThreadFactory.java
index bf4c26d..cf552be 100644
--- a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/HandlerThreadFactory.java
+++ b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/HandlerThreadFactory.java
@@ -20,8 +20,8 @@
final class HandlerThreadFactory {
- private static HandlerThreadWrapper sLoopThread = new HandlerThreadWrapper("loop");
- private static HandlerThreadWrapper sWriteLogThread = new HandlerThreadWrapper("writer");
+ private static final HandlerThreadWrapper sLoopThread = new HandlerThreadWrapper("loop");
+ private static final HandlerThreadWrapper sWriteLogThread = new HandlerThreadWrapper("writer");
private HandlerThreadFactory() {
throw new InstantiationError("Must not instantiate this class");
@@ -36,7 +36,7 @@ public static Handler getWriteLogThreadHandler() {
}
private static class HandlerThreadWrapper {
- private Handler handler = null;
+ private final Handler handler;
public HandlerThreadWrapper(String threadName) {
HandlerThread handlerThread = new HandlerThread("BlockCanary-" + threadName);
diff --git a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/LooperMonitor.java b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/LooperMonitor.java
index 3b697e6..ee5b41a 100644
--- a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/LooperMonitor.java
+++ b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/LooperMonitor.java
@@ -21,12 +21,10 @@
class LooperMonitor implements Printer {
- private static final int DEFAULT_BLOCK_THRESHOLD_MILLIS = 3000;
-
- private long mBlockThresholdMillis = DEFAULT_BLOCK_THRESHOLD_MILLIS;
+ private long mBlockThresholdMillis;
private long mStartTimestamp = 0;
private long mStartThreadTimestamp = 0;
- private BlockListener mBlockListener = null;
+ private BlockListener mBlockListener;
private boolean mPrintingStarted = false;
private final boolean mStopWhenDebugging;
@@ -83,21 +81,21 @@ public void run() {
}
private void startDump() {
- if (null != BlockCanaryInternals.getInstance().stackSampler) {
+ if (BlockCanaryInternals.getInstance().stackSampler != null) {
BlockCanaryInternals.getInstance().stackSampler.start();
}
- if (null != BlockCanaryInternals.getInstance().cpuSampler) {
+ if (BlockCanaryInternals.getInstance().cpuSampler != null) {
BlockCanaryInternals.getInstance().cpuSampler.start();
}
}
private void stopDump() {
- if (null != BlockCanaryInternals.getInstance().stackSampler) {
+ if (BlockCanaryInternals.getInstance().stackSampler != null) {
BlockCanaryInternals.getInstance().stackSampler.stop();
}
- if (null != BlockCanaryInternals.getInstance().cpuSampler) {
+ if (BlockCanaryInternals.getInstance().cpuSampler != null) {
BlockCanaryInternals.getInstance().cpuSampler.stop();
}
}
diff --git a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/StackSampler.java b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/StackSampler.java
index 2d65e4a..ca7cc2d 100644
--- a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/StackSampler.java
+++ b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/StackSampler.java
@@ -28,8 +28,16 @@ class StackSampler extends AbstractSampler {
private static final int DEFAULT_MAX_ENTRY_COUNT = 100;
private static final LinkedHashMap sStackMap = new LinkedHashMap<>();
- private int mMaxEntryCount = DEFAULT_MAX_ENTRY_COUNT;
- private Thread mCurrentThread;
+ private final int mMaxEntryCount;
+ private final Thread mCurrentThread;
+
+ public StackTraceElement[] getTraceElements() {
+ synchronized (sStackMap) {
+ return traceElements;
+ }
+ }
+
+ private static StackTraceElement[] traceElements;
public StackSampler(Thread thread, long sampleIntervalMillis) {
this(thread, DEFAULT_MAX_ENTRY_COUNT, sampleIntervalMillis);
@@ -59,8 +67,8 @@ public ArrayList getThreadStackEntries(long startTime, long endTime) {
@Override
protected void doSample() {
StringBuilder stringBuilder = new StringBuilder();
-
- for (StackTraceElement stackTraceElement : mCurrentThread.getStackTrace()) {
+ traceElements = mCurrentThread.getStackTrace();
+ for (StackTraceElement stackTraceElement : traceElements) {
stringBuilder
.append(stackTraceElement.toString())
.append(BlockInfo.SEPARATOR);
diff --git a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/BlockInfo.java b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/BlockInfo.java
index 1b07edd..f78058d 100644
--- a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/BlockInfo.java
+++ b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/BlockInfo.java
@@ -19,7 +19,7 @@
import android.content.pm.PackageInfo;
import android.os.Build;
import android.os.Build.VERSION;
-import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.Log;
import com.github.moduth.blockcanary.BlockCanaryInternals;
@@ -46,7 +46,6 @@ public class BlockInfo {
public static final String KEY_QUA = "qua";
public static final String KEY_MODEL = "model";
public static final String KEY_API = "api-level";
- public static final String KEY_IMEI = "imei";
public static final String KEY_UID = "uid";
public static final String KEY_CPU_CORE = "cpu-core";
public static final String KEY_CPU_BUSY = "cpu-busy";
@@ -63,20 +62,14 @@ public class BlockInfo {
public static final String KEY_TOTAL_MEMORY = "totalMemory";
public static final String KEY_FREE_MEMORY = "freeMemory";
- public static String sQualifier;
- public static String sModel;
- public static String sApiLevel = "";
- /**
- * The International Mobile Equipment Identity or IMEI /aɪˈmiː/ is a number,
- * usually unique, to identify 3GPP and iDEN mobile phones
- */
- public static String sImei = "";
- public static int sCpuCoreNum = -1;
+ public static final String sQualifier;
+ public static final String sModel;
+ public static final String sApiLevel;
+ public static final int sCpuCoreNum;
public String qualifier;
public String model;
public String apiLevel = "";
- public String imei = "";
public int cpuCoreNum = -1;
// Per Block Info fields
@@ -94,28 +87,18 @@ public class BlockInfo {
public boolean cpuBusy;
public String cpuRateInfo;
public ArrayList threadStackEntries = new ArrayList<>();
+ public StackTraceElement[] stackTraceElements ;
- private StringBuilder basicSb = new StringBuilder();
- private StringBuilder cpuSb = new StringBuilder();
- private StringBuilder timeSb = new StringBuilder();
- private StringBuilder stackSb = new StringBuilder();
- private static final String EMPTY_IMEI = "empty_imei";
+ private final StringBuilder basicSb = new StringBuilder();
+ private final StringBuilder cpuSb = new StringBuilder();
+ private final StringBuilder timeSb = new StringBuilder();
+ private final StringBuilder stackSb = new StringBuilder();
static {
sCpuCoreNum = PerformanceUtils.getNumCores();
sModel = Build.MODEL;
sApiLevel = Build.VERSION.SDK_INT + " " + VERSION.RELEASE;
sQualifier = BlockCanaryInternals.getContext().provideQualifier();
- try {
- TelephonyManager telephonyManager = (TelephonyManager) BlockCanaryInternals
- .getContext()
- .provideContext()
- .getSystemService(Context.TELEPHONY_SERVICE);
- sImei = telephonyManager.getDeviceId();
- } catch (Exception exception) {
- Log.e(TAG, NEW_INSTANCE_METHOD, exception);
- sImei = EMPTY_IMEI;
- }
}
public BlockInfo() {
@@ -124,7 +107,7 @@ public BlockInfo() {
public static BlockInfo newInstance() {
BlockInfo blockInfo = new BlockInfo();
Context context = BlockCanaryInternals.getContext().provideContext();
- if (blockInfo.versionName == null || blockInfo.versionName.length() == 0) {
+ if (TextUtils.isEmpty(blockInfo.versionName)) {
try {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
blockInfo.versionCode = info.versionCode;
@@ -138,7 +121,6 @@ public static BlockInfo newInstance() {
blockInfo.model = sModel;
blockInfo.apiLevel = sApiLevel;
blockInfo.qualifier = sQualifier;
- blockInfo.imei = sImei;
blockInfo.uid = BlockCanaryInternals.getContext().provideUid();
blockInfo.processName = ProcessUtils.myProcessName();
blockInfo.network = BlockCanaryInternals.getContext().provideNetworkType();
@@ -163,6 +145,11 @@ public BlockInfo setThreadStackEntries(ArrayList threadStackEntries) {
return this;
}
+ public BlockInfo setStackTraceElements(StackTraceElement[] stackTraceElements) {
+ this.stackTraceElements = stackTraceElements;
+ return this;
+ }
+
public BlockInfo setMainThreadTimeCost(long realTimeStart, long realTimeEnd, long threadTimeStart, long threadTimeEnd) {
timeCost = realTimeEnd - realTimeStart;
threadTimeCost = threadTimeEnd - threadTimeStart;
@@ -176,7 +163,6 @@ public BlockInfo flushString() {
basicSb.append(KEY_QUA).append(KV).append(qualifier).append(separator);
basicSb.append(KEY_VERSION_NAME).append(KV).append(versionName).append(separator);
basicSb.append(KEY_VERSION_CODE).append(KV).append(versionCode).append(separator);
- basicSb.append(KEY_IMEI).append(KV).append(imei).append(separator);
basicSb.append(KEY_UID).append(KV).append(uid).append(separator);
basicSb.append(KEY_NETWORK).append(KV).append(network).append(separator);
basicSb.append(KEY_MODEL).append(KV).append(model).append(separator);
@@ -220,4 +206,22 @@ public String getTimeString() {
public String toString() {
return String.valueOf(basicSb) + timeSb + cpuSb + stackSb;
}
+
+ public Exception buildException(){
+ StringBuilder sb = new StringBuilder("threadTimeCost time cost:")
+ .append(threadTimeCost)
+ .append("ms,real time cost:")
+ .append(timeCost)
+ .append("ms");
+ if(timeCost - threadTimeCost > 300){
+ sb.append(",thread waiting a long time!!!");
+ }
+ if(cpuBusy){
+ sb.append(",cpu is busy !!!");
+ }
+ Exception exception = new BlockcanaryException(sb.toString());
+ exception.setStackTrace(stackTraceElements);
+ return exception;
+
+ }
}
diff --git a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/BlockcanaryException.java b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/BlockcanaryException.java
new file mode 100644
index 0000000..86fe7f8
--- /dev/null
+++ b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/BlockcanaryException.java
@@ -0,0 +1,19 @@
+package com.github.moduth.blockcanary.internal;
+
+public class BlockcanaryException extends Exception{
+
+ public BlockcanaryException() {
+ }
+
+ public BlockcanaryException(String detailMessage) {
+ super(detailMessage);
+ }
+
+ public BlockcanaryException(String detailMessage, Throwable throwable) {
+ super(detailMessage, throwable);
+ }
+
+ public BlockcanaryException(Throwable throwable) {
+ super(throwable);
+ }
+}
diff --git a/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/NetUtils.java b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/NetUtils.java
new file mode 100644
index 0000000..448ce67
--- /dev/null
+++ b/blockcanary-analyzer/src/main/java/com/github/moduth/blockcanary/internal/NetUtils.java
@@ -0,0 +1,164 @@
+package com.github.moduth.blockcanary.internal;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.telephony.TelephonyManager;
+
+@SuppressWarnings({ "deprecation", "RedundantSuppression" })
+public class NetUtils {
+ /**
+ * 没有网络连接
+ */
+ public static final String NETWORK_NONE = "NONE";
+ /**
+ * wifi连接
+ */
+ public static final String NETWORK_WIFI = "WIFI";
+ /**
+ * 2G
+ */
+ public static final String NETWORK_2G = "2G";
+ /**
+ * 3G
+ */
+ public static final String NETWORK_3G = "3G";
+ /**
+ * 4G
+ */
+ public static final String NETWORK_4G = "4G";
+ /**
+ * 手机流量
+ */
+ public static final String NETWORK_MOBILE = "MOBILE";
+
+ /**
+ * 获取运营商名字
+ *
+ * @param context context
+ * @return int
+ */
+ public static String getOperatorName(Context context) {
+ /*
+ * getSimOperatorName()就可以直接获取到运营商的名字
+ * 也可以使用IMSI获取,getSimOperator(),然后根据返回值判断,例如"46000"为移动
+ * IMSI相关链接:http://baike.baidu.com/item/imsi
+ */
+ TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ // getSimOperatorName就可以直接获取到运营商的名字
+ return telephonyManager.getSimOperatorName();
+ }
+
+ /**
+ * 获取当前网络连接的类型
+ *
+ * @param context context
+ * @return int
+ */
+ public static String getNetworkType(Context context) {
+ ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context
+ .CONNECTIVITY_SERVICE);
+ if (null == connManager) {
+ return NETWORK_NONE;
+ }
+ // 获取网络类型,如果为空,返回无网络
+ NetworkInfo activeNetInfo = connManager.getActiveNetworkInfo();
+ if (activeNetInfo == null || !activeNetInfo.isAvailable()) {
+ return NETWORK_NONE;
+ }
+ // 判断是否为WIFI
+ NetworkInfo wifiInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ if (null != wifiInfo) {
+ NetworkInfo.State state = wifiInfo.getState();
+ if (null != state) {
+ if (state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING) {
+ return NETWORK_WIFI;
+ }
+ }
+ }
+ // 若不是WIFI,则去判断是2G、3G、4G网
+ TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ int networkType = telephonyManager.getNetworkType();
+ switch (networkType) {
+ /*
+ GPRS : 2G(2.5) General Packet Radia Service 114kbps
+ EDGE : 2G(2.75G) Enhanced Data Rate for GSM Evolution 384kbps
+ UMTS : 3G WCDMA 联通3G Universal Mobile Telecommunication System 完整的3G移动通信技术标准
+ CDMA : 2G 电信 Code Division Multiple Access 码分多址
+ EVDO_0 : 3G (EVDO 全程 CDMA2000 1xEV-DO) Evolution - Data Only (Data Optimized) 153.6kps - 2.4mbps 属于3G
+ EVDO_A : 3G 1.8mbps - 3.1mbps 属于3G过渡,3.5G
+ 1xRTT : 2G CDMA2000 1xRTT (RTT - 无线电传输技术) 144kbps 2G的过渡,
+ HSDPA : 3.5G 高速下行分组接入 3.5G WCDMA High Speed Downlink Packet Access 14.4mbps
+ HSUPA : 3.5G High Speed Uplink Packet Access 高速上行链路分组接入 1.4 - 5.8 mbps
+ HSPA : 3G (分HSDPA,HSUPA) High Speed Packet Access
+ IDEN : 2G Integrated Dispatch Enhanced Networks 集成数字增强型网络 (属于2G,来自维基百科)
+ EVDO_B : 3G EV-DO Rev.B 14.7Mbps 下行 3.5G
+ LTE : 4G Long Term Evolution FDD-LTE 和 TDD-LTE , 3G过渡,升级版 LTE Advanced 才是4G
+ EHRPD : 3G CDMA2000向LTE 4G的中间产物 Evolved High Rate Packet Data HRPD的升级
+ HSPAP : 3G HSPAP 比 HSDPA 快些
+ */
+ // 2G网络
+ case TelephonyManager.NETWORK_TYPE_GPRS:
+ case TelephonyManager.NETWORK_TYPE_CDMA:
+ case TelephonyManager.NETWORK_TYPE_EDGE:
+ case TelephonyManager.NETWORK_TYPE_1xRTT:
+ case TelephonyManager.NETWORK_TYPE_IDEN:
+ return NETWORK_2G;
+ // 3G网络
+ case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ case TelephonyManager.NETWORK_TYPE_UMTS:
+ case TelephonyManager.NETWORK_TYPE_EVDO_0:
+ case TelephonyManager.NETWORK_TYPE_HSDPA:
+ case TelephonyManager.NETWORK_TYPE_HSUPA:
+ case TelephonyManager.NETWORK_TYPE_HSPA:
+ case TelephonyManager.NETWORK_TYPE_EVDO_B:
+ case TelephonyManager.NETWORK_TYPE_EHRPD:
+ case TelephonyManager.NETWORK_TYPE_HSPAP:
+ return NETWORK_3G;
+ // 4G网络
+ case TelephonyManager.NETWORK_TYPE_LTE:
+ return NETWORK_4G;
+ default:
+ return NETWORK_MOBILE;
+ }
+ }
+
+ /**
+ * 判断网络是否连接
+ *
+ * @param context context
+ * @return true/false
+ */
+ public static boolean isNetConnected(Context context) {
+ ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (connectivity != null) {
+ NetworkInfo info = connectivity.getActiveNetworkInfo();
+ if (info != null && info.isConnected()) {
+ return info.getState() == NetworkInfo.State.CONNECTED;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 判断是否wifi连接
+ *
+ * @param context context
+ * @return true/false
+ */
+ public static synchronized boolean isWifiConnected(Context context) {
+ ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context
+ .CONNECTIVITY_SERVICE);
+ if (connectivityManager != null) {
+ NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
+ if (networkInfo != null) {
+ int networkInfoType = networkInfo.getType();
+ if (networkInfoType == ConnectivityManager.TYPE_WIFI || networkInfoType == ConnectivityManager
+ .TYPE_ETHERNET) {
+ return networkInfo.isConnected();
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/blockcanary-android-no-op/build.gradle b/blockcanary-android-no-op/build.gradle
index 83af379..5e17a87 100644
--- a/blockcanary-android-no-op/build.gradle
+++ b/blockcanary-android-no-op/build.gradle
@@ -3,7 +3,6 @@ apply from: 'gradle-mvn-push.gradle'
android {
compileSdkVersion LIBRARY_COMPILE_SDK_VERSION
- buildToolsVersion LIBRARY_BUILD_TOOLS_VERSION
defaultConfig {
minSdkVersion LIBRARY_MIN_SDK_VERSION
@@ -14,11 +13,14 @@ android {
buildTypes {
release {
minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
+ lintOptions {
+ checkAllWarnings true
+ }
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
}
diff --git a/blockcanary-android-no-op/src/main/java/com/github/moduth/blockcanary/internal/BlockInfo.java b/blockcanary-android-no-op/src/main/java/com/github/moduth/blockcanary/internal/BlockInfo.java
index 278a8c7..0dbd64f 100644
--- a/blockcanary-android-no-op/src/main/java/com/github/moduth/blockcanary/internal/BlockInfo.java
+++ b/blockcanary-android-no-op/src/main/java/com/github/moduth/blockcanary/internal/BlockInfo.java
@@ -1,4 +1,23 @@
package com.github.moduth.blockcanary.internal;
public class BlockInfo {
+ public Exception buildException(){
+ return null;
+ }
+
+ public String getBasicString() {
+ return "";
+ }
+
+ public String getCpuString() {
+ return "";
+ }
+
+ public String getTimeString() {
+ return "";
+ }
+
+ public String toString() {
+ return "";
+ }
}
diff --git a/blockcanary-android/build.gradle b/blockcanary-android/build.gradle
index ebe613e..11764b3 100644
--- a/blockcanary-android/build.gradle
+++ b/blockcanary-android/build.gradle
@@ -3,7 +3,6 @@ apply from: 'gradle-mvn-push.gradle'
android {
compileSdkVersion LIBRARY_COMPILE_SDK_VERSION
- buildToolsVersion LIBRARY_BUILD_TOOLS_VERSION
defaultConfig {
minSdkVersion LIBRARY_MIN_SDK_VERSION
@@ -14,13 +13,18 @@ android {
buildTypes {
release {
minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
+ lintOptions {
+ checkAllWarnings true
+ }
}
dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
-// compile project(':blockcanary-analyzer')
- compile 'com.github.markzhai:blockcanary-analyzer:1.5.0'
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ api project(':blockcanary-analyzer')
+ //implementation 'com.github.markzhai:blockcanary-analyzer:1.5.0'
+ implementation 'androidx.core:core:1.1.0'
+ implementation "androidx.preference:preference:1.1.0"
}
diff --git a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/BlockCanary.java b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/BlockCanary.java
index edc0858..e80d322 100644
--- a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/BlockCanary.java
+++ b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/BlockCanary.java
@@ -15,11 +15,15 @@
*/
package com.github.moduth.blockcanary;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.os.Build;
import android.os.Looper;
-import android.preference.PreferenceManager;
+import androidx.preference.PreferenceManager;
import com.github.moduth.blockcanary.ui.DisplayActivity;
@@ -33,9 +37,10 @@
public final class BlockCanary {
private static final String TAG = "BlockCanary";
-
+ // these lines are originally copied from LeakCanary: Copyright (C) 2015 Square, Inc.
+ private static final Executor fileIoExecutor = newSingleThreadExecutor("File-IO");
private static BlockCanary sInstance;
- private BlockCanaryInternals mBlockCanaryCore;
+ private final BlockCanaryInternals mBlockCanaryCore;
private boolean mMonitorStarted = false;
private BlockCanary() {
@@ -57,6 +62,7 @@ private BlockCanary() {
* @return {@link BlockCanary}
*/
public static BlockCanary install(Context context, BlockCanaryContext blockCanaryContext) {
+ createNotificationChannel(context);
BlockCanaryContext.init(context, blockCanaryContext);
setEnabled(context, DisplayActivity.class, BlockCanaryContext.get().displayNotification());
return get();
@@ -78,6 +84,52 @@ public static BlockCanary get() {
return sInstance;
}
+ private static void setEnabledBlocking(Context appContext,
+ Class> componentClass,
+ boolean enabled) {
+ ComponentName component = new ComponentName(appContext, componentClass);
+ PackageManager packageManager = appContext.getPackageManager();
+ int newState = enabled ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DISABLED;
+ // Blocks on IPC.
+ packageManager.setComponentEnabledSetting(component, newState, DONT_KILL_APP);
+ }
+
+ private static void executeOnFileIoThread(Runnable runnable) {
+ fileIoExecutor.execute(runnable);
+ }
+
+ private static Executor newSingleThreadExecutor(String threadName) {
+ return Executors.newSingleThreadExecutor(new SingleThreadFactory(threadName));
+ }
+
+ private static void setEnabled(Context context,
+ final Class> componentClass,
+ final boolean enabled) {
+ final Context appContext = context.getApplicationContext();
+ executeOnFileIoThread(new Runnable() {
+ @Override
+ public void run() {
+ setEnabledBlocking(appContext, componentClass, enabled);
+ }
+ });
+ }
+
+ private static void createNotificationChannel(Context context) {
+ // Create the NotificationChannel, but only on API 26+ because
+ // the NotificationChannel class is new and not in the support library
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ int importance = NotificationManager.IMPORTANCE_DEFAULT;
+ NotificationChannel channel = new NotificationChannel(DisplayService.CHANNEL_ID, "Block Canary", importance);
+ channel.enableLights(true);
+ channel.setDescription("Block Canary");
+ channel.setLightColor(Color.RED);
+ // Register the channel with the system; you can't change the importance
+ // or other notification behaviors after this
+ NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
+ if(notificationManager != null) notificationManager.createNotificationChannel(channel);
+ }
+ }
+
/**
* Start monitoring.
*/
@@ -99,6 +151,7 @@ public void stop() {
mBlockCanaryCore.cpuSampler.stop();
}
}
+ // end of lines copied from LeakCanary
/**
* Zip and upload log files, will user context's zip and log implementation.
@@ -130,38 +183,4 @@ public boolean isMonitorDurationEnd() {
return startTime != 0 && System.currentTimeMillis() - startTime >
BlockCanaryContext.get().provideMonitorDuration() * 3600 * 1000;
}
-
- // these lines are originally copied from LeakCanary: Copyright (C) 2015 Square, Inc.
- private static final Executor fileIoExecutor = newSingleThreadExecutor("File-IO");
-
- private static void setEnabledBlocking(Context appContext,
- Class> componentClass,
- boolean enabled) {
- ComponentName component = new ComponentName(appContext, componentClass);
- PackageManager packageManager = appContext.getPackageManager();
- int newState = enabled ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DISABLED;
- // Blocks on IPC.
- packageManager.setComponentEnabledSetting(component, newState, DONT_KILL_APP);
- }
- // end of lines copied from LeakCanary
-
- private static void executeOnFileIoThread(Runnable runnable) {
- fileIoExecutor.execute(runnable);
- }
-
- private static Executor newSingleThreadExecutor(String threadName) {
- return Executors.newSingleThreadExecutor(new SingleThreadFactory(threadName));
- }
-
- private static void setEnabled(Context context,
- final Class> componentClass,
- final boolean enabled) {
- final Context appContext = context.getApplicationContext();
- executeOnFileIoThread(new Runnable() {
- @Override
- public void run() {
- setEnabledBlocking(appContext, componentClass, enabled);
- }
- });
- }
}
diff --git a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/DisplayService.java b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/DisplayService.java
index 7d71590..26d4426 100644
--- a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/DisplayService.java
+++ b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/DisplayService.java
@@ -15,74 +15,50 @@
*/
package com.github.moduth.blockcanary;
-import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
-import android.util.Log;
+import androidx.core.app.NotificationCompat;
import com.github.moduth.blockcanary.internal.BlockInfo;
import com.github.moduth.blockcanary.ui.DisplayActivity;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
-import static android.os.Build.VERSION.SDK_INT;
-import static android.os.Build.VERSION_CODES.HONEYCOMB;
-import static android.os.Build.VERSION_CODES.JELLY_BEAN;
-
final class DisplayService implements BlockInterceptor {
private static final String TAG = "DisplayService";
+ public static final String CHANNEL_ID = "BLOCK_CANARY";
@Override
public void onBlock(Context context, BlockInfo blockInfo) {
Intent intent = new Intent(context, DisplayActivity.class);
intent.putExtra("show_latest", blockInfo.timeStart);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, FLAG_UPDATE_CURRENT);
+ PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
String contentTitle = context.getString(R.string.block_canary_class_has_blocked, blockInfo.timeStart);
String contentText = context.getString(R.string.block_canary_notification_message);
show(context, contentTitle, contentText, pendingIntent);
}
- @TargetApi(HONEYCOMB)
private void show(Context context, String contentTitle, String contentText, PendingIntent pendingIntent) {
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
- Notification notification;
- if (SDK_INT < HONEYCOMB) {
- notification = new Notification();
- notification.icon = R.drawable.block_canary_notification;
- notification.when = System.currentTimeMillis();
- notification.flags |= Notification.FLAG_AUTO_CANCEL;
- notification.defaults = Notification.DEFAULT_SOUND;
- try {
- Method deprecatedMethod = notification.getClass().getMethod("setLatestEventInfo", Context.class, CharSequence.class, CharSequence.class, PendingIntent.class);
- deprecatedMethod.invoke(notification, context, contentTitle, contentText, pendingIntent);
- } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException
- | InvocationTargetException e) {
- Log.w(TAG, "Method not found", e);
- }
- } else {
- Notification.Builder builder = new Notification.Builder(context)
+ if(notificationManager != null) {
+ Notification notification;
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.block_canary_notification)
.setWhen(System.currentTimeMillis())
.setContentTitle(contentTitle)
.setContentText(contentText)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
- .setDefaults(Notification.DEFAULT_SOUND);
- if (SDK_INT < JELLY_BEAN) {
- notification = builder.getNotification();
- } else {
- notification = builder.build();
- }
+ .setDefaults(Notification.DEFAULT_SOUND)
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT);
+
+ notification = builder.build();
+ notificationManager.notify(0xDEAFBEEF, notification);
}
- notificationManager.notify(0xDEAFBEEF, notification);
}
}
diff --git a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/BlockCanaryUtils.java b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/BlockCanaryUtils.java
index 195b0ce..b08248e 100644
--- a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/BlockCanaryUtils.java
+++ b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/BlockCanaryUtils.java
@@ -11,17 +11,19 @@
final class BlockCanaryUtils {
- private static final List WHITE_LIST = new LinkedList<>();
- private static final List CONCERN_LIST = new LinkedList<>();
+ private static final List sWhiteList = new LinkedList<>();
+ private static final List sConcernList = new LinkedList<>();
static {
- WHITE_LIST.addAll(BlockCanaryInternals.getContext().provideWhiteList());
+ if (BlockCanaryInternals.getContext().provideWhiteList() != null) {
+ sWhiteList.addAll(BlockCanaryInternals.getContext().provideWhiteList());
+ }
if (BlockCanaryInternals.getContext().concernPackages() != null) {
- CONCERN_LIST.addAll(BlockCanaryInternals.getContext().concernPackages());
+ sConcernList.addAll(BlockCanaryInternals.getContext().concernPackages());
}
- if (CONCERN_LIST.isEmpty()) {
- CONCERN_LIST.add(ProcessUtils.myProcessName());
+ if (sConcernList.isEmpty()) {
+ sConcernList.add(ProcessUtils.myProcessName());
}
}
@@ -56,7 +58,7 @@ public static boolean isInWhiteList(BlockInfo info) {
if (Character.isLetter(stackEntry.charAt(0))) {
String[] lines = stackEntry.split(BlockInfo.SEPARATOR);
for (String line : lines) {
- for (String whiteListEntry : WHITE_LIST) {
+ for (String whiteListEntry : sWhiteList) {
if (line.startsWith(whiteListEntry)) {
return true;
}
@@ -68,11 +70,11 @@ public static boolean isInWhiteList(BlockInfo info) {
}
public static List getConcernPackages() {
- return CONCERN_LIST;
+ return sConcernList;
}
private static String concernStackString(String line) {
- for (String concernPackage : CONCERN_LIST) {
+ for (String concernPackage : sConcernList) {
if (line.startsWith(concernPackage)) {
return classSimpleName(line);
}
diff --git a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/BlockInfoEx.java b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/BlockInfoEx.java
index 4733b69..fa6b93a 100644
--- a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/BlockInfoEx.java
+++ b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/BlockInfoEx.java
@@ -38,8 +38,6 @@ public static BlockInfoEx newInstance(File file) {
blockInfo.model = line.split(KV)[1];
} else if (line.startsWith(KEY_API)) {
blockInfo.apiLevel = line.split(KV)[1];
- } else if (line.startsWith(KEY_IMEI)) {
- blockInfo.imei = line.split(KV)[1];
} else if (line.startsWith(KEY_CPU_CORE)) {
blockInfo.cpuCoreNum = Integer.valueOf(line.split(KV)[1]);
} else if (line.startsWith(KEY_UID)) {
diff --git a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DetailAdapter.java b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DetailAdapter.java
index c1599c3..353f67b 100644
--- a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DetailAdapter.java
+++ b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DetailAdapter.java
@@ -16,7 +16,7 @@
package com.github.moduth.blockcanary.ui;
import android.content.Context;
-import android.text.Html;
+import androidx.core.text.HtmlCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -47,15 +47,13 @@ public View getView(int position, View convertView, ViewGroup parent) {
Context context = parent.getContext();
if (getItemViewType(position) == TOP_ROW) {
if (convertView == null) {
- convertView =
- LayoutInflater.from(context).inflate(R.layout.block_canary_ref_top_row, parent, false);
+ convertView = LayoutInflater.from(context).inflate(R.layout.block_canary_ref_top_row, parent, false);
}
TextView textView = findById(convertView, R.id.__leak_canary_row_text);
textView.setText(context.getPackageName());
} else {
if (convertView == null) {
- convertView =
- LayoutInflater.from(context).inflate(R.layout.block_canary_ref_row, parent, false);
+ convertView = LayoutInflater.from(context).inflate(R.layout.block_canary_ref_row, parent, false);
}
TextView textView = findById(convertView, R.id.__leak_canary_row_text);
@@ -65,7 +63,7 @@ public View getView(int position, View convertView, ViewGroup parent) {
if (isThreadStackEntry && !mFoldings[position]) {
htmlString += " " + "blocked" + "";
}
- textView.setText(Html.fromHtml(htmlString));
+ textView.setText(HtmlCompat.fromHtml(htmlString, HtmlCompat.FROM_HTML_MODE_LEGACY));
DisplayConnectorView connectorView = findById(convertView, R.id.__leak_canary_row_connector);
connectorView.setType(connectorViewType(position));
@@ -78,9 +76,8 @@ public View getView(int position, View convertView, ViewGroup parent) {
}
private DisplayConnectorView.Type connectorViewType(int position) {
- return (position == 1) ? DisplayConnectorView.Type.START : (
- (position == getCount() - 1) ? DisplayConnectorView.Type.END :
- DisplayConnectorView.Type.NODE);
+ return (position == 1) ? DisplayConnectorView.Type.START : ((position == getCount() - 1)
+ ? DisplayConnectorView.Type.END : DisplayConnectorView.Type.NODE);
}
private String elementToHtmlString(String element, int position, boolean folding) {
diff --git a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DisplayActivity.java b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DisplayActivity.java
index cdd30b8..28bdfc6 100644
--- a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DisplayActivity.java
+++ b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DisplayActivity.java
@@ -23,25 +23,14 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.Button;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-
+import android.view.*;
+import android.widget.*;
import com.github.moduth.blockcanary.BlockCanaryContext;
import com.github.moduth.blockcanary.BlockCanaryInternals;
import com.github.moduth.blockcanary.LogWriter;
@@ -68,7 +57,7 @@ public class DisplayActivity extends Activity {
private static final String TAG = "DisplayActivity";
private static final String SHOW_BLOCK_EXTRA = "show_latest";
- public static final String SHOW_BLOCK_EXTRA_KEY = "BlockStartTime";
+ private static final String SHOW_BLOCK_EXTRA_KEY = "BlockStartTime";
// empty until it's been first loaded.
private List mBlockInfoEntries = new ArrayList<>();
@@ -101,9 +90,9 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.block_canary_display_leak);
- mListView = (ListView) findViewById(R.id.__leak_canary_display_leak_list);
- mFailureView = (TextView) findViewById(R.id.__leak_canary_display_leak_failure);
- mActionButton = (Button) findViewById(R.id.__leak_canary_action);
+ mListView = findViewById(R.id.__leak_canary_display_leak_list);
+ mFailureView = findViewById(R.id.__leak_canary_display_leak_failure);
+ mActionButton = findViewById(R.id.__leak_canary_action);
mMaxStoredBlockCount = getResources().getInteger(R.integer.block_canary_max_stored_count);
@@ -199,10 +188,7 @@ private void shareBlock(BlockInfoEx blockInfo) {
private void shareHeapDump(BlockInfoEx blockInfo) {
File heapDumpFile = blockInfo.logFile;
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
- heapDumpFile.setReadable(true, false);
- }
+ heapDumpFile.setReadable(true, false);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("application/octet-stream");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(heapDumpFile));
@@ -240,12 +226,10 @@ public void onItemClick(AdapterView> parent, View view, int position, long id)
updateUi();
}
});
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- invalidateOptionsMenu();
- ActionBar actionBar = getActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(false);
- }
+ invalidateOptionsMenu();
+ ActionBar actionBar = getActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(false);
}
setTitle(getString(R.string.block_canary_block_list_title, getPackageName()));
mActionButton.setText(R.string.block_canary_delete_all);
@@ -287,12 +271,10 @@ public void onItemClick(AdapterView> parent, View view, int position, long id)
adapter.toggleRow(position);
}
});
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- invalidateOptionsMenu();
- ActionBar actionBar = getActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- }
+ invalidateOptionsMenu();
+ ActionBar actionBar = getActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
}
mActionButton.setVisibility(VISIBLE);
mActionButton.setText(R.string.block_canary_delete);
@@ -309,7 +291,7 @@ public void onClick(View v) {
}
});
adapter.update(blockInfo);
- setTitle(getString(R.string.block_canary_class_has_blocked, blockInfo.timeCost));
+ setTitle(getString(R.string.block_canary_class_has_blocked, Long.toString(blockInfo.timeCost)));
}
private BlockInfoEx getBlock(String startTime) {
@@ -317,7 +299,7 @@ private BlockInfoEx getBlock(String startTime) {
return null;
}
for (BlockInfoEx blockInfo : mBlockInfoEntries) {
- if (blockInfo.timeStart != null && startTime.equals(blockInfo.timeStart)) {
+ if (startTime.equals(blockInfo.timeStart)) {
return blockInfo;
}
}
@@ -347,8 +329,8 @@ public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(DisplayActivity.this)
.inflate(R.layout.block_canary_block_row, parent, false);
}
- TextView titleView = (TextView) convertView.findViewById(R.id.__leak_canary_row_text);
- TextView timeView = (TextView) convertView.findViewById(R.id.__leak_canary_row_time);
+ TextView titleView = convertView.findViewById(R.id.__leak_canary_row_text);
+ TextView timeView = convertView.findViewById(R.id.__leak_canary_row_time);
BlockInfoEx blockInfo = getItem(position);
String index;
@@ -360,7 +342,7 @@ public View getView(int position, View convertView, ViewGroup parent) {
String keyStackString = BlockCanaryUtils.concernStackString(blockInfo);
String title = index + keyStackString + " " +
- getString(R.string.block_canary_class_has_blocked, blockInfo.timeCost);
+ getString(R.string.block_canary_class_has_blocked, Long.toString(blockInfo.timeCost));
titleView.setText(title);
String time = DateUtils.formatDateTime(DisplayActivity.this,
blockInfo.logFile.lastModified(), FORMAT_SHOW_TIME | FORMAT_SHOW_DATE);
diff --git a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DisplayConnectorView.java b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DisplayConnectorView.java
index 0f09d47..e07e9af 100644
--- a/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DisplayConnectorView.java
+++ b/blockcanary-android/src/main/java/com/github/moduth/blockcanary/ui/DisplayConnectorView.java
@@ -53,7 +53,6 @@ public DisplayConnectorView(Context context, AttributeSet attrs) {
type = Type.NODE;
}
- @SuppressWarnings("SuspiciousNameCombination")
@Override
protected void onDraw(Canvas canvas) {
int width = getWidth();
diff --git a/blockcanary-android/src/main/res/values-v14/themes.xml b/blockcanary-android/src/main/res/values-v14/themes.xml
deleted file mode 100644
index 0f875ae..0000000
--- a/blockcanary-android/src/main/res/values-v14/themes.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/blockcanary-sample/build.gradle b/blockcanary-sample/build.gradle
index 32d69b8..4606b24 100644
--- a/blockcanary-sample/build.gradle
+++ b/blockcanary-sample/build.gradle
@@ -2,7 +2,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion LIBRARY_COMPILE_SDK_VERSION
- buildToolsVersion LIBRARY_BUILD_TOOLS_VERSION
defaultConfig {
applicationId "com.example.blockcanary"
@@ -14,16 +13,19 @@ android {
buildTypes {
release {
minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
+ lintOptions {
+ checkAllWarnings true
+ }
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- debugCompile project(':blockcanary-android')
- releaseCompile project(':blockcanary-android-no-op')
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ debugImplementation project(':blockcanary-android')
+ releaseImplementation project(':blockcanary-android-no-op')
- compile 'com.android.support:appcompat-v7:24.2.0'
- compile 'com.android.support:design:24.2.0'
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'com.google.android.material:material:1.0.0'
}
diff --git a/blockcanary-sample/src/main/AndroidManifest.xml b/blockcanary-sample/src/main/AndroidManifest.xml
index fbf6d6b..ceac407 100644
--- a/blockcanary-sample/src/main/AndroidManifest.xml
+++ b/blockcanary-sample/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
-
+ android:theme="@style/ModuThreeHandsomeTheme"
+ tools:ignore="AllowBackup,GoogleAppIndexingWarning">
+ android:label="@string/app_name"
+ android:theme="@style/CjjBaseTheme">
diff --git a/blockcanary-sample/src/main/java/com/example/blockcanary/AppContext.java b/blockcanary-sample/src/main/java/com/example/blockcanary/AppContext.java
index 612df72..3a0fdc8 100644
--- a/blockcanary-sample/src/main/java/com/example/blockcanary/AppContext.java
+++ b/blockcanary-sample/src/main/java/com/example/blockcanary/AppContext.java
@@ -15,11 +15,14 @@
*/
package com.example.blockcanary;
+import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import com.github.moduth.blockcanary.BlockCanaryContext;
+import com.github.moduth.blockcanary.internal.BlockInfo;
+import com.github.moduth.blockcanary.internal.NetUtils;
import java.util.List;
@@ -46,7 +49,7 @@ public String provideUid() {
@Override
public String provideNetworkType() {
- return "4G";
+ return NetUtils.getNetworkType(DemoApplication.getAppContext()) ;
}
@Override
@@ -82,4 +85,14 @@ public List provideWhiteList() {
public boolean stopWhenDebugging() {
return true;
}
+
+ @Override
+ public void onBlock(Context context, BlockInfo blockInfo) {
+ super.onBlock(context, blockInfo);
+ Exception e = blockInfo.buildException();
+ if(e != null){
+ e.printStackTrace();
+ }
+ Log.e("block",blockInfo.toString());
+ }
}
\ No newline at end of file
diff --git a/blockcanary-sample/src/main/java/com/example/blockcanary/DemoActivity.java b/blockcanary-sample/src/main/java/com/example/blockcanary/DemoActivity.java
index 1c72795..958ae25 100644
--- a/blockcanary-sample/src/main/java/com/example/blockcanary/DemoActivity.java
+++ b/blockcanary-sample/src/main/java/com/example/blockcanary/DemoActivity.java
@@ -16,12 +16,10 @@
package com.example.blockcanary;
import android.os.Bundle;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.View;
public class DemoActivity extends AppCompatActivity {
@@ -33,14 +31,6 @@ protected void onCreate(Bundle savedInstanceState) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, DemoFragment.newInstance())
.commit();
-
- FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- showTipDialog();
- }
- });
}
private void showTipDialog() {
@@ -65,8 +55,8 @@ public boolean onOptionsItemSelected(MenuItem item) {
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
- //noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
+ showTipDialog();
return true;
}
diff --git a/blockcanary-sample/src/main/java/com/example/blockcanary/DemoFragment.java b/blockcanary-sample/src/main/java/com/example/blockcanary/DemoFragment.java
index 25b77ca..7a0a035 100644
--- a/blockcanary-sample/src/main/java/com/example/blockcanary/DemoFragment.java
+++ b/blockcanary-sample/src/main/java/com/example/blockcanary/DemoFragment.java
@@ -15,9 +15,11 @@
*/
package com.example.blockcanary;
+import android.os.Build;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -47,20 +49,17 @@ public View onCreateView(final LayoutInflater inflater, final ViewGroup containe
}
@Override
- public void onViewCreated(final View view, @Nullable final Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- Button button1 = (Button) view.findViewById(R.id.button1);
- Button button2 = (Button) view.findViewById(R.id.button2);
- Button button3 = (Button) view.findViewById(R.id.button3);
+ Button button1 = view.findViewById(R.id.button1);
+ Button button2 = view.findViewById(R.id.button2);
+ Button button3 = view.findViewById(R.id.button3);
+ Button button4 = view.findViewById(R.id.button4);
button1.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
+ button4.setOnClickListener(this);
}
@Override
@@ -80,14 +79,19 @@ public void onClick(View v) {
}
break;
case R.id.button2:
- for (int i = 0; i < 100; ++i) {
- readFile();
+ for (int i = 0; i < 200; ++i) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+ readFile();
+ }
}
break;
case R.id.button3:
double result = compute();
System.out.println(result);
break;
+ case R.id.button4:
+ System.out.println("not implemented");
+ break;
default:
break;
}
@@ -95,13 +99,14 @@ public void onClick(View v) {
private static double compute() {
double result = 0;
- for (int i = 0; i < 1000000; ++i) {
+ for (int i = 0; i < 4000000; ++i) {
result += Math.acos(Math.cos(i));
result -= Math.asin(Math.sin(i));
}
return result;
}
+ @Deprecated
private static void readFile() {
FileInputStream reader = null;
try {
diff --git a/blockcanary-sample/src/main/res/drawable-anydpi/ic_done.xml b/blockcanary-sample/src/main/res/drawable-anydpi/ic_done.xml
new file mode 100644
index 0000000..49929f4
--- /dev/null
+++ b/blockcanary-sample/src/main/res/drawable-anydpi/ic_done.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/blockcanary-sample/src/main/res/drawable-hdpi/ic_done.png b/blockcanary-sample/src/main/res/drawable-hdpi/ic_done.png
new file mode 100644
index 0000000..4c4b069
Binary files /dev/null and b/blockcanary-sample/src/main/res/drawable-hdpi/ic_done.png differ
diff --git a/blockcanary-sample/src/main/res/drawable-mdpi/ic_done.png b/blockcanary-sample/src/main/res/drawable-mdpi/ic_done.png
new file mode 100644
index 0000000..9883758
Binary files /dev/null and b/blockcanary-sample/src/main/res/drawable-mdpi/ic_done.png differ
diff --git a/blockcanary-sample/src/main/res/drawable-xhdpi/ic_done.png b/blockcanary-sample/src/main/res/drawable-xhdpi/ic_done.png
new file mode 100644
index 0000000..68e4365
Binary files /dev/null and b/blockcanary-sample/src/main/res/drawable-xhdpi/ic_done.png differ
diff --git a/blockcanary-sample/src/main/res/drawable-xxhdpi/ic_done.png b/blockcanary-sample/src/main/res/drawable-xxhdpi/ic_done.png
new file mode 100644
index 0000000..053ff40
Binary files /dev/null and b/blockcanary-sample/src/main/res/drawable-xxhdpi/ic_done.png differ
diff --git a/blockcanary-sample/src/main/res/drawable/background_splash.xml b/blockcanary-sample/src/main/res/drawable/background_splash.xml
deleted file mode 100644
index 8ecd5eb..0000000
--- a/blockcanary-sample/src/main/res/drawable/background_splash.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
- -
-
-
-
-
\ No newline at end of file
diff --git a/blockcanary-sample/src/main/res/drawable/btn_select.xml b/blockcanary-sample/src/main/res/drawable/btn_select.xml
index a8a916a..588f1ba 100644
--- a/blockcanary-sample/src/main/res/drawable/btn_select.xml
+++ b/blockcanary-sample/src/main/res/drawable/btn_select.xml
@@ -1,8 +1,8 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/blockcanary-sample/src/main/res/drawable/ic_done.png b/blockcanary-sample/src/main/res/drawable/ic_done.png
deleted file mode 100644
index bf5bc7e..0000000
Binary files a/blockcanary-sample/src/main/res/drawable/ic_done.png and /dev/null differ
diff --git a/blockcanary-sample/src/main/res/drawable/ic_launcher_foreground.xml b/blockcanary-sample/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..a5547a3
--- /dev/null
+++ b/blockcanary-sample/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/blockcanary-sample/src/main/res/layout/activity_demo.xml b/blockcanary-sample/src/main/res/layout/activity_demo.xml
index 066c36a..0b423d5 100644
--- a/blockcanary-sample/src/main/res/layout/activity_demo.xml
+++ b/blockcanary-sample/src/main/res/layout/activity_demo.xml
@@ -19,13 +19,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MergeRootFrame" />
-
-
\ No newline at end of file
diff --git a/blockcanary-sample/src/main/res/layout/activity_main.xml b/blockcanary-sample/src/main/res/layout/activity_main.xml
index 5c5fdff..d5dabb8 100644
--- a/blockcanary-sample/src/main/res/layout/activity_main.xml
+++ b/blockcanary-sample/src/main/res/layout/activity_main.xml
@@ -7,24 +7,23 @@
+ android:background="@color/material_blue"
+ android:visibility="gone">
+ android:textSize="18sp" />
@@ -94,14 +93,4 @@
-
-
-
\ No newline at end of file
diff --git a/blockcanary-sample/src/main/res/menu/menu_demo.xml b/blockcanary-sample/src/main/res/menu/menu_demo.xml
index 300f66a..f841b74 100644
--- a/blockcanary-sample/src/main/res/menu/menu_demo.xml
+++ b/blockcanary-sample/src/main/res/menu/menu_demo.xml
@@ -1,5 +1,10 @@
+
+
\ No newline at end of file
diff --git a/blockcanary-sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/blockcanary-sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..7353dbd
--- /dev/null
+++ b/blockcanary-sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/blockcanary-sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/blockcanary-sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..7353dbd
--- /dev/null
+++ b/blockcanary-sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/blockcanary-sample/src/main/res/mipmap-hdpi/ic_launcher.png b/blockcanary-sample/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..fb04068
Binary files /dev/null and b/blockcanary-sample/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/blockcanary-sample/src/main/res/mipmap-hdpi/ic_launcher_round.png b/blockcanary-sample/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..fb04068
Binary files /dev/null and b/blockcanary-sample/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/blockcanary-sample/src/main/res/mipmap-mdpi/ic_launcher.png b/blockcanary-sample/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..4265ffb
Binary files /dev/null and b/blockcanary-sample/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/blockcanary-sample/src/main/res/mipmap-mdpi/ic_launcher_round.png b/blockcanary-sample/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4265ffb
Binary files /dev/null and b/blockcanary-sample/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/blockcanary-sample/src/main/res/mipmap-xhdpi/ic_launcher.png b/blockcanary-sample/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..d8ea51c
Binary files /dev/null and b/blockcanary-sample/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/blockcanary-sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/blockcanary-sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d8ea51c
Binary files /dev/null and b/blockcanary-sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/blockcanary-sample/src/main/res/mipmap-xxhdpi/ic_launcher.png b/blockcanary-sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 16854f6..2a3e83d 100644
Binary files a/blockcanary-sample/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/blockcanary-sample/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/blockcanary-sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/blockcanary-sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..2a3e83d
Binary files /dev/null and b/blockcanary-sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/blockcanary-sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/blockcanary-sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..7d6b1dd
Binary files /dev/null and b/blockcanary-sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/blockcanary-sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/blockcanary-sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..7d6b1dd
Binary files /dev/null and b/blockcanary-sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/blockcanary-sample/src/main/res/values/dimens.xml b/blockcanary-sample/src/main/res/values/dimens.xml
index ad34f6b..73a8f4d 100644
--- a/blockcanary-sample/src/main/res/values/dimens.xml
+++ b/blockcanary-sample/src/main/res/values/dimens.xml
@@ -1,10 +1,4 @@
-
- 16dp
- 16dp
-
0dp
48dp
- 48dp
- 0.5dp
diff --git a/blockcanary-sample/src/main/res/values/ic_launcher_background.xml b/blockcanary-sample/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..c5d5899
--- /dev/null
+++ b/blockcanary-sample/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFF
+
\ No newline at end of file
diff --git a/blockcanary-sample/src/main/res/values/styles.xml b/blockcanary-sample/src/main/res/values/styles.xml
index 5e0dd50..b309e57 100644
--- a/blockcanary-sample/src/main/res/values/styles.xml
+++ b/blockcanary-sample/src/main/res/values/styles.xml
@@ -3,11 +3,10 @@
-
diff --git a/build.gradle b/build.gradle
index 2e498be..f3e8219 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,21 +4,32 @@ buildscript {
repositories {
mavenCentral()
jcenter()
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.2'
+ classpath 'com.android.tools.build:gradle:3.5.0'
}
}
allprojects {
repositories {
+ maven { url 'https://jitpack.io' }
mavenCentral()
jcenter()
+ google()
}
ext {
- LIBRARY_COMPILE_SDK_VERSION = 23
- LIBRARY_BUILD_TOOLS_VERSION = "23.0.3"
- LIBRARY_MIN_SDK_VERSION = 9
- LIBRARY_TARGET_SDK_VERSION = 22
+ LIBRARY_COMPILE_SDK_VERSION = 29
+ LIBRARY_MIN_SDK_VERSION = 16
+ LIBRARY_TARGET_SDK_VERSION = 29
}
+ gradle.projectsEvaluated {
+ tasks.withType(JavaCompile) {
+ options.compilerArgs << "-Xlint:deprecation"
+ }
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
}
diff --git a/gradle.properties b/gradle.properties
index d4b7bce..2eab12f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,21 +1,21 @@
-## Project-wide Gradle settings.
-#
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
-#
+
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-#
+org.gradle.jvmargs=-Xmx8192M
+
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
-#Sat Mar 05 00:07:08 CST 2016
-org.gradle.jvmargs=-Xmx8192M
-#org.gradle.jvmargs=-Xmx10248m -XX\:MaxPermSize\=512m -XX\:+HeapDumpOnOutOfMemoryError -Dfile.encoding\=UTF-8
-org.gradle.daemon=true
-org.gradle.configureondemand=true
org.gradle.parallel=true
-android.useDeprecatedNdk=true
\ No newline at end of file
+org.gradle.daemon=true
+org.gradle.configureondemand=false
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 2322723..5c2d1cf 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 586936a..f4d7b2b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Wed Apr 13 16:42:11 CST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
diff --git a/gradlew b/gradlew
index 9d82f78..b0d6d0a 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,20 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
##############################################################################
##
@@ -6,20 +22,38 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
+warn () {
echo "$*"
}
-die ( ) {
+die () {
echo
echo "$*"
echo
@@ -30,6 +64,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
+nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@@ -40,26 +75,11 @@ case "`uname`" in
MINGW* )
msys=true
;;
+ NONSTOP* )
+ nonstop=true
+ ;;
esac
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -85,7 +105,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -150,11 +170,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 8a0b282..15e1ee3 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -1,90 +1,100 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem http://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega