Bugly集成 – 异常捕获

896次阅读
没有评论

之前一直都是采用友盟的全家桶进行的异常收集,索性最近有时间就给新项目集成了Bugly的异常手机 ~

此篇主要记录我使用AndroidStudio自动集成Bugly的整体过程与最终实现,具体的集成方式还是以Bugly官方文档为准 – Bugly Android SDK 使用指南

目前我仅知俩种捕获异常方式(主讲第二种方式)

系统自带的异常机制,一般是通过实现Thread.UncaughtExceptionHandler接口来实现异常监听
集成三方平台用于捕获异常,我有使用Bugly集成测试过 ~
本篇Bugly的集成Demo,我已上传此处 ~
自动集成
准备工作
新建产品
产品详情
集成场景
集成SDK
同时集成SDK和NDK
SDK与NDK最新版本
参数配置
添加权限
避免混淆Bugly
Bugly初始化
提要
方式1:Application 初始化
最简单方式
项目方式
方式2:AndroidManifest.xml 初始化
实战检验
自造错误
平台查看
大功告成
个性化需求
增加上报进程控制
设置App版本、渠道、包名
设置延迟Bugly初始化
动态设置开发设备
准备工作
首先去官网,然后右上角登录帐户(我是用的QQ快捷登录了)

新建产品
右上角 → 我的产品 → 新建产品

自行创建新产品即可 ~

产品详情
选择对应产品的的操作设置

产品详情 – 这里我们主要用到APP ID

集成场景
注:下方依赖中的 latest.release = 对应的SDK、NDK版本号

集成SDK
在Module的build.gradle文件中添加依赖和属性配置:

//注意:其中latest.release指代最新Bugly SDK版本号,也可以指定明确的版本号,例如2.2.0
implementation 'com.tencent.bugly:crashreport:latest.release'

同时集成SDK和NDK
在Module的build.gradle文件中添加依赖和属性配置:

android {
defaultConfig {
ndk {
// 设置支持的SO库架构
abiFilters ‘armeabi’ //, ‘x86’, ‘armeabi-v7a’, ‘x86_64’, ‘arm64-v8a’
}
}
}

dependencies {
//其中latest.release指代最新Bugly SDK版本号,也可以指定明确的版本号,例如2.1.9
implementation ‘com.tencent.bugly:crashreport:latest.release’
//其中latest.release指代最新Bugly NDK版本号,也可以指定明确的版本号,例如3.0
implementation ‘com.tencent.bugly:nativecrashreport:latest.release’
}

如下

SDK与NDK最新版本
Android 异常上报 SDK 更新日志(版本)

注:如需集成SDK可将下图中最近的 3.2.422更新版本号 替换 依赖中的 latest.release

Android NDK 动态库更新日志(版本)

注:如需集成 NDK 可将下图中最近的 3.7.5更新版本号 替换 依赖中的 latest.release

参数配置
添加权限
在AndroidManifest.xml中添加权限:

注:如果您的App需要上传到google play store,您需要将READ_PHONE_STATE权限屏蔽掉或者移除,否则可能会被下架

避免混淆Bugly
请避免混淆Bugly,在Proguard混淆文件中增加以下配置:

注:这点建立在你的项目有混淆的基础上,如果你没有混淆的话,可以忽略此处 ~

-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.*{;}

Bugly初始化
以下俩种初始化方式,二选其一即可,建议采用项目方式!

注:如同时采用俩种方式进行初始化,那么以Application的初始化方式为准!

提要
因Bugly初始化一般都在Application内,而在项目开发中我们都会有自己的Application,例如我写Demo的时候就是创建的BuglyApplication继承了Application,当我们有自己的Application时记得在清单文件中进行注册,否则一切配置均无效 ~,如下

<!--主要声明:android:name=".BuglyApplication"-->
<application
    android:allowBackup="true"
    android:name=".BuglyApplication"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:networkSecurityConfig="@xml/network_security_config"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

方式1:Application 初始化
注:为了保证运营数据的准确性,建议不要在异步线程初始化Bugly

最简单方式
获取APP ID并将以下代码复制到项目Application类onCreate()中,Bugly会为自动检测环境并完成配置:

CrashReport.initCrashReport(getApplicationContext(), “注册时申请的APPID”, false);

项目方式
主要增加了上报进程控制和一些个性化需求,从而更贴近项目的实战场景 ~ 此处代码完全Copy到项目中使用 !

BuglyApplication

package nk.com.buglytest;

import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;

import com.tencent.bugly.Bugly;
import com.tencent.bugly.crashreport.CrashReport;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**

  • @author MrLiu
  • @date 2020/10/14
  • desc
    */
    public class BuglyApplication extends Application {
    @Override
    public void onCreate() {
    super.onCreate(); Context context = getApplicationContext(); // 获取当前包名 String packageName = context.getPackageName(); // 获取当前进程名 String processName = getProcessName(android.os.Process.myPid()); // 设置是否为上报进程 CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(context); strategy.setUploadProcess(processName == null || processName.equals(packageName)); //设置渠道 strategy.setAppChannel("自行设置或动态读取渠道 ~"); //App的版本 strategy.setAppVersion(getVersionCode(this)); //App的包名 strategy.setAppPackageName(packageName); // CrashReport.setIsDevelopmentDevice(context, true);
    /*
    *第三个参数为SDK调试模式开关, true:测试环境 false:正式环境,调试模式的行为特性如下:
    *- 输出详细的Bugly SDK的Log
    *- 每一条Crash都会被立即上报
    *- 自定义日志将会在Logcat中输出
    *建议在测试阶段建议设置成true,发布时设置为false ~
    */
    CrashReport.initCrashReport(getApplicationContext(), “APPID”, true, strategy);
    //userId
    CrashReport.setUserId(“2020”);
    } /**
    • 获取进程号对应的进程名
      *
    • @param pid 进程号
    • @return 进程名
      */
      private static String getProcessName(int pid) {
      BufferedReader reader = null;
      try {
      reader = new BufferedReader(new FileReader(“/proc/” + pid + “/cmdline”));
      String processName = reader.readLine();
      if (!TextUtils.isEmpty(processName)) {
      processName = processName.trim();
      }
      return processName;
      } catch (Throwable throwable) {
      throwable.printStackTrace();
      } finally {
      try {
      if (reader != null) {
      reader.close();
      }
      } catch (IOException exception) {
      exception.printStackTrace();
      }
      }
      return null;
      }

    /**

    • 返回版本号
    • 对应build.gradle中的versionCode
      *
    • @param context context
    • @return String
      */
      public static String getVersionCode(Context context) {
      String versionCode = “”;
      try {
      PackageManager packageManager = context.getPackageManager();
      PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
      versionCode = String.valueOf(packInfo.versionCode);
      } catch (Exception e) {
      e.printStackTrace();
      }
      return versionCode;
      }
      }

