markzhai / androidperformancemonitor Goto Github PK
View Code? Open in Web Editor NEWA transparent ui-block detection library for Android. (known as BlockCanary)
License: Apache License 2.0
A transparent ui-block detection library for Android. (known as BlockCanary)
License: Apache License 2.0
例如,自定义Block之后让App崩溃掉或者是弹出对话框之类的?
/XXXX/build/intermediates/exploded-aar/com.github.moduth/blockcanary/1.0.0/res/values-v21/values-v21.xml
Error:(2) Error retrieving parent for item: No resource found that matches the given name 'android:Theme.Material'.
06-02 18:07:50.253 E/AndroidRuntime(27493): FATAL EXCEPTION: pool-7-thread-1
06-02 18:07:50.253 E/AndroidRuntime(27493): Process: com.youku.phone, PID: 27493
06-02 18:07:50.253 E/AndroidRuntime(27493): java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String com.github.moduth.blockcanary.IBlockCanaryContext.getLogPath()' on a null object reference
06-02 18:07:50.253 E/AndroidRuntime(27493): at com.github.moduth.blockcanary.log.BlockCanaryInternals.getPath(BlockCanaryInternals.java:30)
06-02 18:07:50.253 E/AndroidRuntime(27493): at com.github.moduth.blockcanary.log.BlockCanaryInternals.detectedLeakDirectory(BlockCanaryInternals.java:38)
06-02 18:07:50.253 E/AndroidRuntime(27493): at com.github.moduth.blockcanary.log.BlockCanaryInternals.getLogFiles(BlockCanaryInternals.java:46)
06-02 18:07:50.253 E/AndroidRuntime(27493): at com.github.moduth.blockcanary.ui.DisplayBlockActivity$LoadBlocks.run(DisplayBlockActivity.java:395)
06-02 18:07:50.253 E/AndroidRuntime(27493): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
06-02 18:07:50.253 E/AndroidRuntime(27493): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
06-02 18:07:50.253 E/AndroidRuntime(27493): at java.lang.Thread.run(Thread.java:818)
Currently the ThreadStackSampler
do sample from time to time, though it is a not time-costy operation(1000 times cost 30ms), it's still somehow meaningless.
We can try to post a message to TimerThread
to tell ThreadStackSampler
to doSample
when looper starts dispatching message (maybe delay a threshold time), and remove that message when looper finishes dispatching.
The only worry is that if some important thread stack can be lost, especially when doing thread synchronization.
java.lang.NullPointerException
at com.github.moduth.blockcanary.ui.DisplayBlockActivity.getBlock(DisplayBlockActivity.java:311)
at com.github.moduth.blockcanary.ui.DisplayBlockActivity.updateUi(DisplayBlockActivity.java:216)
at com.github.moduth.blockcanary.ui.DisplayBlockActivity.access$400(DisplayBlockActivity.java:64)
at com.github.moduth.blockcanary.ui.DisplayBlockActivity$LoadBlocks$2.run(DisplayBlockActivity.java:416)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
<application android:allowBackup="true"
android:label="@string/app_name">
<activity
android:name=".ui.DisplayBlockActivity"
android:icon="@drawable/block_canary_icon"
android:label="@string/display_activity_label"
android:taskAffinity="com.github.moduth.blockcanary"
android:theme="@style/block_canary_BlockCanary.Base">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
android:allowBackup="false"
你好,按照文档添加了下面依赖
compile 'com.github.moduth:blockcanary-android:1.1.0'
debugCompile 'com.github.moduth:blockcanary-ui:1.1.0'
但是在工程中找不到BlockCanary类,有没有可能和其他的库有冲突?
以下是我项目的依赖
dependencies {
def AndroidSupportVersion = "23.1.1"
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile "com.android.support:recyclerview-v7:$AndroidSupportVersion"
compile "com.android.support:appcompat-v7:$AndroidSupportVersion"
compile "com.android.support:design:$AndroidSupportVersion"
compile "com.android.support:cardview-v7:$AndroidSupportVersion"
compile "com.android.support:percent:$AndroidSupportVersion"
compile 'com.google.code.gson:gson:2.5'
compile 'eu.the4thfloor.volley:com.android.volley:2015.05.28'
compile 'com.github.bumptech.glide:glide:3.6.1'
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
compile 'com.github.moduth:blockcanary-android:1.1.0'
debugCompile 'com.github.moduth:blockcanary-ui:1.1.0'
compile project(':refreshLibrary')
compile project(':baselibrary')
compile project(':ThirdLibrary')
compile project(':zxinglibrary')
}
您好,我在android6.0下集成Blockcanary,出现下面的错误,应该是Runtime Permission机制导致的(后来在系统设置里手工设置权限后重启应用没有再出现)。请教Blockcanary现在处理Runtime Permisssion是不是通过发送权限授权通知?
错误信息如下:
05-10 10:42:03.196 4973-5451/cn.com.panchan.homelauncher.debug E/LogWriter: saveLogToSDCard:
java.io.FileNotFoundException: /data/storage/emulated/0/Android/data/cn.com.example.homelauncher.debug/files/log/blockcanary/looper-2016-05-10_10-42-03.193.txt: open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:459)
at java.io.FileOutputStream.(FileOutputStream.java:87)
at java.io.FileOutputStream.(FileOutputStream.java:127)
at com.github.moduth.blockcanary.LogWriter.saveLogToSDCard(LogWriter.java:105)
at com.github.moduth.blockcanary.LogWriter.saveLooperLog(LogWriter.java:53)
at com.github.moduth.blockcanary.BlockCanaryCore$1.onBlockEvent(BlockCanaryCore.java:60)
at com.github.moduth.blockcanary.LooperPrinter$1.run(LooperPrinter.java:72)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
at libcore.io.IoBridge.open(IoBridge.java:445)
at java.io.FileOutputStream.(FileOutputStream.java:87)
at java.io.FileOutputStream.(FileOutputStream.java:127)
at com.github.moduth.blockcanary.LogWriter.saveLogToSDCard(LogWriter.java:105)
at com.github.moduth.blockcanary.LogWriter.saveLooperLog(LogWriter.java:53)
at com.github.moduth.blockcanary.BlockCanaryCore$1.onBlockEvent(BlockCanaryCore.java:60)
at com.github.moduth.blockcanary.LooperPrinter$1.run(LooperPrinter.java:72)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.os.HandlerThread.run(HandlerThread.java:61)
hi,感觉这种方法应对ANR的情况比较合适,但应对界面卡顿的情况还是不太合适,造成界面卡顿的时间片粒度太小了。是否可以重新开一个用Choreographer计算frame的skip数来判断类似滑动界面的卡顿
我觉得原来的名字也蛮好的阿
detail error :
Error:Could not find AndroidPerformanceMonitor:blockcanary-analyzer:unspecified.
Required by:
tvbox:box:unspecified > com.github.moduth:blockcanary-android:1.3.1
没有开启的时候,BlockCanaryCore.getContext()返回是null,导致崩溃,崩溃堆栈如下:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String com.github.moduth.blockcanary.IBlockCanaryContext.getLogPath()' on a null object reference
at com.github.moduth.blockcanary.log.BlockCanaryInternals.getPath(BlockCanaryInternals.java:30)
at com.github.moduth.blockcanary.log.BlockCanaryInternals.detectedLeakDirectory(BlockCanaryInternals.java:38)
at com.github.moduth.blockcanary.log.BlockCanaryInternals.getLogFiles(BlockCanaryInternals.java:46)
at com.github.moduth.blockcanary.ui.DisplayBlockActivity$LoadBlocks.run(DisplayBlockActivity.java:395)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
BlockCanaryContext should expose a method for user to provide white-list prefix
在模拟器中运行程序,生成图标后,点击会报空指针:
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at com.github.moduth.blockcanary.log.Block.newInstance(Block.java:152)
at com.github.moduth.blockcanary.ui.DisplayBlockActivity$LoadBlocks.run(DisplayBlockActivity.java:394)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
看了下代码,是Block.java 152行:
block.timeStart = line.split(" = ")[1];
hi,
it's hard to find what code of my own project leads to the block. so what if highlighting the project code in the back trace.
Currently BlockCanary directly calls getMainLooper().setMessageLogging()
to do monitor, which may conflicts with the original logging set by app, we can add a append mode for those situation.
配置BlockCanaryContext时,如果某个log字段为“”,那么Block newInstance(File )方法会抛出异常,跳过读取后续的字段。在DisplayBlockActivity 299行,block.timeStart为空,导致crash
I saw you use a lot of UI of leakcanary
, probably some of the content of the README
. And leakcanary is inder Apache 2.0.
You did not use that license, and give any credit neither.
compile 'com.github.moduth:blockcanary-android:1.1.1'
FATAL EXCEPTION: main
Process: com.xxxx.xxx, PID: 26457
java.lang.RuntimeException: Unable to stop activity {com.xxxx.xxx/com.github.moduth.blockcanary.ui.DisplayBlockActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.internal.view.menu.MenuBuilder.close()' on a null object reference
at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3359)
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3405)
at android.app.ActivityThread.access$1200(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1322)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5238)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:931)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:726)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.internal.view.menu.MenuBuilder.close()' on a null object reference
at android.widget.ActionMenuPresenter$OverflowPopup.onDismiss(ActionMenuPresenter.java:685)
at android.widget.PopupWindow.dismiss(PopupWindow.java:1364)
at android.widget.ListPopupWindow.dismiss(ListPopupWindow.java:656)
at com.android.internal.view.menu.MenuPopupHelper.dismiss(MenuPopupHelper.java:157)
at android.widget.ActionMenuPresenter.hideOverflowMenu(ActionMenuPresenter.java:332)
at android.widget.ActionMenuPresenter.dismissPopupMenus(ActionMenuPresenter.java:343)
at android.widget.ActionMenuView.dismissPopupMenus(ActionMenuView.java:679)
at android.widget.Toolbar.dismissPopupMenus(Toolbar.java:391)
at com.android.internal.widget.ToolbarWidgetWrapper.dismissPopupMenus(ToolbarWidgetWrapper.java:394)
at com.android.internal.widget.ActionBarOverlayLayout.dismissPopups(ActionBarOverlayLayout.java:810)
at com.android.internal.policy.impl.PhoneWindow.checkCloseActionMenu(PhoneWindow.java:860)
at com.android.internal.policy.impl.PhoneWindow.closePanel(PhoneWindow.java:815)
at com.android.internal.policy.impl.PhoneWindow.closeAllPanels(PhoneWindow.java:1025)
at android.app.Activity.performStop(Activity.java:6083)
at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3356)
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3405)
at android.app.ActivityThread.access$1200(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1322)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5238)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
It's much harder to understand the sample app if the comments are in "not" English.
Please could you use English? Thanks. :)
在2.3系统上,会发生crash ,日志如下
AndroidRuntime﹕ FATAL EXCEPTION: BlockCanaryThread_writelog
java.lang.IllegalArgumentException: contentView required: pkg=***id=-558907665 notification=Notification(vibrate=null,sound=null,defaults=0x0,flags=0x10)
at android.os.Parcel.readException(Parcel.java:1326)
at android.os.Parcel.readException(Parcel.java:1276)
at android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:274)
at android.app.NotificationManager.notify(NotificationManager.java:111)
at android.app.NotificationManager.notify(NotificationManager.java:91)
at com.github.moduth.blockcanary.BlockCanary.notify(BlockCanary.java:194)
at com.github.moduth.blockcanary.BlockCanary.access$200(BlockCanary.java:29)
at com.github.moduth.blockcanary.BlockCanary$1.onBlockEvent(BlockCanary.java:67)
at com.github.moduth.blockcanary.LooperPrinter$1.run(LooperPrinter.java:57)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.os.HandlerThread.run(HandlerThread.java:60)
LeakCanary example:
<string name="leak_canary_display_activity_label">Demo_Leaks</string>
RT.
hi作者您好,您的项目我非常喜欢,非常实用。拜读过您的作品后我用kotlin将Block Canary复写了一下,用来兼容Kotlin代码检测。同时我还加入了一些其它功能,我把它开源并放在了这里
https://github.com/kiruto/debug-bottle
同时附上了您项目的链接和许可证,请问我可以这样做,并应用于我的项目吗?感谢过目
把UI那部分抽出去,核心只留记录log那块,因为可能线上也用,但是只打log然后上传。
新安装后,点击通知时报了这个,已初次化:
04-13 22:28:18.183 8079-8079/com.ms.meizinewsapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ms.meizinewsapplication, PID: 8079
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.github.moduth.blockcanary.ui.DisplayBlockActivity.getBlock(DisplayBlockActivity.java:313)
at com.github.moduth.blockcanary.ui.DisplayBlockActivity.updateUi(DisplayBlockActivity.java:218)
at com.github.moduth.blockcanary.ui.DisplayBlockActivity.access$400(DisplayBlockActivity.java:65)
at com.github.moduth.blockcanary.ui.DisplayBlockActivity$LoadBlocks$2.run(DisplayBlockActivity.java:420)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5691)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
public class AppBlockCanaryContext extends BlockCanaryContext {
private static final String TAG = "AppBlockCanaryContext";
/**
* 标示符,可以唯一标示该安装版本号,如版本+渠道名+编译平台
*
* @return apk唯一标示符
*/
@Override
public String getQualifier() {
String qualifier = "";
try {
PackageInfo info = MyApplication.getAppContext().getPackageManager()
.getPackageInfo(MyApplication.getAppContext().getPackageName(), 0);
qualifier += info.versionCode + "_" + info.versionName + "_YYB";
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "getQualifier exception", e);
}
return qualifier;
}
@Override
public String getUid() {
return "87224330";
}
@Override
public String getNetworkType() {
return "4G";
}
@Override
public int getConfigDuration() {
return 9999;
}
@Override
public int getConfigBlockThreshold() {
return 500;
}
/**
* 是否开启通知
*
* @return
*/
@Override
public boolean isNeedDisplay() {
return true;
}
}
对leakcanary不是了解,哪个更好呢?
Block类内部有一段代码
if (block.imei == null || block.imei.length() == 0) {
TelephonyManager mTManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
block.imei = mTManager.getDeviceId();
}
这个在Android6.0上运行,如果没有电话权限会导致崩溃
请问这个工具能在YUNOS系统上跑吗?主线程sleep的时候endTime - mStartTimeMillis还是很小
Analyze log files and output to readable format.
For analyze, I consider:
Any language can be fine, as it's done offline on pc or server.
代码混淆编译不过 proguard文件缺少说明
比如加注释的类不检测,某些地方耗时无法避免,基本上是很难优化的,如果还一直生成日志或者上传,重复的太多会影响查看
查看Log信息的界面里,上面的CPU、Memory等三项信息可以折叠展开。但最后一项堆栈信息(可能有多次堆栈信息)不行。只会在最后面加上一句“blocked”。
这是BUG还是我的使用方式有误?
除此之外这个包非常好用,谢谢!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.