Giter Site home page Giter Site logo

markzhai / androidperformancemonitor Goto Github PK

View Code? Open in Web Editor NEW
6.6K 214.0 1.0K 1.05 MB

A transparent ui-block detection library for Android. (known as BlockCanary)

License: Apache License 2.0

Java 100.00%
android performance monitor apm blockcanary anr detection-library

androidperformancemonitor's Introduction

Chinese README

Android Performance Monitor Maven Central

A transparent ui-block detection library for Android, app only needs one-line-code to setup.

The naming is to pay respect to the great library LeakCanary, ui-related codes are modified from leakcanary's ui part.

  • 1.5.0 Add context that can stop monitor in debug mode.
  • 1.4.1 Bug fix.
  • 1.4.0 Bug fix, add onBlock interceptor in context.
  • 1.3.1 Enable configuration of label and icon.
  • 1.3.0 Add white-list and concern-package feature.

Getting started

You may choose how to assemble them as you like.

dependencies {
    // most often used way, enable notification to notify block event
    compile 'com.github.markzhai:blockcanary-android:1.5.0'

    // this way you only enable BlockCanary in debug package
    // debugCompile 'com.github.markzhai:blockcanary-android:1.5.0'
    // releaseCompile 'com.github.markzhai:blockcanary-no-op:1.5.0'
}

As this library uses getMainLooper().setMessageLogging(), please check if you set it in your app (related issue #27)

Usage

Maximum log count is set to 500, you can rewrite it in your app int.xml.

<integer name="block_canary_max_stored_count">1000</integer>

Monitor app's label and icon can be configured by placing a block_canary_icon drawable in your xhdpi drawable directory and in strings.xml:

<string name="block_canary_display_activity_label">Blocks</string>
public class DemoApplication extends Application {
    @Override
    public void onCreate() {
        // ...
        // Do it on main process
        BlockCanary.install(this, new AppBlockCanaryContext()).start();
    }
}

Implement your application BlockCanaryContext context (strongly recommend you to check all these configs):

public class AppBlockCanaryContext extends BlockCanaryContext {

    /**
     * Implement in your project.
     *
     * @return Qualifier which can specify this installation, like version + flavor.
     */
    public String provideQualifier() {
        return "unknown";
    }

    /**
     * Implement in your project.
     *
     * @return user id
     */
    public String provideUid() {
        return "uid";
    }

    /**
     * Network type
     *
     * @return {@link String} like 2G, 3G, 4G, wifi, etc.
     */
    public String provideNetworkType() {
        return "unknown";
    }

    /**
     * Config monitor duration, after this time BlockCanary will stop, use
     * with {@code BlockCanary}'s isMonitorDurationEnd
     *
     * @return monitor last duration (in hour)
     */
    public int provideMonitorDuration() {
        return -1;
    }

    /**
     * Config block threshold (in millis), dispatch over this duration is regarded as a BLOCK. You may set it
     * from performance of device.
     *
     * @return threshold in mills
     */
    public int provideBlockThreshold() {
        return 1000;
    }

    /**
     * Thread stack dump interval, use when block happens, BlockCanary will dump on main thread
     * stack according to current sample cycle.
     * <p>
     * Because the implementation mechanism of Looper, real dump interval would be longer than
     * the period specified here (especially when cpu is busier).
     * </p>
     *
     * @return dump interval (in millis)
     */
    public int provideDumpInterval() {
        return provideBlockThreshold();
    }

    /**
     * Path to save log, like "/blockcanary/", will save to sdcard if can.
     *
     * @return path of log files
     */
    public String providePath() {
        return "/blockcanary/";
    }

    /**
     * If need notification to notice block.
     *
     * @return true if need, else if not need.
     */
    public boolean displayNotification() {
        return true;
    }

    /**
     * Implement in your project, bundle files into a zip file.
     *
     * @param src  files before compress
     * @param dest files compressed
     * @return true if compression is successful
     */
    public boolean zip(File[] src, File dest) {
        return false;
    }

    /**
     * Implement in your project, bundled log files.
     *
     * @param zippedFile zipped file
     */
    public void upload(File zippedFile) {
        throw new UnsupportedOperationException();
    }


    /**
     * Packages that developer concern, by default it uses process name,
     * put high priority one in pre-order.
     *
     * @return null if simply concern only package with process name.
     */
    public List<String> concernPackages() {
        return null;
    }

    /**
     * Filter stack without any in concern package, used with @{code concernPackages}.
     *
     * @return true if filter, false it not.
     */
    public boolean filterNonConcernStack() {
        return false;
    }

    /**
     * Provide white list, entry in white list will not be shown in ui list.
     *
     * @return return null if you don't need white-list filter.
     */
    public List<String> provideWhiteList() {
        LinkedList<String> whiteList = new LinkedList<>();
        whiteList.add("org.chromium");
        return whiteList;
    }

    /**
     * Whether to delete files whose stack is in white list, used with white-list.
     *
     * @return true if delete, false it not.
     */
    public boolean deleteFilesInWhiteList() {
        return true;
    }

    /**
     * Block interceptor, developer may provide their own actions.
     */
    public void onBlock(Context context, BlockInfo blockInfo) {

    }
}

How does it work?

Blog in Chinese: BlockCanary.

Principle flow picture:

flow

Screenshot

Block detail Block list

Donation

If you find this repository helpful, you may make a donation to me via alipay or wechat. alipay wechat

Contributors

This library is initially created by markzhai, and maintained under the organization moduth with nimengbo and zzz40500.

Special thanks to android-cjj, Mr.Bao, chiahaolu to contribute.

Change Log

Check CHANGELOG

Contribute

If you would like to contribute code to BlockCanary you can do so through GitHub by forking the repository and sending a pull request.

License

Copyright (C) 2016 MarkZhai (http://zhaiyifan.cn).

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.

androidperformancemonitor's People

Contributors

android-cjj avatar baoyongzhang avatar markzhai avatar nimengbo avatar piasy avatar tanglie1993 avatar twlkyao avatar yaconggu avatar zeeshanasghar avatar zzz40500 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

androidperformancemonitor's Issues

堆栈信息无法折叠展开

查看Log信息的界面里,上面的CPU、Memory等三项信息可以折叠展开。但最后一项堆栈信息(可能有多次堆栈信息)不行。只会在最后面加上一句“blocked”。

这是BUG还是我的使用方式有误?

除此之外这个包非常好用,谢谢!

2.3 系统 Crash

在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)


在虚拟机上运行时,报空指针错误

在模拟器中运行程序,生成图标后,点击会报空指针:

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];

