接入Tinker

接入tinker目前给了两种方式,一种是基于命令行的方式,类似于AndFix的接入方式;一种就是gradle的方式。

考虑早期使用Andfix的app应该挺多的,以及很多人对gradle的相关配置还是觉得比较繁琐的,下面对两种方式都介绍下。

(1)命令行接入

接入之前我们先考虑下,接入的话,正常需要的前提(开启混淆的状态)。

  • 对于API

    一般来说,我们接入热修库,会在Application#onCreate中进行一下初始化操作。然后在某个地方去调用类似loadPatch这样的API去加载patch文件。

  • 对于patch的生成

    简单的方式就是通过两个apk做对比然后生成;需要注意的是:两个apk做对比,需要的前提条件,第二次打包混淆所使用的mapping文件应该和线上apk是一致的。

最后就是看看这个项目有没有需要配置混淆;

有了大致的概念,我们就基本了解命令行接入tinker,大致需要哪些步骤了。

依赖引入

dependencies {// ...//可选,用于生成application类provided('com.tencent.tinker:tinker-android-anno:1.7.7')//tinker的核心库compile('com.tencent.tinker:tinker-android-lib:1.7.7')
}

顺便加一下签名的配置:

android{//...signingConfigs {release {try {storeFile file("release.keystore")storePassword "testres"keyAlias "testres"keyPassword "testres"} catch (ex) {throw new InvalidUserDataException(ex.toString())}}}buildTypes {release {minifyEnabled truesigningConfig signingConfigs.releaseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}debug {debuggable trueminifyEnabled truesigningConfig signingConfigs.releaseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}

文末会有demo的下载地址,可以直接参考build.gradle文件,不用担心这些签名文件去哪找。

API引入

API主要就是初始化和loadPacth。

正常情况下,我们会考虑在Application的onCreate中去初始化,不过tinker推荐下面的写法:

@DefaultLifeCycle(application = ".SimpleTinkerInApplication",flags = ShareConstants.TINKER_ENABLE_ALL,loadVerifyFlag = false)
public class SimpleTinkerInApplicationLike extends ApplicationLike {public SimpleTinkerInApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);}@Overridepublic void onBaseContextAttached(Context base) {super.onBaseContextAttached(base);}@Overridepublic void onCreate() {super.onCreate();TinkerInstaller.install(this);}
}

ApplicationLike通过名字你可能会猜,并非是Application的子类,而是一个类似Application的类。

tinker建议编写一个ApplicationLike的子类,你可以当成Application去使用,注意顶部的注解:@DefaultLifeCycle,其application属性,会在编译期生成一个SimpleTinkerInApplication类。

所以,虽然我们这么写了,但是实际上Application会在编译期生成,所以AndroidManifest.xml中是这样的:

 <applicationandroid:name=".SimpleTinkerInApplication".../>

编写如果报红,可以build下。

这样其实也能猜出来,这个注解背后有个Annotation Processor在做处理,如果你没了解过,可以看下:

  • Android 如何编写基于编译时注解的项目

通过该文会对一个编译时注解的运行流程和基本API有一定的掌握,文中也会对tinker该部分的源码做解析。

上述,就完成了tinker的初始化,那么调用loadPatch的时机,我们直接在Activity中添加一个Button设置:


public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void loadPatch(View view) {TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(),Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed.apk");}
}

我们会将patch文件直接push到sdcard根目录;

所以一定要注意:添加SDCard权限,如果你是6.x以上的系统,自己添加上授权代码,或者手动在设置页面打开SDCard读写权限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

除以以外,有个特殊的地方就是tinker需要在AndroidManifest.xml中指定TINKER_ID。

<application><meta-dataandroid:name="TINKER_ID"android:value="tinker_id_6235657" />//...
</application>

到此API相关的就结束了,剩下的就是考虑patch如何生成。

patch生成

tinker提供了patch生成的工具,源码见:tinker-patch-cli,打成一个jar就可以使用,并且提供了命令行相关的参数以及文件。

命令行如下:

java -jar tinker-patch-cli-1.7.7.jar -old old.apk -new new.apk -config tinker_config.xml -out output

需要注意的就是tinker_config.xml,里面包含tinker的配置,例如签名文件等。

这里我们直接使用tinker提供的签名文件,所以不需要做修改,不过里面有个Application的item修改为与本例一致:

<loader value="com.zhy.tinkersimplein.SimpleTinkerInApplication"/>

大致的文件结构如下:

可以在tinker-patch-cli中提取,或者直接下载文末的例子。

上述介绍了patch生成的命令,最后需要注意的就是,在第一次打出apk的时候,保留下生成的mapping文件,在/build/outputs/mapping/release/mapping.txt

可以copy到与proguard-rules.pro同目录,同时在第二次打修复包的时候,在proguard-rules.pro中添加上:

-applymapping mapping.txt

保证后续的打包与线上包使用的是同一个mapping文件。

tinker本身的混淆相关配置,可以参考:

  • tinker_proguard.pro

如果,你对该部分描述不了解,可以直接查看源码即可。

测试

首先随便生成一个apk(API、混淆相关已经按照上述引入),安装到手机或者模拟器上。

然后,copy出mapping.txt文件,设置applymapping,修改代码,再次打包,生成new.apk。

两次的apk,可以通过命令行指令去生成patch文件。

如果你下载本例,命令需要在[该目录]下执行。

最终会在output文件夹中生成产物:

我们直接将patch_signed.apk push到sdcard,点击loadpatch,一定要观察命令行是否成功。

本例修改了title。

点击loadPatch,观察log,如果成功,应用默认为重启,然后再次启动即可达到修复效果。

到这里命令行的方式就介绍完了,和Andfix的接入的方式基本上是一样的。

值得注意的是:该例仅展示了基本的接入,对于tinker的各种配置信息,还是需要去读tinker的文档(如果你确定要使用)tinker-wiki。

(2)gradle接入

gradle接入的方式应该算是主流的方式,所以tinker也直接给出了例子,单独将该tinker-sample-android以project方式引入即可。

引入之后,可以查看其接入API的方式,以及相关配置。

在你每次build时,会在build/bakApk下生成本地打包的apk,R文件,以及mapping文件。

如果你需要生成patch文件,可以通过:

./gradlew tinkerPatchRelease  // 或者 ./gradlew tinkerPatchDebug

生成。

生成目录为:build/outputs/tinkerPatch

需要注意的是,需要在app/build.gradle中设置相比较的apk(即old.apk,本次为new.apk),

ext {tinkerEnabled = true//old apk file to build patch apktinkerOldApkPath = "${bakPath}/old.apk"//proguard mapping file to build patch apktinkerApplyMappingPath = "${bakPath}/old-mapping.txt"
}

提供的例子,基本上展示了tinker的自定义扩展的方式,具体还可以参考:

  • Tinker-自定义扩展

所以,如果你使用命令行方式接入,也不要忘了学习下其支持哪些扩展。

三、Application是如何编译时生成的

从注释和命名上看:

//可选,用于生成application类
provided('com.tencent.tinker:tinker-android-anno:1.7.7')

明显是该库,其结构如下:

典型的编译时注解的项目,源码见tinker-android-anno。

入口为com.tencent.tinker.anno.AnnotationProcessor,可以在该services/javax.annotation.processing.Processor文件中找到处理类全路径。

再次建议,如果你不了解,简单阅读下Android 如何编写基于编译时注解的项目该文。

直接看AnnotationProcessor的process方法:

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {processDefaultLifeCycle(roundEnv.getElementsAnnotatedWith(DefaultLifeCycle.class));return true;
}

直接调用了processDefaultLifeCycle:

