Java源码示例:com.tencent.tinker.lib.tinker.Tinker

示例1
public static boolean tryRecoverDexFiles(Tinker manager, ShareSecurityCheck checker, Context context,
                                            String patchVersionDirectory, File patchFile) {
    if (!manager.isEnabledForDex()) {
        TinkerLog.w(TAG, "patch recover, dex is not enabled");
        return true;
    }
    String dexMeta = checker.getMetaContentMap().get(DEX_META_FILE);

    if (dexMeta == null) {
        TinkerLog.w(TAG, "patch recover, dex is not contained");
        return true;
    }

    long begin = SystemClock.elapsedRealtime();
    boolean result = patchDexExtractViaDexDiff(context, patchVersionDirectory, dexMeta, patchFile);
    long cost = SystemClock.elapsedRealtime() - begin;
    TinkerLog.i(TAG, "recover dex result:%b, cost:%d", result, cost);
    return result;
}
 
示例2
public static boolean tryRecoverLibraryFiles(Tinker manager, ShareSecurityCheck checker, Context context,
                                                String patchVersionDirectory, File patchFile) {

    if (!manager.isEnabledForNativeLib()) {
        TinkerLog.w(TAG, "patch recover, library is not enabled");
        return true;
    }
    String libMeta = checker.getMetaContentMap().get(SO_META_FILE);

    if (libMeta == null) {
        TinkerLog.w(TAG, "patch recover, library is not contained");
        return true;
    }
    long begin = SystemClock.elapsedRealtime();
    boolean result = patchLibraryExtractViaBsDiff(context, patchVersionDirectory, libMeta, patchFile);
    long cost = SystemClock.elapsedRealtime() - begin;
    TinkerLog.i(TAG, "recover lib result:%b, cost:%d", result, cost);
    return result;
}
 
示例3
public static boolean tryRecoverResourceFiles(Tinker manager, ShareSecurityCheck checker, Context context,
                                                 String patchVersionDirectory, File patchFile) {

    if (!manager.isEnabledForResource()) {
        TinkerLog.w(TAG, "patch recover, resource is not enabled");
        return true;
    }
    String resourceMeta = checker.getMetaContentMap().get(RES_META_FILE);

    if (resourceMeta == null || resourceMeta.length() == 0) {
        TinkerLog.w(TAG, "patch recover, resource is not contained");
        return true;
    }

    long begin = SystemClock.elapsedRealtime();
    boolean result = patchResourceExtractViaResourceDiff(context, patchVersionDirectory, resourceMeta, patchFile);
    long cost = SystemClock.elapsedRealtime() - begin;
    TinkerLog.i(TAG, "recover resource result:%b, cost:%d", result, cost);
    return result;
}
 
示例4
/**
 * 初始化 TinkerServer 实例
 * @param context context
 * @param tinker {@link Tinker} 实例
 * @param hours  访问服务器的时间间隔, 单位为小时, 应为 >= 0
 * @param appKey 从Tinkerpatch中得到的appKey
 * @param appVersion 在Tinkerpatch中填写的appVersion
 * @param channel 发布的渠道名称,由于GooglePlay渠道的政策限制,我们会停止所有channel中含有google关键字的动态下发功能。
 */
public static void installTinkerServer(
    Context context,
    Tinker tinker,
    int hours,
    String appKey,
    String appVersion,
    String channel
) {
    installTinkerServer(
        context,
        tinker,
        hours,
        appKey,
        appVersion,
        channel,
        new TinkerServerPatchRequestCallback()
    );
}
 
示例5
/**
 * 检查服务器是否有补丁更新
 * @param immediately 是否立刻检查,忽略时间间隔限制
 */
public static void checkTinkerUpdate(final boolean immediately) {
    if (sTinkerServerClient == null) {
        TinkerLog.e(TAG, "checkTinkerUpdate, sTinkerServerClient == null");
        return;
    }
    Tinker tinker = sTinkerServerClient.getTinker();
    //only check at the main process
    if (tinker.isMainProcess()) {
        Looper.getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override public boolean queueIdle() {
                sTinkerServerClient.checkTinkerUpdate(immediately);
                return false;
            }
        });
    }
}
 
