Bugly
1、基本介绍
-
Bugly 是腾讯推出的 App 质量追踪平台,专门帮开发者发现、定位、解决线上 App 的崩溃、卡顿等问题
-
Bugly 优势在于免费、接入简单,适合中小团队快速搭建质量监控体系
2、场景实例
-
以前:用户反馈"点了一下就闪退了",开发者复现不了,无从下手
-
现在:Bugly 后台直接看到崩溃堆栈、机型、系统版本、操作路径,精准定位到某行代码
3、演示
(1)Setting
- 项目级 build.gradle
groovy
android {
defaultConfig {
ndk {
abiFilters 'armeabi'
}
}
}
...
dependencies {
implementation 'com.tencent.bugly:crashreport:latest.release'
}
- AndroidManifest.xml
xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-
proguard-rules.pro,避免混淆 Bugly
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
(2)Activity
xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MainActivity"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_simulate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="模拟一个异常"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
java
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private final String[] permissions = {
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.ACCESS_WIFI_STATE
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
boolean needRequest = false;
for (String permission : permissions) {
int re = checkSelfPermission(permission);
Log.i(TAG, "check ---------- 权限:" + permission + ",授权结果:" + re);
if (re != PackageManager.PERMISSION_GRANTED) {
needRequest = true;
break;
}
}
if (!needRequest) {
next();
return;
}
ActivityResultLauncher<String[]> activityResultLauncher = registerForActivityResult(
new ActivityResultContracts.RequestMultiplePermissions(),
o -> {
for (Map.Entry<String, Boolean> stringBooleanEntry : o.entrySet()) {
Log.i(TAG, "request ---------- 权限:" + stringBooleanEntry.getKey() + ",授权结果:" + stringBooleanEntry.getValue());
}
for (boolean granted : o.values()) {
if (!granted) {
Toast.makeText(this, "未授权权限", Toast.LENGTH_SHORT).show();
finish();
return;
}
}
next();
}
);
activityResultLauncher.launch(permissions);
}
private void next() {
CrashReport.initCrashReport(getApplicationContext(), "【App ID】", false);
Button btnSimulate = findViewById(R.id.btn_simulate);
btnSimulate.setOnClickListener(v -> {
int i = 10 / 0;
});
}
}