private void processDefaultLifeCycle(Set<? extends Element> elements) {// 被注解DefaultLifeCycle标识的对象for (Element e : elements) {// 拿到DefaultLifeCycle注解对象DefaultLifeCycle ca = e.getAnnotation(DefaultLifeCycle.class);String lifeCycleClassName = ((TypeElement) e).getQualifiedName().toString();String lifeCyclePackageName = lifeCycleClassName.substring(0, lifeCycleClassName.lastIndexOf('.'));lifeCycleClassName = lifeCycleClassName.substring(lifeCycleClassName.lastIndexOf('.') + 1);String applicationClassName = ca.application();if (applicationClassName.startsWith(".")) {applicationClassName = lifeCyclePackageName + applicationClassName;}String applicationPackageName = applicationClassName.substring(0, applicationClassName.lastIndexOf('.'));applicationClassName = applicationClassName.substring(applicationClassName.lastIndexOf('.') + 1);String loaderClassName = ca.loaderClass();if (loaderClassName.startsWith(".")) {loaderClassName = lifeCyclePackageName + loaderClassName;}// /TinkerAnnoApplication.tmplfinal InputStream is = AnnotationProcessor.class.getResourceAsStream(APPLICATION_TEMPLATE_PATH);final Scanner scanner = new Scanner(is);final String template = scanner.useDelimiter("\\A").next();final String fileContent = template.replaceAll("%PACKAGE%", applicationPackageName).replaceAll("%APPLICATION%", applicationClassName).replaceAll("%APPLICATION_LIFE_CYCLE%", lifeCyclePackageName + "." + lifeCycleClassName).replaceAll("%TINKER_FLAGS%", "" + ca.flags()).replaceAll("%TINKER_LOADER_CLASS%", "" + loaderClassName).replaceAll("%TINKER_LOAD_VERIFY_FLAG%", "" + ca.loadVerifyFlag());JavaFileObject fileObject = processingEnv.getFiler().createSourceFile(applicationPackageName + "." + applicationClassName);processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Creating " + fileObject.toUri());Writer writer = fileObject.openWriter();PrintWriter pw = new PrintWriter(writer);pw.print(fileContent);pw.flush();writer.close();}}

代码比较简单,可以分三部分理解:

  • 步骤1:首先找到被DefaultLifeCycle标识的Element(为类对象TypeElement),得到该对象的包名,类名等信息,然后通过该对象,拿到@DefaultLifeCycle对象,获取该注解中声明属性的值。
  • 步骤2:读取一个模板文件,读取为字符串,将各个占位符通过步骤1中的值替代。
  • 步骤3:通过JavaFileObject将替换完成的字符串写文件,其实就是本例中的Application对象。

我们看一眼模板文件:

package %PACKAGE%;import com.tencent.tinker.loader.app.TinkerApplication;/**** Generated application for tinker life cycle**/
public class %APPLICATION% extends TinkerApplication {public %APPLICATION%() {super(%TINKER_FLAGS%, "%APPLICATION_LIFE_CYCLE%", "%TINKER_LOADER_CLASS%", %TINKER_LOAD_VERIFY_FLAG%);}}

对应我们的SimpleTinkerInApplicationLike

@DefaultLifeCycle(application = ".SimpleTinkerInApplication",flags = ShareConstants.TINKER_ENABLE_ALL,loadVerifyFlag = false)
public class SimpleTinkerInApplicationLike extends ApplicationLike {}

主要就几个占位符:

  • 包名,如果application属性值以点开始,则同包;否则则截取
  • 类名,application属性值中的类名
  • %TINKER_FLAGS%对应flags
  • %APPLICATION_LIFE_CYCLE%,编写的ApplicationLike的全路径
  • “%TINKER_LOADER_CLASS%”,这个值我们没有设置,实际上对应@DefaultLifeCycle的loaderClass属性,默认值为com.tencent.tinker.loader.TinkerLoader
  • %TINKER_LOAD_VERIFY_FLAG%对应loadVerifyFlag

于是最终生成的代码为:

/**** Generated application for tinker life cycle**/
public class SimpleTinkerInApplication extends TinkerApplication {public SimpleTinkerInApplication() {super(7, "com.zhy.tinkersimplein.SimpleTinkerInApplicationLike", "com.tencent.tinker.loader.TinkerLoader", false);}}

tinker这么做的目的,文档上是这么说的:

为了减少错误的出现,推荐使用Annotation生成Application类。

这样大致了解了Application是如何生成的。

接下来我们大致看一下tinker的原理。

四、原理

来源于:https://github.com/Tencent/tinker

tinker贴了一张大致的原理图。

可以看出:

tinker将old.apk和new.apk做了diff,拿到patch.dex,然后将patch.dex与本机中apk的classes.dex做了合并,生成新的classes.dex,运行时通过反射将合并后的dex文件放置在加载的dexElements数组的前面。

运行时替代的原理,其实和Qzone的方案差不多,都是去反射修改dexElements。

两者的差异是:Qzone是直接将patch.dex插到数组的前面;而tinker是将patch.dex与app中的classes.dex合并后的全量dex插在数组的前面。

tinker这么做的目的还是因为Qzone方案中提到的CLASS_ISPREVERIFIED的解决方案存在问题;而tinker相当于换个思路解决了该问题。

接下来我们就从代码中去验证该原理。

本片文章源码分析的两条线:

  • 应用启动时,从默认目录加载合并后的classes.dex
  • patch下发后,合成classes.dex至目标目录

五、源码分析

(1)加载patch

加载的代码实际上在生成的Application中调用的,其父类为TinkerApplication,在其attachBaseContext中辗转会调用到loadTinker()方法,在该方法内部,反射调用了TinkerLoader的tryLoad方法。

@Override
public Intent tryLoad(TinkerApplication app, int tinkerFlag, boolean tinkerLoadVerifyFlag) {Intent resultIntent = new Intent();long begin = SystemClock.elapsedRealtime();tryLoadPatchFilesInternal(app, tinkerFlag, tinkerLoadVerifyFlag, resultIntent);long cost = SystemClock.elapsedRealtime() - begin;ShareIntentUtil.setIntentPatchCostTime(resultIntent, cost);return resultIntent;
}

tryLoadPatchFilesInternal中会调用到loadTinkerJars方法:

private void tryLoadPatchFilesInternal(TinkerApplication app, int tinkerFlag, boolean tinkerLoadVerifyFlag, Intent resultIntent) {// 省略大量安全性校验代码if (isEnabledForDex) {//tinker/patch.info/patch-641e634c/dexboolean dexCheck = TinkerDexLoader.checkComplete(patchVersionDirectory, securityCheck, resultIntent);if (!dexCheck) {//file not found, do not load patchLog.w(TAG, "tryLoadPatchFiles:dex check fail");return;}}//now we can load patch jarif (isEnabledForDex) {boolean loadTinkerJars = TinkerDexLoader.loadTinkerJars(app, tinkerLoadVerifyFlag, patchVersionDirectory, resultIntent, isSystemOTA);if (!loadTinkerJars) {Log.w(TAG, "tryLoadPatchFiles:onPatchLoadDexesFail");return;}}
}

TinkerDexLoader.checkComplete主要是用于检查下发的meta文件中记录的dex信息(meta文件,可以查看生成patch的产物,在assets/dex-meta.txt),检查meta文件中记录的dex文件信息对应的dex文件是否存在,并把值存在TinkerDexLoader的静态变量dexList中。

TinkerDexLoader.loadTinkerJars传入四个参数,分别为application,tinkerLoadVerifyFlag(注解上声明的值,传入为false),patchVersionDirectory当前version的patch文件夹,intent,当前patch是否仅适用于art。

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public static boolean loadTinkerJars(Application application, boolean tinkerLoadVerifyFlag, String directory, Intent intentResult, boolean isSystemOTA) {PathClassLoader classLoader = (PathClassLoader) TinkerDexLoader.class.getClassLoader();String dexPath = directory + "/" + DEX_PATH + "/";File optimizeDir = new File(directory + "/" + DEX_OPTIMIZE_PATH);ArrayList<File> legalFiles = new ArrayList<>();final boolean isArtPlatForm = ShareTinkerInternals.isVmArt();for (ShareDexDiffPatchInfo info : dexList) {//for dalvik, ignore art support dexif (isJustArtSupportDex(info)) {continue;}String path = dexPath + info.realName;File file = new File(path);legalFiles.add(file);}// just for artif (isSystemOTA) {parallelOTAResult = true;parallelOTAThrowable = null;Log.w(TAG, "systemOTA, try parallel oat dexes!!!!!");TinkerParallelDexOptimizer.optimizeAll(legalFiles, optimizeDir,new TinkerParallelDexOptimizer.ResultCallback() {});SystemClassLoaderAdder.installDexes(application, classLoader, optimizeDir, legalFiles);return true;}

找出仅支持art的dex,且当前patch是否仅适用于art时,并行去loadDex。

关键是最后的installDexes:

@SuppressLint("NewApi")
public static void installDexes(Application application, PathClassLoader loader, File dexOptDir, List<File> files)throws Throwable {if (!files.isEmpty()) {ClassLoader classLoader = loader;if (Build.VERSION.SDK_INT >= 24) {classLoader = AndroidNClassLoader.inject(loader, application);}//because in dalvik, if inner class is not the same classloader with it wrapper class.//it won't fail at dex2optif (Build.VERSION.SDK_INT >= 23) {V23.install(classLoader, files, dexOptDir);} else if (Build.VERSION.SDK_INT >= 19) {V19.install(classLoader, files, dexOptDir);} else if (Build.VERSION.SDK_INT >= 14) {V14.install(classLoader, files, dexOptDir);} else {V4.install(classLoader, files, dexOptDir);}//install donesPatchDexCount = files.size();Log.i(TAG, "after loaded classloader: " + classLoader + ", dex size:" + sPatchDexCount);if (!checkDexInstall(classLoader)) {//reset patch dexSystemClassLoaderAdder.uninstallPatchDex(classLoader);throw new TinkerRuntimeException(ShareConstants.CHECK_DEX_INSTALL_FAIL);}}
}

这里实际上就是根据不同的系统版本,去反射处理dexElements。

我们看一下V19的实现(主要我看了下本机只有个22的源码~):

private static final class V19 {private static void install(ClassLoader loader, List<File> additionalClassPathEntries,File optimizedDirectory)throws IllegalArgumentException, IllegalAccessException,NoSuchFieldException, InvocationTargetException, NoSuchMethodException, IOException {Field pathListField = ShareReflectUtil.findField(loader, "pathList");Object dexPathList = pathListField.get(loader);ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>();ShareReflectUtil.expandFieldArray(dexPathList, "dexElements", makeDexElements(dexPathList,new ArrayList<File>(additionalClassPathEntries), optimizedDirectory,suppressedExceptions));if (suppressedExceptions.size() > 0) {for (IOException e : suppressedExceptions) {Log.w(TAG, "Exception in makeDexElement", e);throw e;}}}
}        
  1. 找到PathClassLoader(BaseDexClassLoader)对象中的pathList对象
  2. 根据pathList对象找到其中的makeDexElements方法,传入patch相关的对应的实参,返回Element[]对象
  3. 拿到pathList对象中原本的dexElements方法
  4. 步骤2与步骤3中的Element[]数组进行合并,将patch相关的dex放在数组的前面
  5. 最后将合并后的数组,设置给pathList

这里其实和Qzone的提出的方案基本是一致的。如果你以前未了解过Qzone的方案,可以参考此文:

  • Android 热补丁动态修复框架小结

(2)合成patch

这里的入口为:

 TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(),Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed.apk");

上述代码会调用DefaultPatchListener中的onPatchReceived方法:

# DefaultPatchListener
@Override
public int onPatchReceived(String path) {int returnCode = patchCheck(path);if (returnCode == ShareConstants.ERROR_PATCH_OK) {TinkerPatchService.runPatchService(context, path);} else {Tinker.with(context).getLoadReporter().onLoadPatchListenerReceiveFail(new File(path), returnCode);}return returnCode;}

首先对tinker的相关配置(isEnable)以及patch的合法性进行检测,如果合法,则调用TinkerPatchService.runPatchService(context, path);

public static void runPatchService(Context context, String path) {try {Intent intent = new Intent(context, TinkerPatchService.class);intent.putExtra(PATCH_PATH_EXTRA, path);intent.putExtra(RESULT_CLASS_EXTRA, resultServiceClass.getName());context.startService(intent);} catch (Throwable throwable) {TinkerLog.e(TAG, "start patch service fail, exception:" + throwable);}
}

TinkerPatchService是IntentService的子类,这里通过intent设置了两个参数,一个是patch的路径,一个是resultServiceClass,该值是调用Tinker.install的时候设置的,默认为DefaultTinkerResultService.class。由于是IntentService,直接看onHandleIntent即可,如果你对IntentService陌生,可以查看此文:Android IntentService完全解析 当Service遇到Handler 

@Override
protected void onHandleIntent(Intent intent) {final Context context = getApplicationContext();Tinker tinker = Tinker.with(context);String path = getPatchPathExtra(intent);File patchFile = new File(path);boolean result;increasingPriority();PatchResult patchResult = new PatchResult();result = upgradePatchProcessor.tryPatch(context, path, patchResult);patchResult.isSuccess = result;patchResult.rawPatchFilePath = path;patchResult.costTime = cost;patchResult.e = e;AbstractResultService.runResultService(context, patchResult, getPatchResultExtra(intent));}

比较清晰,主要关注upgradePatchProcessor.tryPatch方法,调用的是UpgradePatch.tryPatch。ps:这里有个有意思的地方increasingPriority(),其内部实现为:

private void increasingPriority() {TinkerLog.i(TAG, "try to increase patch process priority");try {Notification notification = new Notification();if (Build.VERSION.SDK_INT < 18) {startForeground(notificationId, notification);} else {startForeground(notificationId, notification);// start InnerServicestartService(new Intent(this, InnerService.class));}} catch (Throwable e) {TinkerLog.i(TAG, "try to increase patch process priority error:" + e);}
}

如果你对“保活”这个话题比较关注,那么对这段代码一定不陌生,主要是利用系统的一个漏洞来启动一个前台Service。如果有兴趣,可以参考此文:关于 Android 进程保活,你所需要知道的一切。

下面继续回到tryPatch方法:

# UpgradePatch
@Override
public boolean tryPatch(Context context, String tempPatchPath, PatchResult patchResult) {Tinker manager = Tinker.with(context);final File patchFile = new File(tempPatchPath);//it is a new patch, so we should not find a existSharePatchInfo oldInfo = manager.getTinkerLoadResultIfPresent().patchInfo;String patchMd5 = SharePatchFileUtil.getMD5(patchFile);//use md5 as versionpatchResult.patchVersion = patchMd5;SharePatchInfo newInfo;//already have patchif (oldInfo != null) {newInfo = new SharePatchInfo(oldInfo.oldVersion, patchMd5, Build.FINGERPRINT);} else {newInfo = new SharePatchInfo("", patchMd5, Build.FINGERPRINT);}//check ok, we can real recover a new patchfinal String patchDirectory = manager.getPatchDirectory().getAbsolutePath();final String patchName = SharePatchFileUtil.getPatchVersionDirectory(patchMd5);final String patchVersionDirectory = patchDirectory + "/" + patchName;//copy fileFile destPatchFile = new File(patchVersionDirectory + "/" + SharePatchFileUtil.getPatchVersionFile(patchMd5));// check md5 firstif (!patchMd5.equals(SharePatchFileUtil.getMD5(destPatchFile))) {SharePatchFileUtil.copyFileUsingStream(patchFile, destPatchFile);}//we use destPatchFile instead of patchFile, because patchFile may be deleted during the patch processif (!DexDiffPatchInternal.tryRecoverDexFiles(manager, signatureCheck, context, patchVersionDirectory, destPatchFile)) {TinkerLog.e(TAG, "UpgradePatch tryPatch:new patch recover, try patch dex failed");return false;}return true;
}

拷贝patch文件拷贝至私有目录,然后调用DexDiffPatchInternal.tryRecoverDexFiles

protected static boolean tryRecoverDexFiles(Tinker manager, ShareSecurityCheck checker, Context context,String patchVersionDirectory, File patchFile) {String dexMeta = checker.getMetaContentMap().get(DEX_META_FILE);boolean result = patchDexExtractViaDexDiff(context, patchVersionDirectory, dexMeta, patchFile);return result;
}

直接看patchDexExtractViaDexDiff

private static boolean patchDexExtractViaDexDiff(Context context, String patchVersionDirectory, String meta, final File patchFile) {String dir = patchVersionDirectory + "/" + DEX_PATH + "/";if (!extractDexDiffInternals(context, dir, meta, patchFile, TYPE_DEX)) {TinkerLog.w(TAG, "patch recover, extractDiffInternals fail");return false;}final Tinker manager = Tinker.with(context);File dexFiles = new File(dir);File[] files = dexFiles.listFiles();...files遍历执行:DexFile.loadDexreturn true;
}

核心代码主要在extractDexDiffInternals中:

private static boolean extractDexDiffInternals(Context context, String dir, String meta, File patchFile, int type) {//parse metaArrayList<ShareDexDiffPatchInfo> patchList = new ArrayList<>();ShareDexDiffPatchInfo.parseDexDiffPatchInfo(meta, patchList);File directory = new File(dir);//I think it is better to extract the raw files from apkTinker manager = Tinker.with(context);ZipFile apk = null;ZipFile patch = null;ApplicationInfo applicationInfo = context.getApplicationInfo();String apkPath = applicationInfo.sourceDir; //base.apkapk = new ZipFile(apkPath);patch = new ZipFile(patchFile);for (ShareDexDiffPatchInfo info : patchList) {final String infoPath = info.path;String patchRealPath;if (infoPath.equals("")) {patchRealPath = info.rawName;} else {patchRealPath = info.path + "/" + info.rawName;}File extractedFile = new File(dir + info.realName);ZipEntry patchFileEntry = patch.getEntry(patchRealPath);ZipEntry rawApkFileEntry = apk.getEntry(patchRealPath);patchDexFile(apk, patch, rawApkFileEntry, patchFileEntry, info, extractedFile);}return true;
}

这里的代码比较关键了,可以看出首先解析了meta里面的信息,meta中包含了patch中每个dex的相关数据。然后通过Application拿到sourceDir,其实就是本机apk的路径以及patch文件;根据mate中的信息开始遍历,其实就是取出对应的dex文件,最后通过patchDexFile对两个dex文件做合并。

private static void patchDexFile(ZipFile baseApk, ZipFile patchPkg, ZipEntry oldDexEntry, ZipEntry patchFileEntry,ShareDexDiffPatchInfo patchInfo,  File patchedDexFile) throws IOException {InputStream oldDexStream = null;InputStream patchFileStream = null;oldDexStream = new BufferedInputStream(baseApk.getInputStream(oldDexEntry));patchFileStream = (patchFileEntry != null ? new BufferedInputStream(patchPkg.getInputStream(patchFileEntry)) : null);new DexPatchApplier(oldDexStream, patchFileStream).executeAndSaveTo(patchedDexFile);}

通过ZipFile拿到其内部文件的InputStream,其实就是读取本地apk对应的dex文件,以及patch中对应dex文件,对二者的通过executeAndSaveTo方法进行合并至patchedDexFile,即patch的目标私有目录。

(完)

https://www.huxiu.com/member/1485082/l.html
https://www.huxiu.com/member/1485082/m.html
https://www.huxiu.com/member/1485082/b.html
https://www.huxiu.com/member/1485082/a.html
https://www.huxiu.com/member/1485082/w.html
https://www.huxiu.com/member/1485091/n.html
https://www.huxiu.com/member/1485091/c.html
https://www.huxiu.com/member/1485091/d.html
https://www.huxiu.com/member/1485091/u.html
https://www.huxiu.com/member/1485091/o.html
https://www.huxiu.com/member/1485091/l.html
https://www.huxiu.com/member/1485091/m.html
https://www.huxiu.com/member/1485091/b.html
https://www.huxiu.com/member/1485091/a.html
https://www.huxiu.com/member/1485091/w.html
https://www.huxiu.com/member/1485096/n.html
https://www.huxiu.com/member/1485096/c.html
https://www.huxiu.com/member/1485096/d.html
https://www.huxiu.com/member/1485096/u.html
https://www.huxiu.com/member/1485096/o.html
https://www.huxiu.com/member/1485096/l.html
https://www.huxiu.com/member/1485096/m.html
https://www.huxiu.com/member/1485096/b.html
https://www.huxiu.com/member/1485096/a.html
https://www.huxiu.com/member/1485096/w.html
https://www.huxiu.com/member/1485099/n.html
https://www.huxiu.com/member/1485099/c.html
https://www.huxiu.com/member/1485099/d.html
https://www.huxiu.com/member/1485099/u.html
https://www.huxiu.com/member/1485099/o.html
https://www.huxiu.com/member/1485099/l.html
https://www.huxiu.com/member/1485099/m.html
https://www.huxiu.com/member/1485099/b.html
https://www.huxiu.com/member/1485099/a.html
https://www.huxiu.com/member/1485099/w.html
https://www.huxiu.com/member/1485103/n.html
https://www.huxiu.com/member/1485103/c.html
https://www.huxiu.com/member/1485103/d.html
https://www.huxiu.com/member/1485103/u.html
https://www.huxiu.com/member/1485103/o.html
https://www.huxiu.com/member/1485103/l.html
https://www.huxiu.com/member/1485103/m.html
https://www.huxiu.com/member/1485103/b.html
https://www.huxiu.com/member/1485103/a.html
https://www.huxiu.com/member/1485103/w.html
https://www.huxiu.com/member/1485112/n.html
https://www.huxiu.com/member/1485112/c.html
https://www.huxiu.com/member/1485112/d.html
https://www.huxiu.com/member/1485112/u.html
https://www.huxiu.com/member/1485112/o.html
https://www.huxiu.com/member/1485112/l.html
https://www.huxiu.com/member/1485112/m.html
https://www.huxiu.com/member/1485112/b.html
https://www.huxiu.com/member/1485112/a.html
https://www.huxiu.com/member/1485112/w.html
https://www.huxiu.com/member/1485117/n.html
https://www.huxiu.com/member/1485117/c.html
https://www.huxiu.com/member/1485117/d.html
https://www.huxiu.com/member/1485117/u.html
https://www.huxiu.com/member/1485117/o.html
https://www.huxiu.com/member/1485117/l.html
https://www.huxiu.com/member/1485117/m.html
https://www.huxiu.com/member/1485117/b.html
https://www.huxiu.com/member/1485117/a.html
https://www.huxiu.com/member/1485117/w.html
https://www.huxiu.com/member/1485122/n.html
https://www.huxiu.com/member/1485122/c.html
https://www.huxiu.com/member/1485122/d.html
https://www.huxiu.com/member/1485122/u.html
https://www.huxiu.com/member/1485122/o.html
https://www.huxiu.com/member/1485122/l.html
https://www.huxiu.com/member/1485122/m.html
https://www.huxiu.com/member/1485122/b.html
https://www.huxiu.com/member/1485122/a.html
https://www.huxiu.com/member/1485122/w.html

https://www.huxiu.com/member/1485139/n.html
https://www.huxiu.com/member/1485139/c.html
https://www.huxiu.com/member/1485139/d.html
https://www.huxiu.com/member/1485139/u.html
https://www.huxiu.com/member/1485139/o.html
https://www.huxiu.com/member/1485139/l.html
https://www.huxiu.com/member/1485139/m.html
https://www.huxiu.com/member/1485139/b.html
https://www.huxiu.com/member/1485139/a.html
https://www.huxiu.com/member/1485139/w.html
https://www.huxiu.com/member/1485148/n.html
https://www.huxiu.com/member/1485148/c.html
https://www.huxiu.com/member/1485148/d.html
https://www.huxiu.com/member/1485148/u.html
https://www.huxiu.com/member/1485148/o.html
https://www.huxiu.com/member/1485148/l.html
https://www.huxiu.com/member/1485148/m.html
https://www.huxiu.com/member/1485148/b.html
https://www.huxiu.com/member/1485148/a.html
https://www.huxiu.com/member/1485148/w.html
https://www.huxiu.com/member/1485156/n.html
https://www.huxiu.com/member/1485156/c.html
https://www.huxiu.com/member/1485156/d.html
https://www.huxiu.com/member/1485156/u.html
https://www.huxiu.com/member/1485156/o.html
https://www.huxiu.com/member/1485156/l.html
https://www.huxiu.com/member/1485156/m.html
https://www.huxiu.com/member/1485156/b.html
https://www.huxiu.com/member/1485156/a.html
https://www.huxiu.com/member/1485156/w.html
https://www.huxiu.com/member/1485171/n.html
https://www.huxiu.com/member/1485171/c.html
https://www.huxiu.com/member/1485171/d.html
https://www.huxiu.com/member/1485171/u.html
https://www.huxiu.com/member/1485171/o.html
https://www.huxiu.com/member/1485171/l.html
https://www.huxiu.com/member/1485171/m.html
https://www.huxiu.com/member/1485171/b.html
https://www.huxiu.com/member/1485171/a.html
https://www.huxiu.com/member/1485171/w.html
https://www.huxiu.com/member/1485178/n.html
https://www.huxiu.com/member/1485178/c.html
https://www.huxiu.com/member/1485178/d.html
https://www.huxiu.com/member/1485178/u.html
https://www.huxiu.com/member/1485178/o.html
https://www.huxiu.com/member/1485178/l.html
https://www.huxiu.com/member/1485178/m.html
https://www.huxiu.com/member/1485178/b.html
https://www.huxiu.com/member/1485178/a.html
https://www.huxiu.com/member/1485178/w.html
https://www.huxiu.com/member/1485165/n.html
https://www.huxiu.com/member/1485165/c.html
https://www.huxiu.com/member/1485165/d.html
https://www.huxiu.com/member/1485165/u.html
https://www.huxiu.com/member/1485165/o.html
https://www.huxiu.com/member/1485165/l.html
https://www.huxiu.com/member/1485165/m.html
https://www.huxiu.com/member/1485165/b.html
https://www.huxiu.com/member/1485165/a.html
https://www.huxiu.com/member/1485165/w.html
https://www.huxiu.com/member/1485185/n.html
https://www.huxiu.com/member/1485185/c.html
https://www.huxiu.com/member/1485185/d.html
https://www.huxiu.com/member/1485185/u.html
https://www.huxiu.com/member/1485185/o.html
https://www.huxiu.com/member/1485185/l.html
https://www.huxiu.com/member/1485185/m.html
https://www.huxiu.com/member/1485185/b.html
https://www.huxiu.com/member/1485185/a.html
https://www.huxiu.com/member/1485185/w.html
https://www.huxiu.com/member/1485188/n.html
https://www.huxiu.com/member/1485188/c.html
https://www.huxiu.com/member/1485188/d.html
https://www.huxiu.com/member/1485188/u.html
https://www.huxiu.com/member/1485188/o.html
https://www.huxiu.com/member/1485188/l.html
https://www.huxiu.com/member/1485188/m.html
https://www.huxiu.com/member/1485188/b.html
https://www.huxiu.com/member/1485188/a.html
https://www.huxiu.com/member/1485188/w.html
https://www.huxiu.com/member/1485191/n.html
https://www.huxiu.com/member/1485191/c.html
https://www.huxiu.com/member/1485191/d.html
https://www.huxiu.com/member/1485191/u.html
https://www.huxiu.com/member/1485191/o.html
https://www.huxiu.com/member/1485191/l.html
https://www.huxiu.com/member/1485191/m.html
https://www.huxiu.com/member/1485191/b.html
https://www.huxiu.com/member/1485191/a.html
https://www.huxiu.com/member/1485191/w.html
https://www.huxiu.com/member/1485195/n.html
https://www.huxiu.com/member/1485195/c.html
https://www.huxiu.com/member/1485195/d.html
https://www.huxiu.com/member/1485195/u.html
https://www.huxiu.com/member/1485195/o.html
https://www.huxiu.com/member/1485195/l.html
https://www.huxiu.com/member/1485195/m.html
https://www.huxiu.com/member/1485195/b.html
https://www.huxiu.com/member/1485195/a.html
https://www.huxiu.com/member/1485195/w.html
https://www.huxiu.com/member/1485191/n.html
https://www.huxiu.com/member/1485191/c.html
https://www.huxiu.com/member/1485191/d.html
https://www.huxiu.com/member/1485191/u.html
https://www.huxiu.com/member/1485191/o.html
https://www.huxiu.com/member/1485191/l.html
https://www.huxiu.com/member/1485191/m.html
https://www.huxiu.com/member/1485191/b.html
https://www.huxiu.com/member/1485191/a.html
https://www.huxiu.com/member/1485191/w.html
https://www.huxiu.com/member/1485200/n.html
https://www.huxiu.com/member/1485200/c.html
https://www.huxiu.com/member/1485200/d.html
https://www.huxiu.com/member/1485200/u.html
https://www.huxiu.com/member/1485200/o.html
https://www.huxiu.com/member/1485200/l.html
https://www.huxiu.com/member/1485200/m.html
https://www.huxiu.com/member/1485200/b.html
https://www.huxiu.com/member/1485200/a.html
https://www.huxiu.com/member/1485200/w.html
https://www.huxiu.com/member/1485209/n.html
https://www.huxiu.com/member/1485209/c.html
https://www.huxiu.com/member/1485209/d.html
https://www.huxiu.com/member/1485209/u.html
https://www.huxiu.com/member/1485209/o.html
https://www.huxiu.com/member/1485209/l.html
https://www.huxiu.com/member/1485209/m.html
https://www.huxiu.com/member/1485209/b.html
https://www.huxiu.com/member/1485209/a.html
https://www.huxiu.com/member/1485209/w.html

https://www.huxiu.com/member/1485214/n.html
https://www.huxiu.com/member/1485214/c.html
https://www.huxiu.com/member/1485214/d.html
https://www.huxiu.com/member/1485214/u.html
https://www.huxiu.com/member/1485214/o.html
https://www.huxiu.com/member/1485214/l.html
https://www.huxiu.com/member/1485214/m.html
https://www.huxiu.com/member/1485214/b.html
https://www.huxiu.com/member/1485214/a.html
https://www.huxiu.com/member/1485214/w.html
https://www.huxiu.com/member/1485218/n.html
https://www.huxiu.com/member/1485218/c.html
https://www.huxiu.com/member/1485218/d.html
https://www.huxiu.com/member/1485218/u.html
https://www.huxiu.com/member/1485218/o.html
https://www.huxiu.com/member/1485218/l.html
https://www.huxiu.com/member/1485218/m.html
https://www.huxiu.com/member/1485218/b.html
https://www.huxiu.com/member/1485218/a.html
https://www.huxiu.com/member/1485218/w.html
https://www.huxiu.com/member/1485224/n.html
https://www.huxiu.com/member/1485224/c.html
https://www.huxiu.com/member/1485224/d.html
https://www.huxiu.com/member/1485224/u.html
https://www.huxiu.com/member/1485224/o.html
https://www.huxiu.com/member/1485224/l.html
https://www.huxiu.com/member/1485224/m.html
https://www.huxiu.com/member/1485224/b.html
https://www.huxiu.com/member/1485224/a.html
https://www.huxiu.com/member/1485224/w.html
https://www.huxiu.com/member/1485238/n.html
https://www.huxiu.com/member/1485238/c.html
https://www.huxiu.com/member/1485238/d.html
https://www.huxiu.com/member/1485238/u.html
https://www.huxiu.com/member/1485238/o.html
https://www.huxiu.com/member/1485238/l.html
https://www.huxiu.com/member/1485238/m.html
https://www.huxiu.com/member/1485238/b.html
https://www.huxiu.com/member/1485238/a.html
https://www.huxiu.com/member/1485238/w.html
https://www.huxiu.com/member/1485247/n.html
https://www.huxiu.com/member/1485247/c.html
https://www.huxiu.com/member/1485247/d.html
https://www.huxiu.com/member/1485247/u.html
https://www.huxiu.com/member/1485247/o.html
https://www.huxiu.com/member/1485247/l.html
https://www.huxiu.com/member/1485247/m.html
https://www.huxiu.com/member/1485247/b.html
https://www.huxiu.com/member/1485247/a.html
https://www.huxiu.com/member/1485247/w.html
https://www.huxiu.com/member/1485255/n.html
https://www.huxiu.com/member/1485255/c.html
https://www.huxiu.com/member/1485255/d.html
https://www.huxiu.com/member/1485255/u.html
https://www.huxiu.com/member/1485255/o.html
https://www.huxiu.com/member/1485255/l.html
https://www.huxiu.com/member/1485255/m.html
https://www.huxiu.com/member/1485255/b.html
https://www.huxiu.com/member/1485255/a.html
https://www.huxiu.com/member/1485255/w.html
https://www.huxiu.com/member/1485264/n.html
https://www.huxiu.com/member/1485264/c.html
https://www.huxiu.com/member/1485264/d.html
https://www.huxiu.com/member/1485264/u.html
https://www.huxiu.com/member/1485264/o.html
https://www.huxiu.com/member/1485264/l.html
https://www.huxiu.com/member/1485264/m.html
https://www.huxiu.com/member/1485264/b.html
https://www.huxiu.com/member/1485264/a.html
https://www.huxiu.com/member/1485264/w.html
https://www.huxiu.com/member/1485271/n.html
https://www.huxiu.com/member/1485271/c.html
https://www.huxiu.com/member/1485271/d.html
https://www.huxiu.com/member/1485271/u.html
https://www.huxiu.com/member/1485271/o.html
https://www.huxiu.com/member/1485271/l.html
https://www.huxiu.com/member/1485271/m.html
https://www.huxiu.com/member/1485271/b.html
https://www.huxiu.com/member/1485271/a.html
https://www.huxiu.com/member/1485271/w.html
https://www.huxiu.com/member/1485279/n.html
https://www.huxiu.com/member/1485279/c.html
https://www.huxiu.com/member/1485279/d.html
https://www.huxiu.com/member/1485279/u.html
https://www.huxiu.com/member/1485279/o.html
https://www.huxiu.com/member/1485279/l.html
https://www.huxiu.com/member/1485279/m.html
https://www.huxiu.com/member/1485279/b.html
https://www.huxiu.com/member/1485279/a.html
https://www.huxiu.com/member/1485279/w.html
https://www.huxiu.com/member/1485283/n.html
https://www.huxiu.com/member/1485283/c.html
https://www.huxiu.com/member/1485283/d.html
https://www.huxiu.com/member/1485283/u.html
https://www.huxiu.com/member/1485283/o.html
https://www.huxiu.com/member/1485283/l.html
https://www.huxiu.com/member/1485283/m.html
https://www.huxiu.com/member/1485283/b.html
https://www.huxiu.com/member/1485283/a.html
https://www.huxiu.com/member/1485283/w.html
https://www.huxiu.com/member/1485289/n.html
https://www.huxiu.com/member/1485289/c.html
https://www.huxiu.com/member/1485289/d.html
https://www.huxiu.com/member/1485289/u.html
https://www.huxiu.com/member/1485289/o.html
https://www.huxiu.com/member/1485289/l.html
https://www.huxiu.com/member/1485289/m.html
https://www.huxiu.com/member/1485289/b.html
https://www.huxiu.com/member/1485289/a.html
https://www.huxiu.com/member/1485289/w.html
https://www.huxiu.com/member/1485294/n.html
https://www.huxiu.com/member/1485294/c.html
https://www.huxiu.com/member/1485294/d.html
https://www.huxiu.com/member/1485294/u.html
https://www.huxiu.com/member/1485294/o.html
https://www.huxiu.com/member/1485294/l.html
https://www.huxiu.com/member/1485294/m.html
https://www.huxiu.com/member/1485294/b.html
https://www.huxiu.com/member/1485294/a.html
https://www.huxiu.com/member/1485294/w.html
https://www.huxiu.com/member/1485301/n.html
https://www.huxiu.com/member/1485301/c.html
https://www.huxiu.com/member/1485301/d.html
https://www.huxiu.com/member/1485301/u.html
https://www.huxiu.com/member/1485301/o.html
https://www.huxiu.com/member/1485301/l.html
https://www.huxiu.com/member/1485301/m.html
https://www.huxiu.com/member/1485301/b.html
https://www.huxiu.com/member/1485301/a.html
https://www.huxiu.com/member/1485301/w.html
https://www.huxiu.com/member/1485312/n.html
https://www.huxiu.com/member/1485312/c.html
https://www.huxiu.com/member/1485312/d.html
https://www.huxiu.com/member/1485312/u.html
https://www.huxiu.com/member/1485312/o.html
https://www.huxiu.com/member/1485312/l.html
https://www.huxiu.com/member/1485312/m.html
https://www.huxiu.com/member/1485312/b.html
https://www.huxiu.com/member/1485312/a.html
https://www.huxiu.com/member/1485312/w.html
https://www.huxiu.com/member/1485317/n.html
https://www.huxiu.com/member/1485317/c.html
https://www.huxiu.com/member/1485317/d.html
https://www.huxiu.com/member/1485317/u.html
https://www.huxiu.com/member/1485317/o.html
https://www.huxiu.com/member/1485317/l.html
https://www.huxiu.com/member/1485317/m.html
https://www.huxiu.com/member/1485317/b.html
https://www.huxiu.com/member/1485317/a.html
https://www.huxiu.com/member/1485317/w.html
https://www.huxiu.com/member/1485321/n.html
https://www.huxiu.com/member/1485321/c.html
https://www.huxiu.com/member/1485321/d.html
https://www.huxiu.com/member/1485321/u.html
https://www.huxiu.com/member/1485321/o.html
https://www.huxiu.com/member/1485321/l.html
https://www.huxiu.com/member/1485321/m.html
https://www.huxiu.com/member/1485321/b.html
https://www.huxiu.com/member/1485321/a.html
https://www.huxiu.com/member/1485321/w.html
https://www.huxiu.com/member/1485327/n.html
https://www.huxiu.com/member/1485327/c.html
https://www.huxiu.com/member/1485327/d.html
https://www.huxiu.com/member/1485327/u.html
https://www.huxiu.com/member/1485327/o.html
https://www.huxiu.com/member/1485327/l.html
https://www.huxiu.com/member/1485327/m.html
https://www.huxiu.com/member/1485327/b.html
https://www.huxiu.com/member/1485327/a.html
https://www.huxiu.com/member/1485327/w.html
https://www.huxiu.com/member/1485334/n.html
https://www.huxiu.com/member/1485334/c.html
https://www.huxiu.com/member/1485334/d.html
https://www.huxiu.com/member/1485334/u.html
https://www.huxiu.com/member/1485334/o.html
https://www.huxiu.com/member/1485334/l.html
https://www.huxiu.com/member/1485334/m.html
https://www.huxiu.com/member/1485334/b.html
https://www.huxiu.com/member/1485334/a.html
https://www.huxiu.com/member/1485334/w.html
https://www.huxiu.com/member/1485351/n.html
https://www.huxiu.com/member/1485351/c.html
https://www.huxiu.com/member/1485351/d.html
https://www.huxiu.com/member/1485351/u.html
https://www.huxiu.com/member/1485351/o.html
https://www.huxiu.com/member/1485351/l.html
https://www.huxiu.com/member/1485351/m.html
https://www.huxiu.com/member/1485351/b.html
https://www.huxiu.com/member/1485351/a.html
https://www.huxiu.com/member/1485351/w.html
https://www.huxiu.com/member/1485361/n.html
https://www.huxiu.com/member/1485361/c.html
https://www.huxiu.com/member/1485361/d.html
https://www.huxiu.com/member/1485361/u.html
https://www.huxiu.com/member/1485361/o.html
https://www.huxiu.com/member/1485361/l.html
https://www.huxiu.com/member/1485361/m.html
https://www.huxiu.com/member/1485361/b.html
https://www.huxiu.com/member/1485361/a.html
https://www.huxiu.com/member/1485361/w.html
https://www.huxiu.com/member/1485367/n.html
https://www.huxiu.com/member/1485367/c.html
https://www.huxiu.com/member/1485367/d.html
https://www.huxiu.com/member/1485367/u.html
https://www.huxiu.com/member/1485367/o.html
https://www.huxiu.com/member/1485367/l.html
https://www.huxiu.com/member/1485367/m.html
https://www.huxiu.com/member/1485367/b.html
https://www.huxiu.com/member/1485367/a.html
https://www.huxiu.com/member/1485367/w.html
https://www.huxiu.com/member/1485378/n.html
https://www.huxiu.com/member/1485378/c.html
https://www.huxiu.com/member/1485378/d.html
https://www.huxiu.com/member/1485378/u.html
https://www.huxiu.com/member/1485378/o.html
https://www.huxiu.com/member/1485378/l.html
https://www.huxiu.com/member/1485378/m.html
https://www.huxiu.com/member/1485378/b.html
https://www.huxiu.com/member/1485378/a.html
https://www.huxiu.com/member/1485378/w.html
https://www.huxiu.com/member/1485382/n.html
https://www.huxiu.com/member/1485382/c.html
https://www.huxiu.com/member/1485382/d.html
https://www.huxiu.com/member/1485382/u.html
https://www.huxiu.com/member/1485382/o.html
https://www.huxiu.com/member/1485382/l.html
https://www.huxiu.com/member/1485382/m.html
https://www.huxiu.com/member/1485382/b.html
https://www.huxiu.com/member/1485382/a.html
https://www.huxiu.com/member/1485382/w.html
https://www.huxiu.com/member/1485385/n.html
https://www.huxiu.com/member/1485385/c.html
https://www.huxiu.com/member/1485385/d.html
https://www.huxiu.com/member/1485385/u.html
https://www.huxiu.com/member/1485385/o.html
https://www.huxiu.com/member/1485385/l.html
https://www.huxiu.com/member/1485385/m.html
https://www.huxiu.com/member/1485385/b.html
https://www.huxiu.com/member/1485385/a.html
https://www.huxiu.com/member/1485385/w.html
https://www.huxiu.com/member/1485392/n.html
https://www.huxiu.com/member/1485392/c.html
https://www.huxiu.com/member/1485392/d.html
https://www.huxiu.com/member/1485392/u.html
https://www.huxiu.com/member/1485392/o.html
https://www.huxiu.com/member/1485392/l.html
https://www.huxiu.com/member/1485392/m.html
https://www.huxiu.com/member/1485392/b.html
https://www.huxiu.com/member/1485392/a.html
https://www.huxiu.com/member/1485392/w.html
https://www.huxiu.com/member/1485399/n.html
https://www.huxiu.com/member/1485399/c.html
https://www.huxiu.com/member/1485399/d.html
https://www.huxiu.com/member/1485399/u.html
https://www.huxiu.com/member/1485399/o.html
https://www.huxiu.com/member/1485399/l.html
https://www.huxiu.com/member/1485399/m.html
https://www.huxiu.com/member/1485399/b.html
https://www.huxiu.com/member/1485399/a.html
https://www.huxiu.com/member/1485399/w.html
https://www.huxiu.com/member/1485405/n.html
https://www.huxiu.com/member/1485405/c.html
https://www.huxiu.com/member/1485405/d.html
https://www.huxiu.com/member/1485405/u.html
https://www.huxiu.com/member/1485405/o.html
https://www.huxiu.com/member/1485405/l.html
https://www.huxiu.com/member/1485405/m.html
https://www.huxiu.com/member/1485405/b.html
https://www.huxiu.com/member/1485405/a.html
https://www.huxiu.com/member/1485405/w.html
https://www.huxiu.com/member/1485407/n.html
https://www.huxiu.com/member/1485407/c.html
https://www.huxiu.com/member/1485407/d.html
https://www.huxiu.com/member/1485407/u.html
https://www.huxiu.com/member/1485407/o.html
https://www.huxiu.com/member/1485407/l.html
https://www.huxiu.com/member/1485407/m.html
https://www.huxiu.com/member/1485407/b.html
https://www.huxiu.com/member/1485407/a.html
https://www.huxiu.com/member/1485407/w.html
https://www.huxiu.com/member/1485421/n.html
https://www.huxiu.com/member/1485421/c.html
https://www.huxiu.com/member/1485421/d.html
https://www.huxiu.com/member/1485421/u.html
https://www.huxiu.com/member/1485421/o.html
https://www.huxiu.com/member/1485421/l.html
https://www.huxiu.com/member/1485421/m.html
https://www.huxiu.com/member/1485421/b.html
https://www.huxiu.com/member/1485421/a.html
https://www.huxiu.com/member/1485421/w.html
https://www.huxiu.com/member/1485429/n.html
https://www.huxiu.com/member/1485429/c.html
https://www.huxiu.com/member/1485429/d.html
https://www.huxiu.com/member/1485429/u.html
https://www.huxiu.com/member/1485429/o.html
https://www.huxiu.com/member/1485429/l.html
https://www.huxiu.com/member/1485429/m.html
https://www.huxiu.com/member/1485429/b.html
https://www.huxiu.com/member/1485429/a.html
https://www.huxiu.com/member/1485429/w.html
https://www.huxiu.com/member/1485437/n.html
https://www.huxiu.com/member/1485437/c.html
https://www.huxiu.com/member/1485437/d.html
https://www.huxiu.com/member/1485437/u.html
https://www.huxiu.com/member/1485437/o.html
https://www.huxiu.com/member/1485437/l.html
https://www.huxiu.com/member/1485437/m.html
https://www.huxiu.com/member/1485437/b.html
https://www.huxiu.com/member/1485437/a.html
https://www.huxiu.com/member/1485437/w.html
https://www.huxiu.com/member/1485442/n.html
https://www.huxiu.com/member/1485442/c.html
https://www.huxiu.com/member/1485442/d.html
https://www.huxiu.com/member/1485442/u.html
https://www.huxiu.com/member/1485442/o.html
https://www.huxiu.com/member/1485442/l.html
https://www.huxiu.com/member/1485442/m.html
https://www.huxiu.com/member/1485442/b.html
https://www.huxiu.com/member/1485442/a.html
https://www.huxiu.com/member/1485442/w.html
https://www.huxiu.com/member/1485451/n.html
https://www.huxiu.com/member/1485451/c.html
https://www.huxiu.com/member/1485451/d.html
https://www.huxiu.com/member/1485451/u.html
https://www.huxiu.com/member/1485451/o.html
https://www.huxiu.com/member/1485451/l.html
https://www.huxiu.com/member/1485451/m.html
https://www.huxiu.com/member/1485451/b.html
https://www.huxiu.com/member/1485451/a.html
https://www.huxiu.com/member/1485451/w.html
https://www.huxiu.com/member/1485457/n.html
https://www.huxiu.com/member/1485457/c.html
https://www.huxiu.com/member/1485457/d.html
https://www.huxiu.com/member/1485457/u.html
https://www.huxiu.com/member/1485457/o.html
https://www.huxiu.com/member/1485457/l.html
https://www.huxiu.com/member/1485457/m.html
https://www.huxiu.com/member/1485457/b.html
https://www.huxiu.com/member/1485457/a.html
https://www.huxiu.com/member/1485457/w.html
https://www.huxiu.com/member/1485464/n.html
https://www.huxiu.com/member/1485464/c.html
https://www.huxiu.com/member/1485464/d.html
https://www.huxiu.com/member/1485464/u.html
https://www.huxiu.com/member/1485464/o.html
https://www.huxiu.com/member/1485464/l.html
https://www.huxiu.com/member/1485464/m.html
https://www.huxiu.com/member/1485464/b.html
https://www.huxiu.com/member/1485464/a.html
https://www.huxiu.com/member/1485464/w.html
https://www.huxiu.com/member/1485468/n.html
https://www.huxiu.com/member/1485468/c.html
https://www.huxiu.com/member/1485468/d.html
https://www.huxiu.com/member/1485468/u.html
https://www.huxiu.com/member/1485468/o.html
https://www.huxiu.com/member/1485468/l.html
https://www.huxiu.com/member/1485468/m.html
https://www.huxiu.com/member/1485468/b.html
https://www.huxiu.com/member/1485468/a.html
https://www.huxiu.com/member/1485468/w.html
https://www.huxiu.com/member/1485472/n.html
https://www.huxiu.com/member/1485472/c.html
https://www.huxiu.com/member/1485472/d.html
https://www.huxiu.com/member/1485472/u.html
https://www.huxiu.com/member/1485472/o.html
https://www.huxiu.com/member/1485472/l.html
https://www.huxiu.com/member/1485472/m.html
https://www.huxiu.com/member/1485472/b.html
https://www.huxiu.com/member/1485472/a.html
https://www.huxiu.com/member/1485472/w.html
https://www.huxiu.com/member/1485483/n.html
https://www.huxiu.com/member/1485483/c.html
https://www.huxiu.com/member/1485483/d.html
https://www.huxiu.com/member/1485483/u.html
https://www.huxiu.com/member/1485483/o.html
https://www.huxiu.com/member/1485483/l.html
https://www.huxiu.com/member/1485483/m.html
https://www.huxiu.com/member/1485483/b.html
https://www.huxiu.com/member/1485483/a.html
https://www.huxiu.com/member/1485483/w.html
https://www.huxiu.com/member/1485489/n.html
https://www.huxiu.com/member/1485489/c.html
https://www.huxiu.com/member/1485489/d.html
https://www.huxiu.com/member/1485489/u.html
https://www.huxiu.com/member/1485489/o.html
https://www.huxiu.com/member/1485489/l.html
https://www.huxiu.com/member/1485489/m.html
https://www.huxiu.com/member/1485489/b.html
https://www.huxiu.com/member/1485489/a.html
https://www.huxiu.com/member/1485489/w.html
https://www.huxiu.com/member/1472815/n.html
https://www.huxiu.com/member/1472815/c.html
https://www.huxiu.com/member/1472815/d.html
https://www.huxiu.com/member/1472815/u.html
https://www.huxiu.com/member/1472815/o.html
https://www.huxiu.com/member/1472815/l.html
https://www.huxiu.com/member/1472815/m.html
https://www.huxiu.com/member/1472815/b.html
https://www.huxiu.com/member/1472815/a.html
https://www.huxiu.com/member/1472815/w.html
https://www.huxiu.com/member/1485494/n.html
https://www.huxiu.com/member/1485494/c.html
https://www.huxiu.com/member/1485494/d.html
https://www.huxiu.com/member/1485494/u.html
https://www.huxiu.com/member/1485494/o.html
https://www.huxiu.com/member/1485494/l.html
https://www.huxiu.com/member/1485494/m.html
https://www.huxiu.com/member/1485494/b.html
https://www.huxiu.com/member/1485494/a.html
https://www.huxiu.com/member/1485494/w.html
https://www.huxiu.com/member/1472830/n.html
https://www.huxiu.com/member/1472830/c.html
https://www.huxiu.com/member/1472830/d.html
https://www.huxiu.com/member/1472830/u.html
https://www.huxiu.com/member/1472830/o.html
https://www.huxiu.com/member/1472830/l.html
https://www.huxiu.com/member/1472830/m.html
https://www.huxiu.com/member/1472830/b.html
https://www.huxiu.com/member/1472830/a.html
https://www.huxiu.com/member/1472830/w.html
https://www.huxiu.com/member/1480114/n.html
https://www.huxiu.com/member/1480114/c.html
https://www.huxiu.com/member/1480114/d.html
https://www.huxiu.com/member/1480114/u.html
https://www.huxiu.com/member/1480114/o.html
https://www.huxiu.com/member/1480114/l.html
https://www.huxiu.com/member/1480114/m.html
https://www.huxiu.com/member/1480114/b.html
https://www.huxiu.com/member/1480114/a.html
https://www.huxiu.com/member/1480114/w.html
https://www.huxiu.com/member/1480142/n.html
https://www.huxiu.com/member/1480142/c.html
https://www.huxiu.com/member/1480142/d.html
https://www.huxiu.com/member/1480142/u.html
https://www.huxiu.com/member/1480142/o.html
https://www.huxiu.com/member/1480142/l.html
https://www.huxiu.com/member/1480142/m.html
https://www.huxiu.com/member/1480142/b.html
https://www.huxiu.com/member/1480142/a.html
https://www.huxiu.com/member/1480142/w.html
https://www.huxiu.com/member/1480301/n.html
https://www.huxiu.com/member/1480301/c.html
https://www.huxiu.com/member/1480301/d.html
https://www.huxiu.com/member/1480301/u.html
https://www.huxiu.com/member/1480301/o.html
https://www.huxiu.com/member/1480301/l.html
https://www.huxiu.com/member/1480301/m.html
https://www.huxiu.com/member/1480301/b.html
https://www.huxiu.com/member/1480301/a.html
https://www.huxiu.com/member/1480301/w.html
https://www.huxiu.com/member/1480351/n.html
https://www.huxiu.com/member/1480351/c.html
https://www.huxiu.com/member/1480351/d.html
https://www.huxiu.com/member/1480351/u.html
https://www.huxiu.com/member/1480351/o.html
https://www.huxiu.com/member/1480351/l.html
https://www.huxiu.com/member/1480351/m.html
https://www.huxiu.com/member/1480351/b.html
https://www.huxiu.com/member/1480351/a.html
https://www.huxiu.com/member/1480351/w.html
https://www.huxiu.com/member/1480410/n.html
https://www.huxiu.com/member/1480410/c.html
https://www.huxiu.com/member/1480410/d.html
https://www.huxiu.com/member/1480410/u.html
https://www.huxiu.com/member/1480410/o.html
https://www.huxiu.com/member/1480410/l.html
https://www.huxiu.com/member/1480410/m.html
https://www.huxiu.com/member/1480410/b.html
https://www.huxiu.com/member/1480410/a.html
https://www.huxiu.com/member/1480410/w.html
https://www.huxiu.com/member/1480443/n.html
https://www.huxiu.com/member/1480443/c.html
https://www.huxiu.com/member/1480443/d.html
https://www.huxiu.com/member/1480443/u.html
https://www.huxiu.com/member/1480443/o.html
https://www.huxiu.com/member/1480443/l.html
https://www.huxiu.com/member/1480443/m.html
https://www.huxiu.com/member/1480443/b.html
https://www.huxiu.com/member/1480443/a.html
https://www.huxiu.com/member/1480443/w.html
https://www.huxiu.com/member/1480627/n.html
https://www.huxiu.com/member/1480627/c.html
https://www.huxiu.com/member/1480627/d.html
https://www.huxiu.com/member/1480627/u.html
https://www.huxiu.com/member/1480627/o.html
https://www.huxiu.com/member/1480627/l.html
https://www.huxiu.com/member/1480627/m.html
https://www.huxiu.com/member/1480627/b.html
https://www.huxiu.com/member/1480627/a.html
https://www.huxiu.com/member/1480627/w.html
https://www.huxiu.com/member/1480655/n.html
https://www.huxiu.com/member/1480655/c.html
https://www.huxiu.com/member/1480655/d.html
https://www.huxiu.com/member/1480655/u.html
https://www.huxiu.com/member/1480655/o.html
https://www.huxiu.com/member/1480655/l.html
https://www.huxiu.com/member/1480655/m.html
https://www.huxiu.com/member/1480655/b.html
https://www.huxiu.com/member/1480655/a.html
https://www.huxiu.com/member/1480655/w.html
https://www.huxiu.com/member/1480747/n.html
https://www.huxiu.com/member/1480747/c.html
https://www.huxiu.com/member/1480747/d.html
https://www.huxiu.com/member/1480747/u.html
https://www.huxiu.com/member/1480747/o.html
https://www.huxiu.com/member/1480747/l.html
https://www.huxiu.com/member/1480747/m.html
https://www.huxiu.com/member/1480747/b.html
https://www.huxiu.com/member/1480747/a.html
https://www.huxiu.com/member/1480747/w.html
https://www.huxiu.com/member/1480718/n.html
https://www.huxiu.com/member/1480718/c.html
https://www.huxiu.com/member/1480718/d.html
https://www.huxiu.com/member/1480718/u.html
https://www.huxiu.com/member/1480718/o.html
https://www.huxiu.com/member/1480718/l.html
https://www.huxiu.com/member/1480718/m.html
https://www.huxiu.com/member/1480718/b.html

https://www.huxiu.com/member/1480718/a.html
https://www.huxiu.com/member/1480718/w.html
https://www.huxiu.com/member/1480673/n.html
https://www.huxiu.com/member/1480673/c.html
https://www.huxiu.com/member/1480673/d.html
https://www.huxiu.com/member/1480673/u.html
https://www.huxiu.com/member/1480673/o.html
https://www.huxiu.com/member/1480673/l.html
https://www.huxiu.com/member/1480673/m.html
https://www.huxiu.com/member/1480673/b.html
https://www.huxiu.com/member/1480673/a.html
https://www.huxiu.com/member/1480673/w.html

https://www.huxiu.com/member/1480935/n.html
https://www.huxiu.com/member/1480935/c.html
https://www.huxiu.com/member/1480935/d.html
https://www.huxiu.com/member/1480935/u.html
https://www.huxiu.com/member/1480935/o.html
https://www.huxiu.com/member/1480935/l.html
https://www.huxiu.com/member/1480935/m.html
https://www.huxiu.com/member/1480935/b.html
https://www.huxiu.com/member/1480935/a.html
https://www.huxiu.com/member/1480935/w.html
https://www.huxiu.com/member/1480964/n.html

https://www.huxiu.com/member/1480964/c.html
https://www.huxiu.com/member/1480964/d.html
https://www.huxiu.com/member/1480964/u.html
https://www.huxiu.com/member/1480964/o.html
https://www.huxiu.com/member/1480964/l.html
https://www.huxiu.com/member/1480964/m.html
https://www.huxiu.com/member/1480964/b.html
https://www.huxiu.com/member/1480964/a.html
https://www.huxiu.com/member/1480964/w.html
https://www.huxiu.com/member/1480984/n.html
https://www.huxiu.com/member/1480984/c.html
https://www.huxiu.com/member/1480984/d.html
https://www.huxiu.com/member/1480984/u.html
https://www.huxiu.com/member/1480984/o.html
https://www.huxiu.com/member/1480984/l.html
https://www.huxiu.com/member/1480984/m.html
https://www.huxiu.com/member/1480984/b.html
https://www.huxiu.com/member/1480984/a.html
https://www.huxiu.com/member/1480984/w.html
https://www.huxiu.com/member/1481003/n.html
https://www.huxiu.com/member/1481003/c.html
https://www.huxiu.com/member/1481003/d.html
https://www.huxiu.com/member/1481003/u.html
https://www.huxiu.com/member/1481003/o.html
https://www.huxiu.com/member/1481003/l.html
https://www.huxiu.com/member/1481003/m.html
https://www.huxiu.com/member/1481003/b.html
https://www.huxiu.com/member/1481003/a.html
https://www.huxiu.com/member/1481003/w.html
https://www.huxiu.com/member/1481074/n.html
https://www.huxiu.com/member/1481074/c.html
https://www.huxiu.com/member/1481074/d.html
https://www.huxiu.com/member/1481074/u.html
https://www.huxiu.com/member/1481074/o.html
https://www.huxiu.com/member/1481074/l.html
https://www.huxiu.com/member/1481074/m.html
https://www.huxiu.com/member/1481074/b.html
https://www.huxiu.com/member/1481074/a.html
https://www.huxiu.com/member/1481074/w.html
https://www.huxiu.com/member/1481092/n.html
https://www.huxiu.com/member/1481092/c.html
https://www.huxiu.com/member/1481092/d.html
https://www.huxiu.com/member/1481092/u.html
https://www.huxiu.com/member/1481092/o.html
https://www.huxiu.com/member/1481092/l.html
https://www.huxiu.com/member/1481092/m.html
https://www.huxiu.com/member/1481092/b.html
https://www.huxiu.com/member/1481092/a.html
https://www.huxiu.com/member/1481092/w.html
https://www.huxiu.com/member/1481117/n.html
https://www.huxiu.com/member/1481117/c.html
https://www.huxiu.com/member/1481117/d.html
https://www.huxiu.com/member/1481117/u.html
https://www.huxiu.com/member/1481117/o.html
https://www.huxiu.com/member/1481117/l.html
https://www.huxiu.com/member/1481117/m.html
https://www.huxiu.com/member/1481117/b.html
https://www.huxiu.com/member/1481117/a.html
https://www.huxiu.com/member/1481117/w.html
https://www.huxiu.com/member/1481317/n.html
https://www.huxiu.com/member/1481317/c.html
https://www.huxiu.com/member/1481317/d.html
https://www.huxiu.com/member/1481317/u.html
https://www.huxiu.com/member/1481317/o.html
https://www.huxiu.com/member/1481317/l.html
https://www.huxiu.com/member/1481317/m.html
https://www.huxiu.com/member/1481317/b.html
https://www.huxiu.com/member/1481317/a.html
https://www.huxiu.com/member/1481317/w.html
https://www.huxiu.com/member/1481344/n.html
https://www.huxiu.com/member/1481344/c.html
https://www.huxiu.com/member/1481344/d.html
https://www.huxiu.com/member/1481344/u.html
https://www.huxiu.com/member/1481344/o.html
https://www.huxiu.com/member/1481344/l.html
https://www.huxiu.com/member/1481344/m.html
https://www.huxiu.com/member/1481344/b.html
https://www.huxiu.com/member/1481344/a.html
https://www.huxiu.com/member/1481344/w.html
https://www.huxiu.com/member/1481401/n.html
https://www.huxiu.com/member/1481401/c.html
https://www.huxiu.com/member/1481401/d.html
https://www.huxiu.com/member/1481401/u.html
https://www.huxiu.com/member/1481401/o.html
https://www.huxiu.com/member/1481401/l.html
https://www.huxiu.com/member/1481401/m.html
https://www.huxiu.com/member/1481401/b.html
https://www.huxiu.com/member/1481401/a.html
https://www.huxiu.com/member/1481401/w.html
https://www.huxiu.com/member/1481608/n.html
https://www.huxiu.com/member/1481608/c.html
https://www.huxiu.com/member/1481608/d.html
https://www.huxiu.com/member/1481608/u.html
https://www.huxiu.com/member/1481608/o.html
https://www.huxiu.com/member/1481608/l.html
https://www.huxiu.com/member/1481608/m.html
https://www.huxiu.com/member/1481608/b.html
https://www.huxiu.com/member/1481608/a.html
https://www.huxiu.com/member/1481608/w.html
https://www.huxiu.com/member/1481706/n.html
https://www.huxiu.com/member/1481706/c.html
https://www.huxiu.com/member/1481706/d.html
https://www.huxiu.com/member/1481706/u.html
https://www.huxiu.com/member/1481706/o.html
https://www.huxiu.com/member/1481706/l.html
https://www.huxiu.com/member/1481706/m.html
https://www.huxiu.com/member/1481706/b.html
https://www.huxiu.com/member/1481706/a.html
https://www.huxiu.com/member/1481706/w.html
https://www.huxiu.com/member/1481683/n.html
https://www.huxiu.com/member/1481683/c.html
https://www.huxiu.com/member/1481683/d.html
https://www.huxiu.com/member/1481683/u.html
https://www.huxiu.com/member/1481683/o.html
https://www.huxiu.com/member/1481683/l.html
https://www.huxiu.com/member/1481683/m.html
https://www.huxiu.com/member/1481683/b.html
https://www.huxiu.com/member/1481683/a.html
https://www.huxiu.com/member/1481683/w.html
https://www.huxiu.com/member/1481650/n.html
https://www.huxiu.com/member/1481650/c.html
https://www.huxiu.com/member/1481650/d.html
https://www.huxiu.com/member/1481650/u.html
https://www.huxiu.com/member/1481650/o.html

Android 热修复 Tinker接入及源码浅析最精彩没有之一相关推荐

  1. Android 热修复 Tinker接入及源码浅析

    本文已在我的公众号hongyangAndroid首发. 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/54882693 本文出自 ...

  2. Android 热修复Tinker接入实战

    1 热修复原理 热修复的原理一句话总结就是:就是dex的动态替换. 首先,我们知道PC上的JVM是直接解析class字节码的,而android上的JVM是解析dex文件的,因此Android程序要运行 ...

  3. Android热修复Tinker接入文档

    一.接入 ​ 按照官方文档https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix/?v=2017052610012 ...

  4. Android 热修复 Tinker Gradle Plugin解析

    本文已在我的公众号hongyangAndroid原创首发. 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/72667669 本文 ...

  5. 热修复框架AndFix【源码阅读】

    前言 AndFix是阿里巴巴开源的Android热修复框架.其基本原理是利用JNI来实现方法的替换,以实现Android APP的热修复,即无需发版即可临时修复在线BUG. 热修复技术有很多种,And ...

  6. Android 微信热修复 Tinker 接入过程及使用方法

    一.前言 学习热修复 Tinker 的使用,主要有两个原因: 业务需要:项目会出现一些细小的bug,需要等到发布新版才能修复,因此一直有关注热修复这块的技术. 技术驱动:这是一件需要一直保持的事情,不 ...

  7. Android热修复-Tinker简析

    一.简介 日常工作工作中难免会遇到项目上线后出现bug问题,如果紧急发版往往由于渠道审核时间问题,导致bug修复不及时,影响用户体验.这时我们需要引入热修复,免去发版审核烦恼. 热更新优势: 让应用能 ...

  8. Android热修复Tinker原理分析

    目录 1.tinker的class文件修复 2.tinker的资源文件修复 3.几种热修复方案对比 1.tinker的class文件修复 1.1.先说dex文件的加载和类的查找过程 1.1.1.dex ...

  9. springboot 搭建 简单 web项目 【springboot + freemark模板 + yml 配置文件 + 热修复 + 测试用例】附源码...

    项目 地址:  https://gitee.com/sanmubird/springboot-simpleweb.git 项目介绍: 本项目主要有一下内容: 1: springboot yml 配置 ...

最新文章

  1. SILK 的 Delay Decision 和 Dither
  2. Print all attributes and values in a Javascript Object
  3. windows mysql 开启日志功能_Windows下开启mysql日志功能
  4. LeetCode上求两个排序数组中位数问题—— Median of Two Sorted Arrays
  5. 初识vue 2.0(5):使用props父子组件通信
  6. 最全多线程经典面试题和答案
  7. c语言死锁算法实验报告,死锁实验报告
  8. JSP的9个内置对象-response
  9. java 泛型 擦除_Java泛型和类型擦除
  10. Sightseeing Cows(POJ-3621)
  11. java多线程-生产者消费者模式
  12. 帧中继环境下ospf的使用(点到点模式)
  13. isp和3a的联系与区别是什么?
  14. sublime php测试,sublime phpcs代码检查配置
  15. 移动端网页、公众号兼容性问题记录
  16. java论坛 基于SSM框架的游戏论坛 java游戏贴吧 java游戏论坛 java论坛 ssm论坛 ssm贴吧 可以改为各种论坛,分类可在后台自己控制,图片可任意换
  17. 使用MYSITE.github.io的免费二级域名实现顶级域名的重定向网址跳转
  18. 洛谷P1336 课题选择
  19. 打印机显示域服务器,操作打印机提示“active directory域服务当前不可用”怎么办?...
  20. 短视频应该怎么做?零基础如何学习视频剪辑?

热门文章

  1. 计算机制图训练实训报告答案,制图实训报告范文
  2. 测试用例(功能用例)——资产维修、资产报废
  3. 哎,系统分析师下午没过
  4. 第二章 信息系统集成及服务管理
  5. 2020,是时候介绍一下自己!
  6. macbook 终端命令怎么使用_mac终端命令大全 苹果入门
  7. mac下smartsvn安装与破解
  8. 数据结构__头插法建立单链表、尾插法建立单链表
  9. 微积分在小学教学中如何应用
  10. 开源硬件maple驱动安装问题