Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please update project with this pull request, containing changes from all current forks #131

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f8073f5
fixed condition
hehonghui Aug 19, 2017
f3a469b
remove permission WRITE_EXTERNAL_STORAGE & READ_PHONE_STATE
Aug 21, 2017
0280d0c
Update README_CN.md
pscj Aug 21, 2017
5017305
Update README_CN.md
pscj Aug 21, 2017
da42202
Update README_CN.md
pscj Aug 21, 2017
cfda0a8
Android O 停止 cpu 采样
Jul 19, 2018
0e2f46d
add support for oreo
okasurya Jun 26, 2019
762eed2
target29
GvcZhang Jul 23, 2019
c7c859a
升级 gradle
Jul 19, 2018
7d9d79c
初步优化代码
Jul 19, 2018
6e04342
优化依赖
Jul 19, 2018
f2783f1
本地依赖
Jul 19, 2018
b145934
Judge white list is null
Sep 14, 2018
29276b9
Remove imei analysis
Sep 14, 2018
ea3de35
Add NetUtils to get network type
Sep 14, 2018
cf621a4
Rename fields
Sep 14, 2018
170a29b
上报异常
Jun 8, 2019
3d002db
Update Gradle to v3.4.2, fix some inspection warnings, display notifi…
1951FDG Aug 12, 2019
394aa39
Use NotificationCompat.Builder
1951FDG Aug 12, 2019
ed9b600
Update layout of sample app
1951FDG Aug 12, 2019
d397b38
Fourth action titled " WAIT FOR MORE" is not implemented yet
1951FDG Aug 12, 2019
e6f681d
/proc/stat is no longer accessible in Android O
1951FDG Aug 12, 2019
bff502f
Increase number of times loop is run to ensure that on newer devices …
1951FDG Aug 12, 2019
2e4ba4e
Fix some inspection warnings
1951FDG Aug 12, 2019
2e34405
Catch all inspection warnings available
1951FDG Aug 12, 2019
f46805d
Add JitPack
1951FDG Aug 12, 2019
c682b9a
Update to AndroidX, Android Studio 3.5
1951FDG Sep 25, 2019
fcfd5c6
Increase number of times loop is run to ensure that on newer devices …
1951FDG Sep 25, 2019
aabd172
Fix some inspection warnings
1951FDG Sep 25, 2019
b249897
修改配置
Aug 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
@@ -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平台的一个非侵入式的性能监控组件,应用只需要实现一个抽象类,提供一些该组件需要的上下文环境,就可以在平时使用应用的时候检测主线程上的各种卡慢问题,并通过组件提供的各种信息分析出原因并进行修复。

Expand Down
8 changes: 5 additions & 3 deletions blockcanary-analyzer/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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'])
}
10 changes: 8 additions & 2 deletions blockcanary-analyzer/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
xmlns:android="http://schemas.android.com/apk/res/android">

<!-- To store the heap dumps and leak analysis results. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
android:maxSdkVersion="18" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<application/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -40,7 +40,7 @@ public void run() {
};

public AbstractSampler(long sampleInterval) {
if (0 == sampleInterval) {
if ( sampleInterval <= 0 ) {
sampleInterval = DEFAULT_SAMPLE_INTERVAL;
}
mSampleInterval = sampleInterval;
Expand All @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.github.moduth.blockcanary;

import android.os.Build;
import android.os.Environment;
import android.os.Looper;

Expand All @@ -35,13 +36,11 @@ public final class BlockCanaryInternals {
private static BlockCanaryInternals sInstance;
private static BlockCanaryContext sContext;

private List<BlockInterceptor> mInterceptorChain = new LinkedList<>();
private final List<BlockInterceptor> 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());

Expand All @@ -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());

Expand Down Expand Up @@ -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();
}
Expand All @@ -145,7 +151,7 @@ public static File[] getLogFiles() {

private static class BlockLogFileFilter implements FilenameFilter {

private String TYPE = ".log";
private final String TYPE = ".log";

BlockLogFileFilter() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,16 @@ class StackSampler extends AbstractSampler {
private static final int DEFAULT_MAX_ENTRY_COUNT = 100;
private static final LinkedHashMap<Long, String> 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);
Expand Down Expand Up @@ -59,8 +67,8 @@ public ArrayList<String> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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";
Expand All @@ -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
Expand All @@ -94,28 +87,18 @@ public class BlockInfo {
public boolean cpuBusy;
public String cpuRateInfo;
public ArrayList<String> 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() {
Expand All @@ -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;
Expand All @@ -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();
Expand All @@ -163,6 +145,11 @@ public BlockInfo setThreadStackEntries(ArrayList<String> 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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;

}
}
Loading