Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android实现多次闪退清除数据大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

很多时候由于后台返回的数据异常,可能会导致App闪退。而如果这些异常数据被App本地缓存下来,那么即使杀掉进程重新进入还是会发生闪退。唯一的解决方法就是清除App数据,但是用户可能没有这个意识或者嫌麻烦就直接不再使用了,这是我们无法接受的。在使用淘宝、追书神器等App时我发现有时候它们也会连续闪退,但是往往闪退三次后就恢复正常了,所以一般成熟的App都会做连续闪退三次后清除缓存数据的工作。而目前笔者搜不到有哪篇blog来讲这方面的事情,所以就姑且由我来讲讲此事,为希望提高App用户体验的朋友提供些许参

ACRA
为了能够在闪退的时候做一些事情,我们可以使用ACRA,这是Github上的一个开源项目,允许使用者设置一些Sender在App闪退的时候做一些事情。具体使用可以直接参Github。如果不希望使用ACRA,那么也可以自己实现一个UncachedExceptionHandler并替换系统认的Handler,并在这个Handler里面对数据进行处理。

实现清除数据
ACRA提供了自己的一些Sender,如使用系统邮件客户端向指定邮箱发送邮件的EmailIntentSender。而我们希望记录闪退次数和清除数据则需要implements ReportSender接口。

public class CrashHandler implements ReportSender {
  @Override
  public void send(Context context,CrashReportData errorContent) throws ReportSenderException {
    Timber.i("闪退,检查是否需要清空数据");
    new CrashModel().checkAndClearData();
  }
}

这里我们写了一个CrashModel用来记录闪退次数和时间决定是否需要清空数据,具体代码如下。 由于在ReportSender的时候无法打开其它线程,所以我们无法使用SharedPerferences来清理数据(打开SP的时候其实打开了一个新线程)。为此需要找到数据缓存的位置并将文件删除。同样道理,记录闪退时间也只能通文件记录。当然,你可以选择一些文件不进行删除,如用户信息等不太容易出问题的数据。

public class CrashModel {

  private static final String KEY_CRASH_TIMES = "crash_times";
  private static final String CRASH_TIME_file_name = "crash_time";
  //不能通过App.getPackagename获取包名,否则会有问题,只能认为cn.campusapp.campus。所以对于debug或者运营版本,清数据会把release的清掉
  private static final String FILE_DIR = String.format("/data/data/%s/",BuildConfig.APPLICATION_ID);
  private static final String account_file_name = String.format("%s%s",FILE_DIR,"shared_prefs/account_pref.xml");
  private static ArrayList<String> FILES_DONTNEED_deletE = new ArrayList<>(); //该目录中的文件不会被删除

  static {
    FILES_DONTNEED_deletE.add(account_file_name); //目前账号信息文件不会被删除,但是会手动改变数据,只保留userId accessToken 和school
  }

  protected ArrayList<Long> mCrashTimes;
  Gson gson = new Gson();
  private File mFileDir;

  public CrashModel() {
    mFileDir = new File(FILE_DIR);
    mCrashTimes = readCrashTimes();
    if (mCrashTimes == null) {
      mCrashTimes = new ArrayList<>();
      storeCrashTimes(mCrashTimes);
    }
  }


  public void checkAndClearData() {
    long timeNow = System.currentTimeMillis();

    if (checkClearData(timeNow,new ArrayList<>(mCrashTimes))) {
      Timber.i("已经在5分钟之内有三次闪退,需要清理数据");
      try {
        clearData();
      } catch (Exception E) {
        Timber.e(e,"清空所有数据失败");
      }
    } else {
      mCrashTimes.add(timeNow);
      storeCrashTimes(mCrashTimes);
      Timber.i("此次不需要清空数据,%s",gson.toJson(mCrashTimes));
    }
  }

  private void storeCrashTimes(ArrayList<Long> crashTimes) {
    try {
      String str = gson.toJson(crashTimes);
      Files.writeToFile(mFileDir,CRASH_TIME_file_name,str);
    } catch (Exception E) {
      Timber.e(e,"保存闪退时间失败");
    }

  }

  private ArrayList<Long> readCrashTimes() {
    try {
      String timestr = Files.readFileContent(mFileDir,CRASH_TIME_file_name);
      return gson.fromJson(timestr,new TypeToken<ArrayList<Long>>() {
      }.getType());
    } catch (Exception E) {
      Timber.e(e,"读取闪退时间失败");
    }
    return null;
  }

  /**
   * 检查是否需要清空数据,目前的清空策略是在5分钟之内有三次闪退的就清空数据,也就是从后往前遍历,只要前两次闪退发生在5分钟之内,就清空数据
   *
   * @return
   */
  private Boolean checkClearData(long time,ArrayList<Long> crashTimes) {
    Timber.i(gson.toJson(crashTimes));
    int count = 0;
    for (int i = crashTimes.size() - 1; i >= 0; i--) {
      long crashTime = crashTimes.get(i);
      if (time - crashTime <= 5 * 60 * 1000) {
        count++;
        if (count >= 2) {
          break;
        }
      }
    }
    if (count >= 2) {
      //在5分钟之内有三次闪退,这时候需要清空数据
      return true;
    } else {
      return false;
    }
  }

  /**
   * 清空数据,包括数据库中的和SharedPreferences中的
   *
   * @throws Exception
   */
  private void clearData() throws Exception {
    Timber.i("开始清理数据");
    Files.deleteFilesExceptSomeInDirectory(mFileDir,FILES_DONTNEED_Delete);
  }


}

然后我们需要将CrashHandler 添加到ACRA的异常处理Sender列表中。在你的Application类中添加如下代码

@ReportsCrashes(
  //一些ACRA的设置,具体参ACRA文档,因为我们使用自定义Sender,所以这里完全可以不用设置
    //mailTo = "bugs@treeholeapp.cn",//mode = ReporTingInteractionMode.TOAST,//resToastText = R.String.crash_toast_text
)
public class App extends Application {

  @Override
  public void onCreate() {
   if (!BuildConfig.DEBUG) { //这里我判断只有在非DEBUG下才清除数据,主要是为了在开发过程中能够保留线程。
        ACRA.init(APPLICATION_COntexT);
        CrashHandler handler = new CrashHandler();
        ACRA.getErrorReporter().setReportSender(handler); //在闪退时检查是否要清空数据
    }

  }
}

总结
以上即为实现多次闪退后清除数据的实现,希望大家开发的App Bug越来越少。

大佬总结

以上是大佬教程为你收集整理的Android实现多次闪退清除数据全部内容,希望文章能够帮你解决Android实现多次闪退清除数据所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:清除数据