1

我创建了一个位置跟踪应用程序,每次更改位置时都会写入本地 SQLite 数据库。不幸的是,该应用程序在跟踪大约 7-8 小时后崩溃了,不幸的是,当我将设备连接到调试器时不会发生这种情况,因此没有可以附加的日志。更多可能有用的信息:

  • 应用程序在从后台唤醒之前崩溃(可以在跟踪的数据中清楚地看到),所以我可以从其他应用程序中排除这个错误
  • 试图写入文本文件而不是数据库但没有任何成功(在崩溃前运行了大约 3 小时)
  • 更改跟踪间隔(5s 正常 1s 最快间隔):相同的结果应用程序在 7-8 小时后也崩溃

以下是一些代码片段:

位置变更事件

@Override
public void onLocationChanged(Location location) {
    if(location == null){
        location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(location == null) {
            return;
        }
    }
    Log.d(TAG, location.toString());
    double currentLatitude = location.getLatitude();
    double currentLongitude = location.getLongitude();
    ActivitylogRepo activityRepo = new ActivitylogRepo(this);
    Activitylog activity = new Activitylog();
    activity.activity = "Position";
    activity.timestamp = getDateTime();
    activity.value2 = String.valueOf(currentLatitude);
    activity.value3 = String.valueOf(currentLongitude);
    activityRepo.insert(activity);
}

数据库插入命令

public int insert(Activitylog activitylog) {

    //Open connection to write data
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(Activitylog.KEY_activity, activitylog.activity);
    values.put(Activitylog.KEY_timestamp, activitylog.timestamp);
    values.put(Activitylog.KEY_value1, activitylog.value1);
    values.put(Activitylog.KEY_value2, activitylog.value2);
    values.put(Activitylog.KEY_value3, activitylog.value3);
    values.put(Activitylog.KEY_value4, activitylog.value4);


    // Inserting Row
    long activitylog_id = db.insert(Activitylog.TABLE, null, values);
    db.close(); // Closing database connection
    return (int) activitylog_id;
}

初始化服务

mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();

    mLocationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(20 * 1000)        // 20s in ms
            .setFastestInterval(5 * 1000); // 5s in ms
4

1 回答 1

1

即使您没有连接到调试器,我也有一些东西可以帮助您捕获崩溃报告 - 从而帮助您找到问题的根源!我已将此作为答案发布,因此我可以很好地格式化它。

下面的课程将处理未捕获的异常,将它们打包到电子邮件中并在您的手机上放置通知(您可以根据需要进行调整)

public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {

    private Context mContext;

    private java.lang.Thread.UncaughtExceptionHandler mDefaultUEH;

    public UncaughtExceptionHandler(Context context, java.lang.Thread.UncaughtExceptionHandler defaultUEH) {
        mContext = context;
        mDefaultUEH = defaultUEH;
    }

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {

        // Make error into something more readable
        String timestamp = android.text.format.DateFormat.getLongDateFormat(mContext).format(
                new Date(System.currentTimeMillis()));
        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        ex.printStackTrace(printWriter);
        String stacktrace = result.toString();
        printWriter.close();

        // Create email intent for error
        Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setType("text/html");
        emailIntent.putExtra(Intent.EXTRA_EMAIL, "email address");
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Crash Report " + timestamp);
        emailIntent.putExtra(Intent.EXTRA_TEXT, stacktrace);

        // Make into pending intent for notifcation

        PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0,
                Intent.createChooser(emailIntent, "Send report with.."), 
                Intent.FLAG_ACTIVITY_NEW_TASK);

        // here create a notification for the user
        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
        builder.setContentTitle("Crash Caught");
        builder.setContentText("Send to Developer");
        builder.setContentIntent(pendingIntent);
        builder.setAutoCancel(true);
        builder.setSmallIcon(R.drawable.ic_notification);

        // Finally display the notification!
        NotificationManager mNotificationManager = (NotificationManager) mContext
                .getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(1337, builder.build());

        // re-throw critical exception further to the os (important)
        mDefaultUEH.uncaughtException(thread, ex);
    }
}

在您的 Application 类中进行设置,如下所示:

public class App extends Application {

    @Override
    public void onCreate() {
    super.onCreate();

    /*
     * Set up uncaught exception handler
     */

    java.lang.Thread.UncaughtExceptionHandler defaultUEH =
    Thread.getDefaultUncaughtExceptionHandler();
    Thread.setDefaultUncaughtExceptionHandler(new
    UncaughtExceptionHandler(this, defaultUEH));

    }

}

我不建议在您的发布版本中包含此代码!此时,您可以使用开发者控制台获取崩溃报告。

于 2015-09-22T08:20:18.367 回答