示例6
/**
 * 向服务器请求在线参数信息
 * @param configRequestCallback
 * @param immediately            是否立刻请求,忽略时间间隔限制
 */
public static void getDynamicConfig(final ConfigRequestCallback configRequestCallback, final boolean immediately) {
    if (sTinkerServerClient == null) {
        TinkerLog.e(TAG, "checkTinkerUpdate, sTinkerServerClient == null");
        return;
    }
    Tinker tinker = sTinkerServerClient.getTinker();
    //only check at the main process
    if (tinker.isMainProcess()) {
        Looper.getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override public boolean queueIdle() {
                sTinkerServerClient.getDynamicConfig(configRequestCallback, immediately);
                return false;
            }
        });
    }
}
 
示例7
public void show_info(View view) {
    // add more Build Info
    final StringBuilder sb = new StringBuilder();
    Tinker tinker = Tinker.with(getApplicationContext());
    if (tinker.isTinkerLoaded()) {
        sb.append(String.format("[patch is loaded] \n"));
        sb.append(String.format("[buildConfig TINKER_ID] %s \n", BuildInfo.TINKER_ID));
        sb.append(String.format("[buildConfig BASE_TINKER_ID] %s \n", BaseBuildInfo.BASE_TINKER_ID));

        sb.append(String.format("[buildConfig MESSSAGE] %s \n", BuildInfo.MESSAGE));
        sb.append(String.format("[TINKER_ID] %s \n", tinker.getTinkerLoadResultIfPresent().getPackageConfigByName(ShareConstants.TINKER_ID)));
        sb.append(String.format("[packageConfig patchMessage] %s \n", tinker.getTinkerLoadResultIfPresent().getPackageConfigByName("patchMessage")));
        sb.append(String.format("[TINKER_ID Rom Space] %d k \n", tinker.getTinkerRomSpace()));

    } else {
        sb.append(String.format("[patch is not loaded] \n"));
        sb.append(String.format("[buildConfig TINKER_ID] %s \n", BuildInfo.TINKER_ID));
        sb.append(String.format("[buildConfig BASE_TINKER_ID] %s \n", BaseBuildInfo.BASE_TINKER_ID));

        sb.append(String.format("[buildConfig MESSSAGE] %s \n", BuildInfo.MESSAGE));
        sb.append(String.format("[TINKER_ID] %s \n", ShareTinkerInternals.getManifestTinkerID(getApplicationContext())));
    }
    sb.append(String.format("[BaseBuildInfo Message] %s \n", BaseBuildInfo.TEST_MESSAGE));

    final TextView v = new TextView(this);
    v.setText(sb);
    v.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
    v.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10);
    v.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    v.setTextColor(0xFF000000);
    v.setTypeface(Typeface.MONOSPACE);
    final int padding = 16;
    v.setPadding(padding, padding, padding, padding);

    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setCancelable(true);
    builder.setView(v);
    final AlertDialog alert = builder.create();
    alert.show();
}
 
示例8
private void initTinker(Context base) {
    // tinker需要你开启MultiDex
    MultiDex.install(base);

    TinkerManager.setTinkerApplicationLike(this);
    // 设置全局异常捕获
    TinkerManager.initFastCrashProtect();
    //开启升级重试功能(在安装Tinker之前设置)
    TinkerManager.setUpgradeRetryEnable(true);
    //设置Tinker日志输出类
    TinkerInstaller.setLogIml(new MyLogImp());
    //安装Tinker(在加载完multiDex之后,否则你需要将com.tencent.tinker.**手动放到main dex中)
    TinkerManager.installTinker(this);
    mTinker = Tinker.with(getApplication());
}
 
示例9
/**
 * try to recover patch oat file
 * @param file
 * @param fileType
 * @param isDirectory
 */
