请问手机中的解锁样式文件夹中的.msocache文件夹夹有什么作用,谢谢您

在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
标签:至少1个,最多5个
整个 watch 的过程通过事件的机制,完成几个抽象对象的逻辑串联,当触发 Watching.prototype.watch 的调用回调函数时,流程便进入到了另外一端,开始进行重新编译,相较于第一次编译,在 webpack 中在二次编译阶段利用了很多缓存机制,来加速代码编译。
文章描述会涉及到整个 webpack 的编译流程,有一些细节可以在这篇文章中
详细的流程描述图中查看。这里会针对 webpack 中涉及缓存的部分和情况进行梳理。
part1. 缓存配置初始化
compilation 初始化
在上一篇文章提到过:
Watching.prototype.watch 通过 compiler.watchFileSystem 的 watch 方法实现,可以大致看出在变化触发编译后,会执行传递的回调函数,最终会调用 Watching.prototype.invalidate 进行编译触发
当 Watching.prototype.invalidate 调用后,会再次调用 Watching.prototype._go 方法重新进行编译流程,而无论在 Watching.prototype._go 方法还是 Compiler.prototype.run 方法,编译核心逻辑在 Compiler.prototype.compile 完成。而编译中第一个缓存设置则就在
Compiler.prototype.compile
中初始化 compilation 中触发。
webpack/lib/Compiler.js
Compiler.prototype.compile = function(callback) {
var params = this.newCompilationParams();
this.applyPlugins("compile", params);
var compilation = this.newCompilation(params);
// ... 省略具体编译流程
关联前面的 watch 流程,可以发现,每次编译开始,也就是每次由 invalidate -&
这条逻辑链触发编译的过程中,都会生成一个 compilation 对象,而实际上
compilation 对象是每单独一次编译的「流程中心」、「数据中心」,从编译开始、文件输出到最后的日志输出,都关联在 compilation 上。
而在 Compiler.prototype.newCompilation 中,则完成了大部分的 webpack 中缓存机制使用的大部分数据
webpack/lib/Compiler.js
Compiler.prototype.createCompilation = function() {
return new Compilation(this);
Compiler.prototype.newCompilation = function(params) {
var compilation = this.createCompilation();
compilation.fileTimestamps = this.fileT
compilation.contextTimestamps = this.contextT
// 省略其他属性赋值、事件触发
this.applyPlugins("compilation", compilation, params);
在调用 new Compilation(this) 生成实例之后,开始进行属性赋值,在 Compiler.prototype.newCompilation 中,主要涉及缓存数据的初始化有两部分
文件(夹)变更记录初始化
webpack/lib/Compiler.js
Watching.prototype.watch = function(files, dirs, missing) {
this.watcher = this.compiler.watchFileSystem.watch(files, dirs, missing, this.startTime, this.watchOptions, function(err, filesModified, contextModified, missingModified, fileTimestamps, contextTimestamps) {
this.watcher =
if(err) return this.handler(err);
this.compiler.fileTimestamps = fileT
this.compiler.contextTimestamps = contextT
this.invalidate();
}.bind(this), function() {
this.compiler.applyPlugins("invalid");
}.bind(this));
这部分是紧接着完成编译之后,将 Watching.prototype.watch 回调函数中 this.compiler.fileTimestamps = fileT、this.compiler.contextTimestamps = contextT
文件(夹)监听底层的 fileTimestamps、contextTimestamps 数据赋值到新生成的 compilation 上。
这两个值,在编译时触发编译模块实例判断是否需要重新编译的 needRebuild 方法中起到作用。
CachePlugin 加载
第三个部分的入口是触发webpack
编译流程中的
compilation 事件,事件触发主要引起 CachePlugin 插件逻辑的加载。
在 watch 过程中,会发现一个规律是,编译时间在编译第一次之后,后面的编译会增加很多,原因是 watch 模式正在流程中,会默认开启
配置。在 webpack 中 cache 选项则是对应 CachePlugin 的加载:
webpack/lib/WebpackOptionsApply.js
if(options.cache === undefined ? options.watch : options.cache) {
var CachePlugin = require("./CachePlugin");
compiler.apply(new CachePlugin(typeof options.cache === "object" ? options.cache : null));
那么在 CachePlugin 中对于 watch 流程中,最重要的一段逻辑则是将 CachePlugin 的 cache 属性与当前编译 compilation 对象进行关联
webpack/lib/CachePlugin.js
compiler.plugin("compilation", function(compilation) {
compilation.cache = this.
}.bind(this));
这样操作之后,编译过程 compilation 中的缓存设置,由于是引用的关系则会使 CachePlugin 的 cache 属性也保持同步。
同时,在完成一次编译后触发变更开始下一次编译的时候,上一次编译完成后更新完成的 cache 结果通过 compilation 事件的触发,就能无缝的衔接到下一次的 compilation 对象上,通过 CachePlugin 完成缓存在每次编译流程中的同步。
在后续环节中,对于文件更新判断,往往基于 contextTimestamps、fileTimestamps ,而对于缓存的存储,则大多是放在由 cachePlugin 初始化在 compilation 对象中的 cache 属性上。
part2. 文件路径查找(resolve)
webpack 编译流程中,时刻都在处理着文件路径问题,其中无论是编译某一个文件,还是调用某一个 loader ,都需要从配置的各种情况(可能是相对路径、绝对路径以及简写等情况)的路径中找到实际文件对应的绝对路径。而这里牵涉到一些耗时的操作,例如会对不同的、,以及一些 resolve 的进行处理。
这里通过在 compiler.resolvers 中的三个 Resolver 实例加载 UnsafeCachePlugin 来针对路径查找进行结果缓存,在相同情况(request)下,通过缓存直接返回。
webpack/lib/WebpackOptionsApply.js
compiler.resolvers.normal.apply(
new UnsafeCachePlugin(options.resolve.unsafeCache),
// 省略其他插件加载
compiler.resolvers.context.apply(
new UnsafeCachePlugin(options.resolve.unsafeCache),
// 省略其他插件加载
compiler.resolvers.loader.apply(
new UnsafeCachePlugin(options.resolve.unsafeCache),
// 省略其他插件加载
分别针对处理编译文件路径查找的 normal 、处理文件夹路径查找的 context 以及 loader 文件路径查找的 loader 都加载了 UnsafeCachePlugin 插件。
enhanced-resolve/lib/UnsafeCachePlugin.js
UnsafeCachePlugin.prototype.apply = function(resolver) {
var oldResolve = resolver.
var regExps = this.regE
var cache = this.
resolver.resolve = function resolve(context, request, callback) {
var id = context + "-&" +
if(cache[id]) {
// From cache
return callback(null, cache[id]);
oldResolve.call(resolver, context, request, function(err, result) {
if(err) return callback(err);
var doCache = regExps.some(function(regExp) {
return regExp.test(result.path);
if(!doCache) return callback(null, result);
callback(null, cache[id] = result);
UnsafeCachePlugin 在这里会直接执行 UnsafeCachePlugin.prototype.apply 方法会重写原有 Resolver 实例的 resolve 方法,会加载一层路径结果 cache ,以及在完成原有方法后更新 cache
当调用 resolver.resolve 时,会首先判断是否在 UnsafeCachePlugin 实例的 cache 属性中已经存在结果,存在则直接返回,不存在则执行原有 resolve 方法
当原有 resolve 方法完成后,会根据加载 UnsafeCachePlugin 时传入的 regExps 来判断是否需要缓存,如果需要则通过 callback(null, cache[id] = result); 返回结果的同时,更新UnsafeCachePlugin 的 cache 缓存对象。
part3. 判断是否需要编译
在完成了编译文件路径查找之后,即将开始对文件进行编译,由输入输出来看可以粗略的当做字符串转换流程,而这个流程是 webpack 中最耗时的流程,webpack 在开始实际的 loader 处理编译之前,进行是否已有缓存的判断。
webpack/lib/Compilation.js
Compilation.prototype.addModule = function(module, cacheGroup) {
cacheGroup = cacheGroup || "m";
var identifier = module.identifier();
if(this.cache && this.cache[cacheGroup + identifier]) {
var cacheModule = this.cache[cacheGroup + identifier];
var rebuild =
if(!cacheModule.error && cacheModule.cacheable && this.fileTimestamps && this.contextTimestamps) {
rebuild = cacheModule.needRebuild(this.fileTimestamps, this.contextTimestamps);
if(!rebuild) {
cacheModule.disconnect();
this._modules[identifier] = cacheM
this.modules.push(cacheModule);
cacheModule.errors.forEach(function(err) {
this.errors.push(err);
cacheModule.warnings.forEach(function(err) {
this.warnings.push(err);
return cacheM
module.lastId = cacheModule.
//省略缓存不存在的处理
这里有一个上下文是,每一个完成路径查找之后的编译文件,会生成对应的一个逻辑编译模块 module,而编译过程中的每一个编译模块,都会关联到 compilation 上的 modules 数组中。
执行 addModule 的时机正式完成路径查找生成模块之后,完成 compilation 添加 module 的过程。
首先调用 module.identifier();
获得编译文件的绝对路径,赋值为 identifier,并且以 cacheGroup + identifier 为 存储的 key,在 cacheGroup 值以及自定义 loader 参数不变的情况下,cache 对象中的模块缓存就由文件的绝对路径保证唯一性。
然后判断是否已经生成过该路径的 module, this.cache && this.cache[cacheGroup + identifier]
判断是否需要重新编译
var rebuild =
if(!cacheModule.error && cacheModule.cacheable && this.fileTimestamps && this.contextTimestamps) {
rebuild = cacheModule.needRebuild(this.fileTimestamps, this.contextTimestamps);
在进入 cacaheModule.needRebuild 之前,有四个前置条件
cacheModule.error:模块编译过程出现错误,则会将错误对象复制到 module 的 error 属性上
:模块是否能缓存,在一些不能缓存的情况,例如在编译过程增加对其他未添加到 module 的 fileDependencies 的文件依赖,依赖文件变更,但是引用原文件没有变更。在 loader 的函数中调用 this.cacheable() 实际上就是申明设置编译可以缓存。后续还会详细提到。
this.fileTimestamps 、this.contextTimestamps:首次活或前一次编译存储的文件最后变更记录
在前置条件满足的情况下,进入 module 的 needRebuild 方法,根据前置条件参数进行逻辑判断
webpack/lib/NormalModule.js
NormalModule.prototype.needRebuild = function needRebuild(fileTimestamps, contextTimestamps) {
var timestamp = 0;
this.fileDependencies.forEach(function(file) {
var ts = fileTimestamps[file];
if(!ts) timestamp = I
if(ts & timestamp) timestamp =
this.contextDependencies.forEach(function(context) {
var ts = contextTimestamps[context];
if(!ts) timestamp = I
if(ts & timestamp) timestamp =
return timestamp &= this.buildT
这里以 NormalModule 为例,会针对 this.fileDependencies、this.contextDependencies 进行相同逻辑的判断。
fileDependencies 指的是编译 module 所关联的文件依赖,一般会包含模块初始化传入的原本编译文件,也可能包含通过在 loader 中调用 this.addDependency 增加的其他的文件依赖,例如在样式文件中的 import
语法引入的文件,在模块逻辑上,模块以入口样式文件为入口作为标识,以 import 进入的样式文件为 fileDependency。
contextDependencies 类似,是 module 关联的文件夹依赖,例如在
实现中就是对 contextDependencies 操作,完成对目标目录的监听。
var ts = contextTimestamps[context];
if(!ts) timestamp = I
if(ts & timestamp) timestamp =
通过这段通用逻辑获取两类依赖的最后变更时间的最大值,与上次构建时间(buildTimestamp)比较 return timestamp &= this.buildT 判断是否需要重新编译。那么如果最后变更时间大于模块本身上次的编译时间,则表明需要重新编译。
part4. 编译过程
如果判断缓存过期失效,则需要进行编译。在编译流程中,会看到很多 loader 会有 this.cacheable(); 调用,同样也会看到 this.addDependency 或 this.dependency 以及很少见的 this.addContextDependency ;同时也会在 module 和 compilation 里面看到两个常见的变量 fileDependencies、contextDependencies 。下面会进行一些深入。
cacheable 属性
承接上面提到在判断是否需要重新编译时的条件 cacheModule.cacheable,上面提到
每一个完成路径查找之后的编译文件,会生成对应的一个逻辑编译模块 module
换一种较为好理解的方式,在一般情况下,每一个 require(dep) 依赖,在 webpack 中都会生成与之对应的 module,其中以 module.request 为唯一标识,而 module.request 就是为 dep 在文件系统中的 路径 和 编译参数 的拼接字符串。
这里的 cacheModule.cacheable 就是模块的 cacheable 属性,表明 module 当前对应的文件以及编译参数(request)上下文的情况下可以进行缓存。
this.cacheable() 、loaderContext、loaderContextCacheable
拿常见的 less-loader 举例子
less-loader/index.js
module.exports = function(source) {
var loaderContext =
var query = loaderUtils.parseQuery(this.query);
var cb = this.async();
// 省略其他配置操作
this.cacheable && this.cacheable();
首先确定 this 指向,less-loader 代码中,其实有一句进行了说明 var loaderContext =,在 loader 文件逻辑中,this 绑定的是上层 module 创建的 loaderContext 对象
webpack-core/lib/NormalModuleMixin.js
var loaderContextC
var loaderContext = {
cacheable: function(flag) {
loaderContextCacheable = flag !==
dependency: function(file) {
this.fileDependencies.push(file);
}.bind(this),
addDependency: function(file) {
this.fileDependencies.push(file);
}.bind(this),
addContextDependency: function(context) {
this.contextDependencies.push(context);
}.bind(this),
// 省略其他属性
这里列了 loaderContext 其中的一些与目前讨论话题相关的属性,可以看到 cacheable 实际上是通过闭包来修改 loaderContextCacheable 这个变量的值,而 loaderContextCacheable 是最终影响 module.cacheable 的决定因素。
loader 执行与 module.cacheable
webpack 提供给 loader 模块两个接口,一个是默认 module.exports 的导出方法,一个是 module.exports.pitch 的,对应两套不同的逻辑。按照在 webpack 中执行顺序
module.exports.pitch 导出方法逻辑
webpack-core/lib/NormalModuleMixin.js
// Load and pitch loaders
(function loadPitch() {
// 省略其他判断、处理逻辑
loaderContextCacheable =
runSyncOrAsync(l.module.pitch, privateLoaderContext, [remaining.join("!"), pitchedLoaders.join("!"), l.data = {}], function(err) {
if(!loaderContextCacheable) this.cacheable =
if(args.length & 0) {
nextLoader.apply(this, [null].concat(args));
loadPitch.call(this);
}.bind(this));
}.call(this));
runSyncOrAsync 是执行 loader 具体实现的函数,在开始 pitch 流程之前,会首先设置 loaderContextCacheable 为 false,然后通过 runSyncOrAsync 进入 loader 的具体 pitch 实现,这样只有在 loader 方法中手动调用 this.cacheable() 才会将保证loaderContextCacheable
的值设置成 true 从而不会进入 if(!loaderContextCacheable) this.cacheable =,标明 module 的 cacheable 为 false。
module.exports 导出方法逻辑
webpack-core/lib/NormalModuleMixin.js
function nextLoader(err/*, paramBuffer1, param2, ...*/) {
if(!loaderContextCacheable) module.cacheable =
// 省略 privateLoaderContext 环境创建
loaderContextCacheable =
runSyncOrAsync(l.module, privateLoaderContext, args, function() {
loaderContext.inputValue = privateLoaderContext.
nextLoader.apply(null, arguments);
在完成 pitch 流程之后,会进入默认逻辑的流程,也类似 pitch 的流程,在调用 runSyncOrAsync 进入 loader 逻辑前,先设置 loaderContextCacheable 为 false,在递归循环中判断 loader 是否在执行中调用 this.cacheable() 将 loaderContextCacheable
设置成 true,从而保证module.cacheable 的值为 true。
综合上面的环节,就是如果要保证 module 可被缓存,则一定需要 loader 中调用 this.cacheable() 触发如图的逻辑链路。
addDependency、dependency、addContextDependency
在 loaderContext 还会提供两类方法
增加文件依赖,addDependency、dependency:目的是在编译过程中,增加对没有生成对应 module 的文件的依赖关系,例如 import common.less 这样的引用文件
增加文件夹依赖,addContextDependency :类比文件依赖,增加对文件夹的依赖
而从上面的实现中,可以看到,两类方法调用之后,会将文件(夹)路径放在 fileDependencies,contextDependencies 中
fileDependencies 、contextDependencies 与 compilation
在完成所有模块的编译之后,在 Compilation.js 中会调用 Compilation.prototype.summerizeDependencies ,其中会将 fileDependencies、contextDependencies 汇集到 compilation 实例上
webpack/lib/Compilation.js
Compilation.prototype.summarizeDependencies = function summarizeDependencies() {
this.modules.forEach(function(module) {
if(module.fileDependencies) {
module.fileDependencies.forEach(function(item) {
this.fileDependencies.push(item);
if(module.contextDependencies) {
module.contextDependencies.forEach(function(item) {
this.contextDependencies.push(item);
this.fileDependencies.sort();
this.fileDependencies = filterDups(this.fileDependencies);
this.contextDependencies.sort();
this.contextDependencies = filterDups(this.contextDependencies);
// 省略其他操作
从实现中可以看到,首先把所有编译 module 的 fileDependencies 与 contextDependencies 都汇集到 compilation 对象,并且进行排序、去重。
但是可能看到这里关于这两个 dependency 的内容有个疑问,跟缓存更新有啥关系呢?
衔接 watch 流程
webpack/lib/Compiler.js
Watching.prototype._done = function(err, compilation) {
// 省略其他流程
if(!this.error)
this.watch(compilation.fileDependencies, compilation.contextDependencies, compilation.missingDependencies);
衔接上篇文章,在 watch 模式下,在完成编译之后,传入 watch 方法正是上面
Compilation.prototype.summarizeDependencies 汇集到 compilation 中的 fileDependencies、contextDependencies 属性,表明上一次编译结果中得出的作为 编译流程中的文件(夹)依赖作为需要进行变更监听的依据。
整个流程下来,就能将编译中涉及的文件进行管控,在下一次编译触发监控中,保证对涉及文件的监控,快速响应文件改动变更。
part5. 编译完成
在完成了之前的编译逻辑之后,webpack 便开始要渲染(render) 代码,而这个拼接过程,是字符串不断分割拼接的过程,对应同样的输入获得同样的输出。webpack 在这里也同样设置了一个缓存机制
webpack/lib/Compilation.js
Compilation.prototype.createChunkAssets = function createChunkAssets() {
// 省略其他逻辑
for(i = 0; i & this.chunks. i++) {
var useChunkHash = !chunk.entry || (this.mainTemplate.useChunkHash && this.mainTemplate.useChunkHash(chunk));
var usedHash = useChunkHash ? chunkHash : this.fullH
if(this.cache && this.cache["c" + chunk.id] && this.cache["c" + chunk.id].hash === usedHash) {
source = this.cache["c" + chunk.id].
if(chunk.entry) {
source = this.mainTemplate.render(this.hash, chunk, this.moduleTemplate, this.dependencyTemplates);
source = this.chunkTemplate.render(chunk, this.moduleTemplate, this.dependencyTemplates);
if(this.cache) {
this.cache["c" + chunk.id] = {
hash: usedHash,
source: source = (source instanceof CachedSource ? source : new CachedSource(source))
在 Compilation.prototype.createChunkAssets 中,会判断每个 chunk 是否有代码生成之后保留的缓存
这里的 chunk 简化来讲,可以看做对应的是配置在 webpack 中的 。
this.cache && this.cache["c" + chunk.id] && this.cache["c" + chunk.id].hash === usedHash 看出,以 chunk.id 为标识,如果整个 chunk 的 webpack 生成
hash 没有变化,说明在 chunk 中的各个 module 等参数都没有发生变化。则可以使用上一次的代码渲染缓存。
同时如果缓存失效,则会将生成之后的代码储存在 this.cache["c" + chunk.id] 对象中。
webpack 中的缓存机制保证了在多次编译的场景下,以增量变更编译的方式保证编译速度。文章内容大致截取了 webpack 编译流程的部分结点进行分析。
0 收藏&&|&&6
你可能感兴趣的文章
21 收藏,739
605 收藏,5.9k
分享到微博?
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。Nexus5X(bullhead) 解锁/解除全盘加密/备份/Root/刷机——[译] - 简书
Nexus5X(bullhead) 解锁/解除全盘加密/备份/Root/刷机——[译]
[指南]Unlock/Root/Flash for Nexus 5X
下载ADB,fastboot工具包,解压至“C:\ADB”,解压至/usr/bin/,你将看到“fastboot.exe”和“adb.exe”。为确保正确安装了adb,请在“ADB”文件夹上按住shift并点击鼠标右键,选择 在此处打开命令窗口,并执行命令adb version,如果它返回Android Debug Bridge的版本号,你就可以进行下一步了。
在手机上打开开发人员选项& USB调试后连接电脑并执行命令adb devices,如果返回你的设备序列号说明 adb 正常工作。
执行命令adb reboot bootloader来重启到 bootloader 模式,执行命令fastboot devices,如果返回你的设备序列号说明fastboot正常工作。
上文给出的ADB链接总是指向最新版,如果电脑已经有ADB,请删除并重新下载
执行fastboot reboot命令正常重启
开机USB调试状态时执行命令adb reboot bootloader或者关机后按电源键+下音量键都可以进入bootloader
开机USB调试状态时执行命令adb reboot recovery或者进入bootloader后调到recovery都可以进入recovery
命令执行后出现finished. total time: x.xxxs表示执行完毕
如何解锁你的 Bootloader
如何在您的设备上安装自定义Recovery
如何使用 TWRP Recovery 制造一个 Nandroid 备份
如何使用 TWRP Recovery 制造一个 EFS 备份
如何 root 你的 Stock Rom
如何使用 TWRP Recovery 安装 ROM
如何使用 TWRP Recovery 安装自定义内核
如何更新到Stock Rom的新版本
如何刷入工厂镜像(返回到Stock Rom)
如何刷入工厂镜像(返回到Stock Rom但不清除存储的数据)
1.如何解锁你的 Bootloader
在“设置&关于手机”中不断点击版本号直到出现toast通知你开启了“开发人员选项”,进入开发人员选项开启“usb调试”并单击启用"oem解锁”复选框
将手机通过usb数据线连接到电脑
执行命令adb reboot bootloader进入bootloader
在“C:\ADB”文件夹上调出命令提示符
执行命令fastboot devices检查fastboot是否正确连接(它应该返回设备的序列号,如果不是需要确保驱动程序已正确安装。)
执行命令fastboot oem unlock(这将从设备清除所有用户数据!),手机提示你确认此操作,如果你想进行下一步请用音量键滚动并用电源键确认
重要提示:除非你的手机系统是完整的不然请不要relock bootloader。你必须首先刷工厂镜像以去除root和自定义recovery(如果你有的话),如果不采取这种预防措施手机会变砖。请参阅本指南的第11条关于如何返回到stock android。
2.如何在您的设备上安装自定义Recovery
前提:解锁bootloader(第一节)
解压文件至电脑“C:\ADB”
在“C:\ADB”文件夹上按住shift并点击鼠标右键,选择 在此处打开命令窗口
执行命令fastboot flash recovery &filename&.img(filename取决于你想刷的自定义Recovery名称)
用音量键滚动到“Restart Bootloader”选项并用电源键选择。
当手机启动回Bootloader你可以选择并启动新刷的recovery(滑动确认时要仔细看清楚。如果TWRP Recovery提示你刷入SuperSU来root时最好不要选择,因为可能系统版本不对,请参考本文方法来获取root)
3.如何使用 TWRP Recovery 制造一个 Nandroid 备份
前提:解锁bootloader(第一节),TWRP Recovery(第二节)
启动TWRP Recovery
从TWRP主屏幕选择backup选项
只选中data/boot/system
滑动确认,此过程将需要几分钟。(会在手机上TWRP目录生成备份文件,请在手机内置存储安全的地方备份一个副本)
4.如何使用 TWRP Recovery 制造一个 EFS 备份
前提:解锁bootloader(第一节),TWRP Recovery(第二节)
启动TWRP Recovery
从TWRP主屏幕选择backup选项
滑动确认,此过程将需要几秒钟。(会在手机上TWRP目录生成备份文件,请在手机内置存储外安全的地方备份一个副本)
5.如何 root 你的 Stock Rom
前提:解锁bootloader(第一节),TWRP recovery(第二节)
在进行任何操作前应该先进行Nandroid备份
下载(2.60+) 到你的手机
开机进入TWRP recovery并选择install
找到SuperSU并选择
安装完成后点wipe cache/dalvik,点back键,点reboot system按钮
因为不是用TWRP提供的方式刷入的SuperSU,如果TWRP提示你没有root要帮你刷入SuperSU的话,不要滑动!选择跳过,你已经root了,兼容而且不会造成问题,以后每次检测到你都忽略它
6.如何使用 TWRP Recovery 安装 ROM
前提:解锁bootloader(第一节), TWRP recovery(第二节)
在进行任何操作前应该先进行Nandroid备份
下载并MD5验证ROM和Gapps包后放在你的设备里
进入TWRP recovery
执行full wipe
从TWRP主屏幕选择wipe选项
选择advanced wipe
只选中system, data, cache, and dalvik cache
从TWRP主屏幕选择install选项
找到ROM压缩包并选择
滑动确认(大多数ROM会在此时安装,但有一些ROM允许你在安装之前做一些设置)
在安装完ROM后直接安装Gapps包
安装完成后点wipe cache/dalvik,点back键,点reboot system按钮
7.如何使用 TWRP Recovery 安装自定义内核
前提:解锁bootloader(第一节), TWRP recovery(第二节)
刷入定制的内核可以更好的控制你的手机。例如超频和降频, 修改 I/O,色彩校准,声音校准和许多其它选项
下载并MD5验证与当前ROM兼容的内核后放在你的设备里
进入 TWRP recovery
从TWRP主屏幕上选择install选项。
找到内核并选择它
安装完成后点wipe cache/dalvik,点back键,点reboot system按钮
!!!第8,9,10节的准备工作!!!
在下载最新的工厂镜像
解压“bullhead-xxxx-factory-xxxx”(x是替换变量)到“C:\bullhead\”
解压完成会生成一个名为“bullhead-xxxx”(x是替换变量)的文件夹。打开并移动下列文件至文件夹“C:\bullhead\images\”
bootloader-bullhead-xxxx.img
radio-bullhead-xxxx.img
windows系统请重命名 bootloader-bullhead-xxxx.img 为 bootloader.img,重命名 radio-bullhead-xxxx.img 为 radio.img
在“C:\bullhead\bullhead-xxxxxx\”里你会看到一个zip名为“image-bullhead-xxxxxx”,解压至“ C:\bullhead\images\”内。现在“ C:\bullhead\images\”里应该有如下文件
android-info.txt
bootloader.img
recovery.img
system.img
userdata.img
vendor.img
在“ C:\bullhead\images\”文件夹里右键新建一个文本文档,打开然后粘贴下列内容进去
fastboot devices
fastboot flash bootloader C:\bullhead\images\bootloader.img
fastboot reboot-bootloader
ping -n 5 127.0.0.1 &nul
fastboot flash radio C:\bullhead\images\radio.img
fastboot reboot-bootloader
ping -n 5 127.0.0.1 &nul
fastboot flash boot C:\bullhead\images\boot.img
fastboot erase cache
fastboot flash cache C:\bullhead\images\cache.img
fastboot flash recovery C:\bullhead\images\recovery.img
fastboot flash system C:\bullhead\images\system.img
fastboot flash vendor C:\bullhead\images\vendor.img
保存,关闭文件后重命名此文件为flash.bat
8.如何更新到Stock Rom的新版本
前提:解锁bootloader(第一节), flash.bat
此方法不会擦除你的数据,你的应用程序和设置会得到保留,应该不会有问题,但是如果你遇到了,需要执行恢复出厂设置并再次刷入。
将手机通过usb数据线连接到电脑并进入bootloader
在“ C:\bullhead\images\”文件夹里打开 flash.bat
9.如何刷入工厂镜像(返回到Stock Rom)
前提:解锁bootloader(第一节), flash.bat
本节会说明如何恢复手机到第一次使用的时候,这将从手机中删除一切。如果你需要刷入工厂镜像但不清除你的个人数据请看下一节。
转到设置/备份执行恢复出厂设置。这将删除所有的用户数据(应用,设置,照片,音乐,备份等)
将手机通过usb数据线连接到电脑并进入bootloader
在“ C:\bullhead\images\”文件夹里打开 flash.bat
如果你想你可以用fastboot oem lock命令来重新锁定bootloader
请注意!这将删除你的用户数据!
重要提示:不要在刷入工厂镜像前relock bootloader,relock bootloader的过程会让装有自定义recovery的手机变砖。另外注意锁定的过程会擦除你的所有数据哪怕你是加密中的设备。
当命令执行完成后你可以执行fastboot reboot重启设备正常使用。
10.如何刷入工厂镜像(返回到Stock Rom但不清除内部存储上的数据)
前提:解锁bootloader(第一节), flash.bat
本节会说明如何恢复手机到第一次使用的时候,除了不会删除现在你手机上内部存储的个人资料。
进入TWRP recovery 并进入wipe菜单,选择advanced wipe,只选中data并滑动确认
转到TWRP recovery 主菜单并进入reboot菜单里,选择bootloader
将手机通过usb数据线连接到电脑
在“ C:\bullhead\images\”文件夹里打开 flash.bat
当命令执行完成后你可以执行fastboot reboot重启设备正常使用。
官方工厂镜像直链:
SHA-256:4ac1e0111cfa8efbdd01800dd2fadc6f8eeeae1b97a9
SHA-256:3fd99923cebdceaceb134dd93e62bdf7a184c82c5fb722
SHA-256:8eed1d9fc7f3d6365cdd41d10f0adab3888f97eeae6631f4afded
linux flash.sh
fastboot devices
read -p "Continue? (y/n)" -n 1 code
if [[ $code == n || $code == N ]]; then
fastboot flash bootloader ./bootloader*.img
fastboot reboot-bootloader
fastboot flash radio ./radio*.img
fastboot reboot-bootloader
fastboot flash boot ./boot.img
fastboot erase cache
fastboot flash cache ./cache.img
fastboot flash recovery ./recovery.img
fastboot flash system ./system.img
fastboot flash vendor ./vendor.img
这个帖子原本是发在5X区的,我只是将整个帖子复制到了6P区而已 2333 这个教程应该算是应有尽有了。看见群里有很多人各种各样的提问,其实也就是“一样米 养百样人”而已,只要你懂得变通,一切都不是问题。 下面,将会写上问题的解决方法也有Nexus如何刷机等等教程(部分资料是...
1. 前往Google开发者网站,下载对应手机型号的完整版工厂镜像解压2. 下载操作所需Android SDK Platform-tools工具,并进行解压备用3. 下载TWRP for shamu4. 下载Zip ROOT工具SuperSU Download Factor...
在前面的两篇文章中北嗅君提到了在 Android 大玩家,各位玩机达人心中的神器 Xposed 和 Supersu. Xposed 介绍可以看: XPOSED:不得不说的 ANDROID 神器Supersu 介绍可以看: Supersu:找不到对手的ROOT工具 当然,有个...
1. 前言 一加2(A2001)自带的氢系统已经很久没有更新了,正式版甚至还停留在Android 5.x版本。对氢不满意,就决定自己刷机,但由于先前没有经验,自己折腾了很久才解决刷机时遇到的问题,才成功刷入了第三方ROM。写个教程给同为小白的各位吧,教教大家怎么刷Andro...
刷机分几种? 我们所说刷机,就是在android手机中刷入第三方的ROM,我觉得这个过程应该分三种!(首先说明: 我是小白,在此只是记录下自己刷机的 “经验”) 什么是Recovery?有过刷机经验的童鞋应该都知道,android系统中有个叫恢复模式(recovery)的存...
梦见高超等人到我家随意用屋子,和妈妈对了‘口供’然后我上楼去查看。 然后梦见格拉上师到我家二楼,观察佛堂,说没有他的佛像。台子上好几座像,上师问的一座,好像是财宝天王。居然还有几个吉祥摆件,连佛像都不是。 我们从佛堂屋子出去,有陌生喇嘛带着弟子来到二楼,关着门和灯,格拉上师...
乐观、悲观一念间!(请点击左面蓝字) 看着上面文章,很是感同身受,比如每天拼凑豆腐块文字,悲观点是因为自己写字能力有限,写不出感人的文章!乐观点则是为了积累《对弈江山》正面宣传的素材,一点点的积累将来都会开花结果。 年轻时看这些战争题材想着“乱世出英雄”,一直感慨自己没有赶...
一日,菠萝小姐跟我抱怨说,整日沉浸在微信的碎片阅读里,类似的内容被不同的公众号转载重复点开消耗时间,抢眼球的标题,看完后的失望,残缺不全的信息成就了支离不堪的心境,她的内心已经麻木不堪,需要灵药。我拍手,终于等到你,一起冥想十分钟吧~ 我们俩约定好定期进行禅坐,关掉电话,关...
江南烟雨朦胧, 天涯存储相思豆。 东海暖风争宠, 咫尺透支忘情水。

我要回帖

更多关于 桌面出现cache文件夹 的文章

 

随机推荐