在没有开启BlockCanary的时候,启动DisplayBlockActivity会crash

没有开启的时候,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)

1.1.0打包release版本出错

dependencies {
    compile 'com.github.moduth:blockcanary-android:1.1.0'
    debugCompile 'com.github.moduth:blockcanary-ui:1.1.0'
}

debug版本正常

然,release:

2016-01-26 08-53-13

Try to sample thread stack when looper start dispatch message

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.

NullPointerException

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)

找不到BlockCanary类

你好,按照文档添加了下面依赖

    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')

}

White List support

BlockCanaryContext should expose a method for user to provide white-list prefix

Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference

新安装后,点击通知时报了这个,已初次化:

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;
    }
}

建议

hi,感觉这种方法应对ANR的情况比较合适,但应对界面卡顿的情况还是不太合适,造成界面卡顿的时间片粒度太小了。是否可以重新开一个用Choreographer计算frame的skip数来判断类似滑动界面的卡顿

读取log时,数组越界导致crash

配置BlockCanaryContext时,如果某个log字段为“”,那么Block newInstance(File )方法会抛出异常,跳过读取后续的字段。在DisplayBlockActivity 299行,block.timeStart为空,导致crash

YUNOS系统运行问题

请问这个工具能在YUNOS系统上跑吗?主线程sleep的时候endTime - mStartTimeMillis还是很小

申请一下修改许可

hi作者您好,您的项目我非常喜欢,非常实用。拜读过您的作品后我用kotlin将Block Canary复写了一下,用来兼容Kotlin代码检测。同时我还加入了一些其它功能,我把它开源并放在了这里
https://github.com/kiruto/debug-bottle
同时附上了您项目的链接和许可证,请问我可以这样做,并应用于我的项目吗?感谢过目

Android6.0权限问题

您好,我在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) 

NullPointerException when tested with Monkey

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) 

can't import in gradle

detail error :
Error:Could not find AndroidPerformanceMonitor:blockcanary-analyzer:unspecified.
Required by:
tvbox:box:unspecified > com.github.moduth:blockcanary-android:1.3.1

No resource found

/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'.

com.github.moduth:blockcanary-ui:1.1.0 AndroidManifest.xml不要允许备份吧

<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"

可以对某些类不进行检测吗?

比如加注释的类不检测,某些地方耗时无法避免,基本上是很难优化的,如果还一直生成日志或者上传,重复的太多会影响查看

need offline log analyzer

Analyze log files and output to readable format.

For analyze, I consider:

  1. parse stacktrace
  2. rank
  3. category

Any language can be fine, as it's done offline on pc or server.

NullPointerException: Attempt to invoke interface method 'java.lang.String com.github.moduth.blockcanary.IBlockCanaryContext.getLogPath()'

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.