@Override
public void onLoadFileNotFound(File file, int fileType, boolean isDirectory) {
    TinkerLog.i(TAG, "patch loadReporter onLoadFileNotFound: patch file not found: %s, fileType:%d, isDirectory:%b",
            file.getAbsolutePath(), fileType, isDirectory);

    // only try to recover opt file
    // check dex opt file at last, some phone such as VIVO/OPPO like to change dex2oat to interpreted
    if (fileType == ShareConstants.TYPE_DEX_OPT) {
        Tinker tinker = Tinker.with(context);
        //we can recover at any process except recover process
        if (tinker.isMainProcess()) {
            File patchVersionFile = tinker.getTinkerLoadResultIfPresent().patchVersionFile;
            if (patchVersionFile != null) {
                if (UpgradePatchRetry.getInstance(context).onPatchListenerCheck(SharePatchFileUtil.getMD5(patchVersionFile))) {
                    TinkerLog.i(TAG, "try to repair oat file on patch process");
                    TinkerInstaller.onReceiveUpgradePatch(context, patchVersionFile.getAbsolutePath());
                } else {
                    TinkerLog.i(TAG, "repair retry exceed must max time, just clean");
                    checkAndCleanPatch();
                }
            }
        }
    } else {
        checkAndCleanPatch();
    }
    SampleTinkerReport.onLoadFileNotFound(fileType);
}
 
示例10
@Override
public int onPatchReceived(String path) {

    path = PatchUtils.release(path);

    int returnCode = patchCheck(path, SharePatchFileUtil.getMD5(new File(path)));

    if (returnCode == ShareConstants.ERROR_PATCH_OK) {
        SamplePatchService.runPatchService(context, path);
    } else {
        Tinker.with(context).getLoadReporter().onLoadPatchListenerReceiveFail(new File(path), returnCode);
    }
    return returnCode;

}
 
示例11
@Override
public boolean beforePatchRequest() {
    boolean result = super.beforePatchRequest();
    if (result) {
        TinkerServerClient client = TinkerServerClient.get();
        Tinker tinker = client.getTinker();
        Context context = client.getContext();

        if (!tinker.isMainProcess()) {
            TinkerLog.e(TAG, "beforePatchRequest, only request on the main process");
            return false;
        }
        if (TinkerServerManager.isGooglePlayChannel()) {
            TinkerLog.e(TAG, "beforePatchRequest, google play channel, return false");
            return false;
        }
        // main process must be the newly version
        // check whether it is pending work
        String currentPatchMd5 = client.getCurrentPatchMd5();
        TinkerLoadResult tinkerLoadResult = tinker.getTinkerLoadResultIfPresent();

        if (tinkerLoadResult.currentVersion == null || !currentPatchMd5.equals(tinkerLoadResult.currentVersion)) {
            Integer version = client.getCurrentPatchVersion();
            if (version > 0) {
                File patchFile = ServerUtils.getServerFile(
                    context, client.getAppVersion(), String.valueOf(version)
                );
                if (patchFile.exists() && patchFile.isFile() && handlePatchFile(context, version, patchFile)) {
                    return false;
                }
            }
        }
    }
    return result;
}
 
示例12
/**
 * 初始化 TinkerServer 实例
 * @param context context
 * @param tinker {@link Tinker} 实例
 * @param hours  访问服务器的时间间隔, 单位为小时, 应为 >= 0
 * @param appKey 从Tinkerpatch中得到的appKey
 * @param appVersion 在Tinkerpatch中填写的appVersion
 * @param channel 发布的渠道名称,由于GooglePlay渠道的政策限制,我们会停止所有channel中含有google关键字的动态下发功能。
 * @param patchRequestCallback {@link PatchRequestCallback} patch请求的callback
 */
public static void installTinkerServer(
    Context context,
    Tinker tinker,
    int hours,
    String appKey,
    String appVersion,
    String channel,
    PatchRequestCallback patchRequestCallback
) {
    final boolean debug = Debugger.getInstance(context).isDebug();
    TinkerLog.i(TAG, String.format("installTinkerServer, debug value: %s appVersion: %s, channel: %s",
        String.valueOf(debug), appVersion, channel)
    );
    sTinkerServerClient = TinkerServerClient.init(
        context,
        tinker,
        appKey,
        appVersion,
        debug,
        patchRequestCallback
    );
    // add channel condition
    sTinkerServerClient.updateTinkerCondition(CONDITION_CHANNEL, channel);
    sTinkerServerClient.setCheckIntervalByHours(hours);
    TinkerServerManager.channel = channel;
}
 