方式2:AndroidManifest.xml 初始化
Bugly2.0及以上版本还支持通过”AndroidManifest.xml”来配置APP信息。如果同时又通过代码中配置了APP信息,则最终以代码配置的信息为准

在AndroidManifest.xml的”Application”中增加“meta-data”配置项:
注:”BUGLY_APP_VERSION”配置的是Bugly平台的APP版本号!而不是”android:versionName”!

通过”AndroidManifest.xml”配置后的初始化方法如下:

CrashReport.initCrashReport(getApplicationContext());

实战检验
自造错误
package nk.com.buglytest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import com.tencent.bugly.crashreport.CrashReport;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    findViewById(R.id.tv_btn1).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Bugly自带的一个造错方法,想自己写个崩溃也行
            CrashReport.testJavaCrash();
        }
    });
}

}

平台查看
我的产品 – 点击已创建好的商品

崩溃分析

大功告成
查看具体崩溃详情后,发现错误详情还是蛮详细的,所以可以收工咯 ~

个性化需求
关于个性化需求在我认为都是针对的项目开发场景进行的功能扩展,其具体的扩展内容可 前往官方文档进行查看 ~

增加上报进程控制
如果App使用了多进程且各个进程都会初始化Bugly(例如在Application类onCreate()中初始化Bugly),那么每个进程下的Bugly都会进行数据上报,造成不必要的资源浪费 ~

因此,为了节省流量、内存等资源,建议初始化的时候对上报进程进行控制,只在主进程下上报数据:判断是否是主进程(通过进程名是否为包名来判断),并在初始化Bugly时增加一个上报进程的策略配置

Context context = getApplicationContext();
// 获取当前包名
String packageName = context.getPackageName();
// 获取当前进程名
String processName = getProcessName(android.os.Process.myPid());
// 设置是否为上报进程
UserStrategy strategy = new UserStrategy(context);
strategy.setUploadProcess(processName == null || processName.equals(packageName));
// 初始化Bugly
CrashReport.initCrashReport(context, “注册时申请的APPID”, isDebug, strategy);
// 如果通过“AndroidManifest.xml”来配置APP信息,初始化方法如下
// CrashReport.initCrashReport(context, strategy);

其中获取进程名的方法“getProcessName”有多种实现方法,推荐方法如下:

/**

  • 获取进程号对应的进程名
    • @param pid 进程号
  • @return 进程名
    */
    private static String getProcessName(int pid) {
    BufferedReader reader = null;
    try {
    reader = new BufferedReader(new FileReader(“/proc/” + pid + “/cmdline”));
    String processName = reader.readLine();
    if (!TextUtils.isEmpty(processName)) {
    processName = processName.trim();
    }
    return processName;
    } catch (Throwable throwable) {
    throwable.printStackTrace();
    } finally {
    try {
    if (reader != null) {
    reader.close();
    }
    } catch (IOException exception) {
    exception.printStackTrace();
    }
    }
    return null;
    }

设置App版本、渠道、包名
Bugly默认读取AndroidManifest.xml文件中VersionName、Package信息。若您有自己的版本或渠道设定需求,可通过该接口修改

strategy.setAppChannel(“myChannel”); //设置渠道
strategy.setAppVersion(“1.0.1”); //App的版本
strategy.setAppPackageName(“com.tencent.xx”); //App的包名

设置延迟Bugly初始化
Bugly会在启动10s后联网同步数据。若您有特别需求,可以修改这个时间 ~

方式1:将此属性在初始化钱就设置完成

strategy.setAppReportDelay(20000); //改为20s

方式2:初始化完成后,通过 CrashReport.setUserId(“userId”)进行设置

    CrashReport.initCrashReport(getApplicationContext(), "APPID", true, strategy);
    //设置 userId
    CrashReport.setUserId("2020");

动态设置开发设备
在开发测试阶段,可以在初始化Bugly之前通过以下接口把调试设备设置成“开发设备”

CrashReport.setIsDevelopmentDevice(context, true);

ADT 17增加了BuildConfig特性,可以通过获取BuildConfig类的DEBUG变量来设置:

CrashReport.setIsDevelopmentDevice(context, BuildConfig.DEBUG);

这里主要通过BuildConfig.DEBUG来判断当前apk是debug包还是release包,故个人感觉可以在项目初始化时让第三个参数使用BuildConfig.DEBUG

//改前
CrashReport.initCrashReport(getApplicationContext(), “2329160dcf”, true, strategy);
//改后
CrashReport.initCrashReport(getApplicationContext(), “2329160dcf”, BuildConfig.DEBUG, strategy);

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 
评论(没有评论)