国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現多次閃退清除數據

2019-12-12 06:38:17
字體:
來源:轉載
供稿:網友

很多時候由于后臺返回的數據異常,可能會導致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越來越少。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 杭锦后旗| 黄龙县| 久治县| 常熟市| 威远县| 酉阳| 塔河县| 格尔木市| 南丰县| 合阳县| 敦化市| 昭苏县| 牟定县| 融水| 揭阳市| 大邑县| 塔城市| 灵宝市| 星子县| 临安市| 北流市| 郑州市| 溆浦县| 锡林郭勒盟| 美姑县| 东至县| 宜章县| 咸宁市| 澎湖县| 乌兰察布市| 台前县| 韶山市| 桓台县| 扶余县| 凤庆县| 昌邑市| 枣庄市| 莎车县| 双辽市| 德保县| 林州市|