示例13
public void rollbackPatchDirectly() {
    TinkerServerClient client = TinkerServerClient.get();
    final Context context = client.getContext();
    final Tinker tinker = client.getTinker();
    //restart now
    tinker.cleanPatch();
    ShareTinkerInternals.killAllOtherProcess(context);
    android.os.Process.killProcess(android.os.Process.myPid());
}
 
示例14
public TinkerServerClient(Context context, Tinker tinker, String appKey,
                          String appVersion, Boolean debug, PatchRequestCallback patchRequestCallback) {
    this.tinker = tinker;
    this.context = context;
    this.clientAPI = TinkerClientAPI.init(context, appKey, appVersion, debug);
    this.patchRequestCallback = patchRequestCallback;
    makeDefaultConditions();
}
 
示例15
/**
 * 初始化 TinkerPatch 的 SDK, 使用默认的 {@link DefaultPatchRequestCallback}
 * @param context
 * @param tinker
 * @param appKey
 * @param appVersion
 * @param debug
 * @return
 */
public static TinkerServerClient init(Context context, Tinker tinker,
                                      String appKey, String appVersion, Boolean debug) {
    if (client == null) {
        synchronized (TinkerClientAPI.class) {
            if (client == null) {
                client = new TinkerServerClient(context, tinker, appKey,
                    appVersion, debug, new DefaultPatchRequestCallback());
            }
        }
    }
    return client;
}
 
示例16
/**
 * 初始化 TinkerPatch 的 SDK, 使用自定义的 {@link PatchRequestCallback}
 * @param context
 * @param tinker
 * @param appKey
 * @param appVersion
 * @param debug
 * @param patchRequestCallback
 * @return
 */
public static TinkerServerClient init(Context context, Tinker tinker, String appKey,
                                      String appVersion, Boolean debug, PatchRequestCallback patchRequestCallback) {
    if (client == null) {
        synchronized (TinkerClientAPI.class) {
            if (client == null) {
                client = new TinkerServerClient(context, tinker, appKey, appVersion, debug, patchRequestCallback);
            }
        }
    }
    return client;
}
 
示例17
public void uninstall_patch(View view) {
    ShareTinkerInternals.killAllOtherProcess(getApplicationContext());
    Tinker.with(getApplicationContext()).cleanPatch();
}
 
示例18
@Override
public void onPatchResult(final PatchResult result) {
    if (result == null) {
        TinkerLog.e(TAG, "received null result!!!!");
        return;
    }
    TinkerLog.i(TAG, "receive result: %s", result.toString());

    //first, we want to kill the recover process
    TinkerServiceInternals.killTinkerPatchServiceProcess(getApplicationContext());
    TinkerServerManager.reportTinkerPatchFail(result);

    if (result.isSuccess) {
        TinkerLog.i(TAG, "patch success, please restart process");
        File rawFile = new File(result.rawPatchFilePath);
        if (rawFile.exists()) {
            TinkerLog.i(TAG, "save delete raw patch file");
            SharePatchFileUtil.safeDeleteFile(rawFile);
        }
        //not like TinkerResultService, I want to restart just when I am at background!
        //if you have not install tinker this moment, you can use TinkerApplicationHelper api
        if (checkIfNeedKill(result)) {
            if (TinkerServerUtils.isBackground()) {
                TinkerLog.i(TAG, "it is in background, just restart process");
                restartProcess();
            } else {
                //we can wait process at background, such as onAppBackground
                //or we can restart when the screen off
                TinkerLog.i(TAG, "tinker wait screen to restart process");
                new TinkerServerUtils.ScreenState(
                    getApplicationContext(), new TinkerServerUtils.IOnScreenOff() {
                    @Override
                    public void onScreenOff() {
                        restartProcess();
                    }
                });
            }
        } else {
            TinkerLog.i(TAG, "I have already install the newly patch version!");
        }
    } else {
        TinkerLog.i(TAG, "patch fail, please check reason");
    }

    //repair current patch fail, just clean!
    if (!result.isSuccess) {
        //if you have not install tinker this moment, you can use TinkerApplicationHelper api
        Tinker.with(getApplicationContext()).cleanPatch();
    }
}
 
示例19
public Tinker getTinker() {
    return tinker;
}