feat: use bugly to report crash
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/.idea/caches
|
||||
.DS_Store
|
||||
/build
|
||||
/release
|
||||
|
||||
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "org.autojs.autojs"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 23
|
||||
versionCode 411
|
||||
versionName "4.0.2 Alpha6"
|
||||
versionCode 412
|
||||
versionName "4.0.2 Alpha7"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
ndk {
|
||||
@@ -140,6 +140,8 @@ dependencies {
|
||||
compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:4.0.3'
|
||||
// Flurry
|
||||
compile 'com.flurry.android:analytics:7.0.0@aar'
|
||||
// Bugly
|
||||
compile 'com.tencent.bugly:crashreport:2.6.6'
|
||||
// MaterialDialogCommon
|
||||
compile('com.afollestad.material-dialogs:commons:0.9.2.3', {
|
||||
exclude group: 'com.android.support'
|
||||
|
||||
7
app/proguard-rules.pro
vendored
7
app/proguard-rules.pro
vendored
@@ -133,4 +133,9 @@
|
||||
# AVLoadingView
|
||||
|
||||
-keep class com.wang.avi.** { *; }
|
||||
-keep class com.wang.avi.indicators.** { *; }
|
||||
-keep class com.wang.avi.indicators.** { *; }
|
||||
|
||||
# Bugly
|
||||
|
||||
-dontwarn com.tencent.bugly.**
|
||||
-keep public class com.tencent.bugly.**{*;}
|
||||
@@ -27,6 +27,8 @@ import org.autojs.autojs.tool.CrashHandler;
|
||||
import org.autojs.autojs.ui.error.ErrorReportActivity;
|
||||
import com.stardust.theme.ThemeColor;
|
||||
import com.stardust.theme.ThemeColorManager;
|
||||
import com.tencent.bugly.Bugly;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -38,6 +40,7 @@ import java.lang.ref.WeakReference;
|
||||
public class App extends MultiDexApplication {
|
||||
|
||||
private static final String TAG = "App";
|
||||
private static final String BUGLY_APP_ID = "19b3607b53";
|
||||
|
||||
private static WeakReference<App> instance;
|
||||
|
||||
@@ -64,7 +67,15 @@ public class App extends MultiDexApplication {
|
||||
|
||||
|
||||
private void setUpDebugEnvironment() {
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(ErrorReportActivity.class));
|
||||
CrashHandler crashHandler = new CrashHandler(ErrorReportActivity.class);
|
||||
|
||||
CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(getApplicationContext());
|
||||
strategy.setCrashHandleCallback(crashHandler);
|
||||
|
||||
CrashReport.initCrashReport(getApplicationContext(), BUGLY_APP_ID, false, strategy);
|
||||
|
||||
crashHandler.setDefaultHandler(Thread.getDefaultUncaughtExceptionHandler());
|
||||
Thread.setDefaultUncaughtExceptionHandler(crashHandler);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.autojs.autojs.network.entity.notification.Notification;
|
||||
import org.autojs.autojs.network.entity.notification.NotificationResponse;
|
||||
import org.autojs.autojs.network.entity.user.User;
|
||||
import com.stardust.util.Objects;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
@@ -77,6 +78,9 @@ public class UserService {
|
||||
private void setUser(User user) {
|
||||
User old = mUser;
|
||||
mUser = user;
|
||||
if(mUser != null){
|
||||
CrashReport.setUserId(mUser.getUid());
|
||||
}
|
||||
if (!Objects.equals(old, mUser)) {
|
||||
if (user == null) {
|
||||
NodeBB.getInstance().invalidateXCsrfToken();
|
||||
|
||||
@@ -15,17 +15,23 @@ import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
|
||||
import org.autojs.autojs.App;
|
||||
import org.autojs.autojs.BuildConfig;
|
||||
import org.autojs.autojs.R;
|
||||
|
||||
import com.stardust.util.IntentUtil;
|
||||
import com.stardust.view.accessibility.AccessibilityService;
|
||||
import com.tencent.bugly.Bugly;
|
||||
import com.tencent.bugly.crashreport.BuglyLog;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.util.Map;
|
||||
|
||||
public class CrashHandler implements UncaughtExceptionHandler {
|
||||
public class CrashHandler extends CrashReport.CrashHandleCallback implements UncaughtExceptionHandler {
|
||||
private static final String TAG = "CrashHandler";
|
||||
private static int crashCount = 0;
|
||||
private static long firstCrashMillis = 0;
|
||||
@@ -37,9 +43,14 @@ public class CrashHandler implements UncaughtExceptionHandler {
|
||||
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
|
||||
}
|
||||
|
||||
public void setDefaultHandler(UncaughtExceptionHandler defaultHandler) {
|
||||
mDefaultHandler = defaultHandler;
|
||||
}
|
||||
|
||||
public void uncaughtException(Thread thread, Throwable ex) {
|
||||
Log.e(TAG, "Uncaught Exception", ex);
|
||||
if (thread != Looper.getMainLooper().getThread()) {
|
||||
Log.e(TAG, "Uncaught Exception", ex);
|
||||
CrashReport.postCatchedException(ex, thread);
|
||||
return;
|
||||
}
|
||||
AccessibilityService service = AccessibilityService.getInstance();
|
||||
@@ -47,38 +58,25 @@ public class CrashHandler implements UncaughtExceptionHandler {
|
||||
Log.d(TAG, "disable service: " + service);
|
||||
service.disableSelf();
|
||||
} else {
|
||||
Log.d(TAG, "cannot disable service: " + service);
|
||||
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
mDefaultHandler.uncaughtException(thread, ex);
|
||||
return;
|
||||
}
|
||||
if (causedByBadWindowToken(ex)) {
|
||||
Toast.makeText(GlobalAppContext.get(), R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show();
|
||||
IntentUtil.goToAppDetailSettings(GlobalAppContext.get());
|
||||
} else {
|
||||
try {
|
||||
Log.e(TAG, "Uncaught Exception", ex);
|
||||
if (crashTooManyTimes())
|
||||
return;
|
||||
String msg = GlobalAppContext.getString(R.string.sorry_for_crash) + ex.toString();
|
||||
startErrorReportActivity(msg, throwableToString(ex));
|
||||
System.exit(1);
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
BuglyLog.d(TAG, "cannot disable service: " + service);
|
||||
}
|
||||
mDefaultHandler.uncaughtException(thread, ex);
|
||||
}
|
||||
|
||||
private static boolean causedByBadWindowToken(Throwable e) {
|
||||
while (e != null) {
|
||||
if (e instanceof WindowManager.BadTokenException) {
|
||||
return true;
|
||||
}
|
||||
e = e.getCause();
|
||||
@Override
|
||||
public synchronized Map<String, String> onCrashHandleStart(int crashType, String errorType,
|
||||
String errorMessage, String errorStack) {
|
||||
Log.d(TAG, "onCrashHandleStart: crashType = " + crashType + ", errorType = " + errorType + ", msg = "
|
||||
+ errorMessage + ", stack = " + errorStack);
|
||||
try {
|
||||
if (crashTooManyTimes())
|
||||
return super.onCrashHandleStart(crashType, errorType, errorMessage, errorStack);
|
||||
String msg = errorType + ": " + errorMessage;
|
||||
startErrorReportActivity(msg, errorStack);
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
return super.onCrashHandleStart(crashType, errorType, errorMessage, errorStack);
|
||||
}
|
||||
|
||||
private void startErrorReportActivity(String msg, String detail) {
|
||||
@@ -107,11 +105,5 @@ public class CrashHandler implements UncaughtExceptionHandler {
|
||||
return System.currentTimeMillis() - firstCrashMillis > 3000;
|
||||
}
|
||||
|
||||
public static String throwableToString(Throwable throwable) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
throwable.printStackTrace();
|
||||
throwable.printStackTrace(pw);
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
|
||||
import org.autojs.autojs.BuildConfig;
|
||||
import org.autojs.autojs.ui.BaseActivity;
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
@@ -80,43 +81,16 @@ public class ErrorReportActivity extends BaseActivity {
|
||||
.title(mTitle)
|
||||
.content(R.string.crash_feedback)
|
||||
.positiveText(R.string.text_exit)
|
||||
.neutralText(R.string.text_copy_debug_info)
|
||||
.negativeText(R.string.text_report_bug)
|
||||
.onPositive(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
exit();
|
||||
}
|
||||
})
|
||||
.onNeutral(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
copyToClip(getDeviceMessage() + errorDetail);
|
||||
exitAfter(1000);
|
||||
}
|
||||
})
|
||||
.onNegative(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
startIssueReportActivity();
|
||||
finish();
|
||||
}
|
||||
.negativeText(R.string.text_copy_debug_info)
|
||||
.onPositive((dialog, which) -> exit())
|
||||
.onNegative((dialog, which) -> {
|
||||
copyToClip(getDeviceMessage() + message + "\n" + errorDetail);
|
||||
exitAfter(1000);
|
||||
})
|
||||
.cancelable(false)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void startIssueReportActivity() {
|
||||
Intent intent = new Intent(this, IssueReporterActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
intent.putExtras(getIntent());
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void showErrorMessage(String message, String errorDetail) {
|
||||
((TextView) findViewById(R.id.error)).setText(message + "\n" + errorDetail);
|
||||
}
|
||||
|
||||
private String getDeviceMessage() {
|
||||
return String.format(Locale.getDefault(), "Version: %s\nAndroid: %d\n", BuildConfig.VERSION_CODE, Build.VERSION.SDK_INT);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.autojs.autojs.tool.IntentTool;
|
||||
import org.autojs.autojs.ui.BaseActivity;
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.stardust.util.IntentUtil;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
|
||||
import org.autojs.autojs.BuildConfig;
|
||||
import org.autojs.autojs.R;
|
||||
|
||||
@@ -87,7 +89,7 @@ public class AboutActivity extends BaseActivity {
|
||||
.title("Crash Test")
|
||||
.positiveText("Crash")
|
||||
.onPositive((dialog, which) -> {
|
||||
throw new RuntimeException("Crash Test");
|
||||
CrashReport.testJavaCrash();
|
||||
}).show();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<string name="text_lll">略略略</string>
|
||||
<string name="text_please_choose">请选择</string>
|
||||
<string name="text_crash">崩溃了o(≧口≦)o</string>
|
||||
<string name="crash_feedback">点击\"退出\"退出程序(ಥ _ ಥ)或者提交错误报告或者复制调试信息反馈给开发者(≧∇≦)ノ</string>
|
||||
<string name="crash_feedback">将会自动提交错误信息。您也可以手动复制调试信息提交给开发者(*^▽^*)或者点击\"退出\"退出程序o(╥﹏╥)o</string>
|
||||
<string name="text_clear">清空</string>
|
||||
<string name="text_console">控制台</string>
|
||||
<string name="text_log">日志</string>
|
||||
|
||||
@@ -1 +1 @@
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":411},"path":"commonRelease-4.0.2 Alpha6.apk","properties":{"packageId":"org.autojs.autojs","split":"","minSdkVersion":"17"}}]
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":412},"path":"commonRelease-4.0.2 Alpha7.apk","properties":{"packageId":"org.autojs.autojs","split":"","minSdkVersion":"17"}}]
|
||||
Reference in New Issue
Block a user