阅读 269

Android性能优化之疑难杂症解决方案,U-APM的性能监控分析

关于Android发展至今,在各项功能十分成熟的情况下,我们越来越重视App的性能优化,以及用户体验,这关乎一个线上应用的DAU持续增长的基础,以及用户口碑的问题,今天刘某人带大家来一起分析一下崩溃/卡顿/ANR/OOM/启动慢等问题是如何解决的,以及使用友盟性能监控平台U-APM的便捷。

一.启动慢/白屏/黑屏优化

我们在应用开发的时候,常常会提前初始化一些数据和功能,来保证用户使用的过程中,不会产生额外的停留,等待时间,那么当一个项目十分庞大的时候,初始化的数据也非常的多,另外由于设备的性能,渲染的机制等各种原因,时常会出现启动慢导致白屏,黑屏等情况,基于此情况,我们来看下如何解决。

1.修改主题/背景图

我们先来看下Activity的结构

1.jpg

修改主题只需要将启动页的主题修改为透明或者图片,这样在ContentView加载出来之前,我们会透过启动的Activity看到桌面,就不会有黑/白屏的现象。再把标题栏去掉,把Activity设置成全屏的,效果挺不错,缺点是如果启动的是一个有复杂耗时操作的Activity,那么会有一种延迟的感觉。

将主题背景设置成一张图片,把标题栏去掉,把Activity设置成全屏的,这这样在ContentView加载出来之前,我们就能看到一张默认背景图,但是图片的屏幕适配问题就需要考虑了,主题里的背景图片会自动拉伸,可能会导致失真或者比例失调的问题,解决办法是使用一张.9的图片。

代码如下

    <item name="android:windowBackground">@android:color/transparent</item>     <item name="android:windowFullscreen">true</item>     <item name="android:navigationBarColor">@android:color/transparent</item>     <item name="android:statusBarColor">@android:color/transparent</item>     <item name="windowNoTitle">true</item>     <item name="windowActionBar">false</item>     <item name="android:windowContentOverlay">@null</item>     <item name="android:windowDisablePreview">false</item>

2.初始化时机

我们常见的初始化,无外乎在Application的onCreate或者启动页的onCreate创建回调中进行初始化,但是了解生命周期你可以发现,实际上onCreate还在进行渲染的操作,所以我们可以把初始化的动作放在onResume中,但是onResume是多次回调的,所以我们还需要进行初始化的判断。

代码如下

@Override

protected void onResume() {

    super.onResume();

    //未初始化才进行初始化

    if (!ThirdSDK.getInstance().isInit()) {

        ThirdSDK.getInstance().init();

    }

}

3.子线程初始化

如果非强制必要在主线程使用,或者非强制要快速初始化,快速调用的函数,我们可以通过在子线程初始化的方式来优化大量函数初始化的情况

代码如下

public class BaseApp extends Application {

    @Override

    public void onCreate() {

        super.onCreate();

        //多进程的情况下,只在主进程进行一次初始化

        if (CommonUtils.isMainProcess()) {

            new Thread(() -> {

                if (!ThirdSDK.getInstance().isInit()) {

                    ThirdSDK.getInstance().init();

                }

            }).start();

        }

    }

}

4.ConstraintLayout

约束布局已经成为Android Studio官方模板中默认的父布局了,可见其地位,ConstraintLayout

可让您使用扁平视图层次结构(无嵌套视图组)创建复杂的大型布局。它与 RelativeLayout 相似,其中所有的视图均根据同级视图与父布局之间的关系进行布局,但其灵活性要高于 RelativeLayout,并且更易于与 Android Studio 的布局编辑器配合使用。  他针对的不光是启动页的优化,所以放在最后,ConstraintLayout能减少布局渲染的层级,也能起到一定的优化作用。  

具体使用方式可以参考Google文档:

developer.android.google.cn/training/co… 

二.崩溃/ANR/OOM

1.崩溃

崩溃的问题是运行时所产生的,并且会抛出Exception,最常见的就是空指针,数组越界等异常了,如果是调试过程中出现崩溃,我相信稍微有一些基础的同学都知道如何去解决问题,在logcat中搜索AndroidRuntime即可,解决起来根据错误提示修复即可,如果非调试状态,而是在线上,那我们就需要日志的采集了,崩溃日志采集一般本地化做的话,徒增了很多的工作量,我比较推荐友盟的移动统计U-App来采集日志,使用方法见下文

