public void onPatchServiceStart(Intent intent) {
    if (!isRetryEnable) {
      TinkerLog.w(TAG, "onPatchServiceStart retry disabled, just return");
      return;
    }

    if (intent == null) {
      TinkerLog.e(TAG, "onPatchServiceStart intent is null, just return");
      return;
    }

    boolean isUpgrade = TinkerPatchService.getPatchUpgradeExtra(intent);

    if (!isUpgrade) {
      TinkerLog.w(TAG, "onPatchServiceStart is not upgrade patch, just return");
      return;
    }

    String path = TinkerPatchService.getPatchPathExtra(intent);

    if (path == null) {
      TinkerLog.w(TAG, "onPatchServiceStart patch path is null, just return");
      return;
    }

    RetryInfo retryInfo;
    File patchFile = new File(path);

    String patchMd5 = SharePatchFileUtil.getMD5(patchFile);
    if (patchMd5 == null) {
      TinkerLog.w(TAG, "onPatchServiceStart patch md5 is null, just return");
      return;
    }

    if (retryInfoFile.exists()) {
      retryInfo = RetryInfo.readRetryProperty(retryInfoFile);
      if (retryInfo.md5 == null || retryInfo.times == null || !patchMd5.equals(retryInfo.md5)) {
        copyToTempFile(patchFile);
        retryInfo.md5 = patchMd5;
        retryInfo.times = "1";
      } else {
        int nowTimes = Integer.parseInt(retryInfo.times);
        if (nowTimes >= RETRY_MAX_COUNT) {
          SharePatchFileUtil.safeDeleteFile(retryInfoFile);
          SharePatchFileUtil.safeDeleteFile(tempPatchFile);
          TinkerLog.w(
              TAG, "onPatchServiceStart retry more than max count, delete retry info file!");
          return;
        } else {
          retryInfo.times = String.valueOf(nowTimes + 1);
        }
      }

    } else {
      copyToTempFile(patchFile);
      retryInfo = new RetryInfo(patchMd5, "1");
    }

    RetryInfo.writeRetryProperty(retryInfoFile, retryInfo);
  }
  /**
   * if we receive any result, we can delete the temp retry info file
   *
   * @param isUpgradePatch
   */
  public void onPatchServiceResult(boolean isUpgradePatch) {
    if (!isRetryEnable) {
      TinkerLog.w(TAG, "onPatchServiceResult retry disabled, just return");
      return;
    }

    if (!isUpgradePatch) {
      TinkerLog.w(TAG, "onPatchServiceResult is not upgrade patch, just return");
      return;
    }

    // delete info file
    if (retryInfoFile.exists()) {
      SharePatchFileUtil.safeDeleteFile(retryInfoFile);
    }
    // delete temp patch file
    if (tempPatchFile.exists()) {
      SharePatchFileUtil.safeDeleteFile(tempPatchFile);
    }
  }
  private void copyToTempFile(File patchFile) {
    if (patchFile.getAbsolutePath().equals(tempPatchFile.getAbsolutePath())) {
      return;
    }
    TinkerLog.w(
        TAG,
        "try copy file: %s to %s",
        patchFile.getAbsolutePath(),
        tempPatchFile.getAbsolutePath());

    try {
      SharePatchFileUtil.copyFileUsingStream(patchFile, tempPatchFile);
    } catch (IOException e) {
    }
  }
    static RetryInfo readRetryProperty(File infoFile) {
      String md5 = null;
      String times = null;

      Properties properties = new Properties();
      FileInputStream inputStream = null;
      try {
        inputStream = new FileInputStream(infoFile);
        properties.load(inputStream);
        md5 = properties.getProperty(RETRY_FILE_MD5_PROPERTY);
        times = properties.getProperty(RETRY_COUNT_PROPERTY);
      } catch (IOException e) {
        e.printStackTrace();
      } finally {
        SharePatchFileUtil.closeQuietly(inputStream);
      }

      return new RetryInfo(md5, times);
    }
    static void writeRetryProperty(File infoFile, RetryInfo info) {
      if (info == null) {
        return;
      }

      File parentFile = infoFile.getParentFile();
      if (!parentFile.exists()) {
        parentFile.mkdirs();
      }

      Properties newProperties = new Properties();
      newProperties.put(RETRY_FILE_MD5_PROPERTY, info.md5);
      newProperties.put(RETRY_COUNT_PROPERTY, info.times);
      FileOutputStream outputStream = null;
      try {
        outputStream = new FileOutputStream(infoFile, false);
        newProperties.store(outputStream, null);
      } catch (Exception e) {
        //                e.printStackTrace();
        TinkerLog.printErrStackTrace(TAG, e, "retry write property fail");
      } finally {
        SharePatchFileUtil.closeQuietly(outputStream);
      }
    }
 /**
  * you must set after tinker has installed
  *
  * @param context
  */
 public UpgradePatchRetry(Context context) {
   this.context = context;
   retryInfoFile = new File(SharePatchFileUtil.getPatchDirectory(context), RETRY_INFO_NAME);
   tempPatchFile = new File(SharePatchFileUtil.getPatchDirectory(context), TEMP_PATCH_NAME);
 }