2.ANR

ANR的表现在老的Android版本上会弹出一个提示框(应用已停止),但是现在主流的版本一般都是直接闪退了,ANR的处理方式比较复杂,需要根据堆栈的溢出信息来逐步分析,表现如图

2.jpg

负责更新界面的应用主线程无法处理用户输入事件或绘制操作,这样会引起用户的不满,所以系统会根据当前的场景等待,等待超时则停止响应,一般以下几种情况会导致ANR。

1.当您的 Activity 位于前台时,您的应用在 5 秒钟内未响应输入事件或 BroadcastReceiver(如按键或屏幕轻触事件)。

2.虽然前台没有 Activity,但您的 BroadcastReceiver 用了相当长的时间仍未执行完毕。

Android 提供了一些方式来帮助我们分析出问题,详情可以查看下官方的文档

developer.android.google.cn/topic/perfo… 

当然,关于线上的App出现问题,我们就需要借助友盟的U-App来采集日志,才方便我们分析问题,使用方法见下文。  

3.OOM

OOM内存溢出,出现的情况大多数是在引用图片上出的问题,全称“Out Of Memory”,最常见的OOM情况有以下三种:

l  java.lang.OutOfMemoryError: Java heap space

¡  java堆内存溢出,此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。对于内存泄露,需要通过内存监控软件查找程序中的泄露代码,而堆大小可以通过虚拟机参数-Xms,-Xmx等修改。

l  java.lang.OutOfMemoryError: PermGen space

¡  java永久代溢出,即方法区溢出了,一般出现于大量Class或者jsp页面,或者采用cglib等反射机制的情况,因为上述情况会产生大量的Class信息存储于方法区。此种情况可以通过更改方法区的大小来解决,使用类似-XX:PermSize=64m -XX:MaxPermSize=256m的形式修改。另外,过多的常量尤其是字符串也会导致方法区溢出。

l  java.lang.StackOverflowError

¡  不会抛OOM error,但也是比较常见的Java内存溢出。JAVA虚拟机栈溢出,一般是由于程序中存在死循环或者深度递归调用造成的,栈大小设置太小也会出现此种溢出。可以通过虚拟机参数-Xss来设置栈的大小。

我们通常使用heapdump来分析内存的波形查找问题,当然,我们也可以先采集日志,见下文

三.U-APM

1.集成

我们可以使用友盟的APM先把日志采集了,便于我们解决问题,U-APM是在原U-App 稳定性分析基础上全新升级的独立产品,所以已计入的同学直接升级即可:at.umtrack.com/LrKb0f

3.jpg

按照文档描述我们来接入,接入的流程步骤如图

4.jpg

1.我们首先在project的build.gradle中添加友盟的仓库,如图示代码

5.jpg

2.在app/build.gradle中添加依赖

6.jpg

3.添加权限

7.jpg

4.初始化,需要先调用预初始化,再调用初始化

8.jpg

好的,一切准备就绪,我们就可以来模拟下错误的采集了,但是要注意,APP_KEY是需要自己去申请的,而APP_CHANNEL对应的是渠道标记,如果没有多渠道,可以无视,如果有多渠道的打包和统计,那么传入对应渠道名即可。

2.使用

来到友盟APM管理平台

9.jpg

可以看到我创建的DEMO显示已集成APM,我来模拟一条空指针的错误

10.jpg

可以看到,实时显示,并且抓到的日志是比较精准的,我们来看下详情

11.jpg

这样就大功告成了,再有崩溃,ANR,OOM都能捕捉到了,而且可以基于友盟的基础能力,我们可以实时统计日活,事件上报等功能,还是蛮不错的。

当然,采集到日志,包括检测到异常,我们拿到日志,都是要自己分析的,这个分析的过程,还是需要个人的经验,以及细心和耐心,解决Bug的道路是枯燥且乏味的,静下心来,才能体验代码之美。

作者:刘桂林



作者:性能优化实践者
链接:https://juejin.cn/post/7031810482881167396

文章分类
ANDROID
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