安卓包下载安全补丁怎么降版本

111925人阅读
【android 进阶之路】(74)
转载请标明出处:
最新github上开源了很多热补丁动态修复框架,大致有:
上述三个框架呢,根据其描述,原理都来自:,以及,所以这俩篇务必要看。这里就不对三个框架做过多对比了,因为原理都一致,实现的代码可能差异并不是特别大。
有兴趣的直接看这篇原理文章,加上上面框架的源码基本就可以看懂了。当然了,本篇博文也会做个上述框架源码的解析,以及在整个实现过程中用到的技术的解析。
二、热修复原理
对于热修复的原理,如果你看了上面的两篇文章,相信你已经大概明白了。重点需要知道的就是,Android的ClassLoader体系,android中加载类一般使用的是PathClassLoader和DexClassLoader,首先看下这两个类的区别:
对于PathClassLoader,从文档上的注释来看:
Provides a simple {@link ClassLoader} implementation that operates
on a list of files and directories in the local file system, but
does not attempt to load classes from the network. Android uses
this class for its system class loader and for its application
class loader(s).
可以看出,Android是使用这个类作为其系统类和应用类的加载器。并且对于这个类呢,只能去加载已经安装到Android系统中的apk文件。
对于DexClassLoader,依然看下注释:
A class loader that loads classes from {@code .jar} and
{@code .apk} files containing a {@code classes.dex} entry.
be used to execute code not installed as part of an application.
可以看出,该类呢,可以用来从.jar和.apk类型的文件内部加载classes.dex文件。可以用来执行非安装的程序代码。
ok,如果大家对于插件化有所了解,肯定对这个类不陌生,插件化一般就是提供一个apk(插件)文件,然后在程序中load该apk,那么如何加载apk中的类呢?其实就是通过这个DexClassLoader,具体的代码我们后面有描述。
ok,到这里,大家只需要明白,Android使用PathClassLoader作为其类加载器,DexClassLoader可以从.jar和.apk类型的文件内部加载classes.dex文件就好了。
上面我们已经说了,Android使用PathClassLoader作为其类加载器,那么热修复的原理具体是?
ok,对于加载类,无非是给个classname,然后去findClass,我们看下源码就明白了。
PathClassLoader和DexClassLoader都继承自BaseDexClassLoader。在BaseDexClassLoader中有如下源码:
#BaseDexClassLoader
protected Class&?& findClass(String name) throws ClassNotFoundException {
Class clazz = pathList.findClass(name);
if (clazz == null) {
throw new ClassNotFoundException(name);
#DexPathList
public Class findClass(String name) {
for (Element element : dexElements) {
DexFile dex = element.dexF
if (dex != null) {
Class clazz = dex.loadClassBinaryName(name, definingContext);
if (clazz != null) {
return null;
public Class loadClassBinaryName(String name, ClassLoader loader) {
return defineClass(name, loader, mCookie);
private native static Class defineClass(String name, ClassLoader loader, int cookie);
可以看出呢,BaseDexClassLoader中有个pathList对象,pathList中包含一个DexFile的集合dexElements,而对于类加载呢,就是遍历这个集合,通过DexFile去寻找。
ok,通俗点说:
一个ClassLoader可以包含多个dex文件,每个dex文件是一个Element,多个dex文件排列成一个有序的数组dexElements,当找类的时候,会按顺序遍历dex文件,然后从当前遍历的dex文件中找类,如果找类则返回,如果找不到从下一个dex文件继续查找。(来自:安卓App热补丁动态修复技术介绍)
那么这样的话,我们可以在这个dexElements中去做一些事情,比如,在这个数组的第一个元素放置我们的patch.jar,里面包含修复过的类,这样的话,当遍历findClass的时候,我们修复的类就会被查找到,从而替代有bug的类。
说到这,你可能已经露出笑容了,原来热修复原理这么简单。不过,还存在一个CLASS_ISPREVERIFIED的问题,对于这个问题呢,详见:该文有图文详解。
ok,对于CLASS_ISPREVERIFIED,还是带大家理一下:
根据上面的文章,在虚拟机启动的时候,当verify选项被打开的时候,如果static方法、private方法、构造函数等,其中的直接引用(第一层关系)到的类都在同一个dex文件中,那么该类就会被打上CLASS_ISPREVERIFIED标志。
那么,我们要做的就是,阻止该类打上CLASS_ISPREVERIFIED的标志。
注意下,是阻止引用者的类,也就是说,假设你的app里面有个类叫做LoadBugClass,再其内部引用了BugClass。发布过程中发现BugClass有编写错误,那么想要发布一个新的BugClass类,那么你就要阻止LoadBugClass这个类打上CLASS_ISPREVERIFIED的标志。
也就是说,你在生成apk之前,就需要阻止相关类打上CLASS_ISPREVERIFIED的标志了。对于如何阻止,上面的文章说的很清楚,让LoadBugClass在构造方法中,去引用别的dex文件,比如:hack.dex中的某个类即可。
ok,总结下:
其实就是两件事:1、动态改变BaseDexClassLoader对象间接引用的dexElements;2、在app打包的时候,阻止相关类去打上CLASS_ISPREVERIFIED标志。
如果你没有看明白,没事,多看几遍,下面也会通过代码来说明。
三、阻止相关类打上CLASS_ISPREVERIFIED标志
ok,接下来的代码基本上会通过所提供的代码来讲解。
那么,这里拿具体的类来说:
大致的流程是:在dx工具执行之前,将LoadBugClass.class文件呢,进行修改,再其构造中添加System.out.println(dodola.hackdex.AntilazyLoad.class),然后继续打包的流程。注意:AntilazyLoad.class这个类是独立在hack.dex中。
ok,这里大家可能会有2个疑问:
如何去修改一个类的class文件
如何在dx之前去进行疑问1的操作
(1)如何去修改一个类的class文件
这里我们使用javassist来操作,很简单:
ok,首先我们新建几个类:
package dodola.
public class AntilazyLoad
package dodola.
public class BugClass
public String bug()
return "bug class";
package dodola.
public class LoadBugClass
public String getBugString()
BugClass bugClass = new BugClass();
return bugClass.bug();
注意下,这里的package,我们要做的是,上述类正常编译以后产生class文件。比如:LoadBugClass.class,我们在LoadBugClass.class的构造中去添加一行:
System.out.println(dodola.hackdex.AntilazyLoad.class)
下面看下操作类:
import javassist.ClassP
import javassist.CtC
import javassist.CtC
public class InjectHack
public static void main(String[] args)
String path = "/Users/zhy/develop_work/eclipse_android/imooc/JavassistTest/";
ClassPool classes = ClassPool.getDefault();
classes.appendClassPath(path + "bin");
CtClass c = classes.get("dodola.hotfix.LoadBugClass");
CtConstructor ctConstructor = c.getConstructors()[0];
ctConstructor
.insertAfter("System.out.println(dodola.hackdex.AntilazyLoad.class);");
c.writeFile(path + "/output");
} catch (Exception e)
e.printStackTrace();
ok,点击run即可了,注意项目中导入javassist-*.jar的包。
首先拿到ClassPool对象,然后添加classpath,如果你有多个classpath可以多次调用。然后从classpath中找到LoadBugClass,拿到其构造方法,在其最后插入一行代码。ok,代码很好懂。
ok,我们反编译看下我们生成的class文件:
ok,关于javassist,如果有兴趣的话,大家可以参考几篇文章学习下:
(2)如何在dx之前去进行(1)的操作
ok,这个就结合的源码来说了。
将其源码导入之后,打开app/build.gradle
apply plugin: 'com.android.application'
task('processWithJavassist')
classPath = file('build/intermediates/classes/debug')//项目编译class所在目录
dodola.patch.PatchClass.process(classPath, project(':hackdex').buildDir
.absolutePath + '/intermediates/classes/debug')//第二个参数是hackdex的class所在目录
applicationVariants.all { variant -&
variant.dex.dependsOn
//在执行dx命令之前将代码打入到class中
你会发现,在执行dx之前,会先执行processWithJavassist这个任务。这个任务的作用呢,就和我们上面的代码一致了。而且源码也给出了,大家自己看下。
ok,到这呢,你就可以点击run了。ok,有兴趣的话,你可以反编译去看看dodola.hotfix.LoadBugClass这个类的构造方法中是否已经添加了改行代码。
关于反编译的用法,工具等,参考:
ok,到此我们已经能够正常的安装apk并且运行了。但是目前还未涉及到打补丁的相关代码。
四、动态改变BaseDexClassLoader对象间接引用的dexElements
ok,这里就比较简单了,动态改变一个对象的某个引用我们反射就可以完成了。
不过这里需要注意的是,还记得我们之前说的,寻找class是遍历dexElements;然后我们的AntilazyLoad.class实际上并不包含在apk的classes.dex中,并且根据上面描述的需要,我们需要将AntilazyLoad.class这个类打成独立的hack_dex.jar,注意不是普通的jar,必须经过dx工具进行转化。
jar cvf hack.jar dodola/hackdex/*
--dex --output hack_dex.jar hack.jar
如果,你没有办法把那一个class文件搞成jar,去百度一下…
ok,现在有了hack_dex.jar,这个是干嘛的呢?
应该还记得,我们的app中部门类引用了AntilazyLoad.class,那么我们必须在应用启动的时候,降这个hack_dex.jar插入到dexElements,否则肯定会出事故的。
那么,Application的onCreate方法里面就很适合做这件事情,我们把hack_dex.jar放到assets目录。
下面看hotfix的源码:
package dodola.
import android.app.A
import android.content.C
import java.io.F
import dodola.hotfixlib.HotF
* Created by sunpengfei on 15/11/4.
public class HotfixApplication extends Application
public void onCreate()
super.onCreate();
File dexPath = new File(getDir("dex", Context.MODE_PRIVATE), "hackdex_dex.jar");
Utils.prepareDex(this.getApplicationContext(), dexPath, "hackdex_dex.jar");
HotFix.patch(this, dexPath.getAbsolutePath(), "dodola.hackdex.AntilazyLoad");
this.getClassLoader().loadClass("dodola.hackdex.AntilazyLoad");
} catch (ClassNotFoundException e)
e.printStackTrace();
ok,在app的私有目录创建一个文件,然后调用Utils.prepareDex将assets中的hackdex_dex.jar写入该文件。
接下来HotFix.patch就是去反射去修改dexElements了。我们深入看下源码:
package dodola.
* Created by sunpengfei on 15/11/4.
public class Utils {
private static final int BUF_SIZE = 2048;
public static boolean prepareDex(Context context, File dexInternalStoragePath, String dex_file) {
BufferedInputStream bis = null;
OutputStream dexWriter = null;
bis = new BufferedInputStream(context.getAssets().open(dex_file));
dexWriter = new BufferedOutputStream(new FileOutputStream(dexInternalStoragePath));
byte[] buf = new byte[BUF_SIZE];
while ((len = bis.read(buf, 0, BUF_SIZE)) & 0) {
dexWriter.write(buf, 0, len);
dexWriter.close();
bis.close();
return true;
ok,其实就是文件的一个读写,将assets目录的文件,写到app的私有目录中的文件。
下面主要看patch方法
package dodola.
import android.annotation.TargetA
import android.content.C
import java.io.F
import java.lang.reflect.A
import java.lang.reflect.F
import java.lang.reflect.InvocationTargetE
import dalvik.system.DexClassL
import dalvik.system.PathClassL
public final class HotFix
public static void patch(Context context, String patchDexFile, String patchClassName)
if (patchDexFile != null && new File(patchDexFile).exists())
if (hasLexClassLoader())
injectInAliyunOs(context, patchDexFile, patchClassName);
} else if (hasDexClassLoader())
injectAboveEqualApiLevel14(context, patchDexFile, patchClassName);
injectBelowApiLevel14(context, patchDexFile, patchClassName);
} catch (Throwable th)
这里很据系统中ClassLoader的类型做了下判断,原理都是反射,我们看其中一个分支hasDexClassLoader();
private static boolean hasDexClassLoader()
Class.forName("dalvik.system.BaseDexClassLoader");
return true;
} catch (ClassNotFoundException e)
return false;
private static void injectAboveEqualApiLevel14(Context context, String str, String str2)
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException
PathClassLoader pathClassLoader = (PathClassLoader) context.getClassLoader();
Object a = combineArray(getDexElements(getPathList(pathClassLoader)),
getDexElements(getPathList(
new DexClassLoader(str, context.getDir("dex", 0).getAbsolutePath(), str, context.getClassLoader()))));
Object a2 = getPathList(pathClassLoader);
setField(a2, a2.getClass(), "dexElements", a);
pathClassLoader.loadClass(str2);
首先查找类dalvik.system.BaseDexClassLoader,如果找到则进入if体。
在injectAboveEqualApiLevel14中,根据context拿到PathClassLoader,然后通过getPathList(pathClassLoader),拿到PathClassLoader中的pathList对象,在调用getDexElements通过pathList取到dexElements对象。
ok,那么我们的hack_dex.jar如何转化为dexElements对象呢?
通过源码可以看出,首先初始化了一个DexClassLoader对象,前面我们说过DexClassLoader的父类也是BaseDexClassLoader,那么我们可以通过和PathClassLoader同样的方式取得dexElements。
ok,到这里,我们取得了,系统中PathClassLoader对象的间接引用dexElements,以及我们的hack_dex.jar中的dexElements,接下来就是合并这两个数组了。
可以看到上面的代码使用的是combineArray方法。
合并完成后,将新的数组通过反射的方式设置给pathList.
接下来看一下反射的细节:
private static Object getPathList(Object obj) throws ClassNotFoundException, NoSuchFieldException,
IllegalAccessException
return getField(obj, Class.forName("dalvik.system.BaseDexClassLoader"), "pathList");
private static Object getDexElements(Object obj) throws NoSuchFieldException, IllegalAccessException
return getField(obj, obj.getClass(), "dexElements");
private static Object getField(Object obj, Class cls, String str)
throws NoSuchFieldException, IllegalAccessException
Field declaredField = cls.getDeclaredField(str);
declaredField.setAccessible(true);
return declaredField.get(obj);
其实都是取成员变量的过程,应该很容易懂~~
private static Object combineArray(Object obj, Object obj2)
Class componentType = obj2.getClass().getComponentType();
int length = Array.getLength(obj2);
int length2 = Array.getLength(obj) +
Object newInstance = Array.newInstance(componentType, length2);
for (int i = 0; i & length2; i++)
if (i & length)
Array.set(newInstance, i, Array.get(obj2, i));
Array.set(newInstance, i, Array.get(obj, i - length));
return newI
ok,这里的两个数组合并,只需要注意一件事,将hack_dex.jar里面的dexElements放到新数组前面即可。
到此,我们就完成了在应用启动的时候,动态的将hack_dex.jar中包含的DexFile注入到ClassLoader的dexElements中。这样就不会查找不到AntilazyLoad这个类了。
ok,那么到此呢,还是没有看到我们如何打补丁,哈,其实呢,已经说过了,打补丁的过程和我们注入hack_dex.jar是一致的。
你现在运行HotFix的app项目,点击menu里面的测试:
会弹出:调用测试方法:bug class
接下来就看如何完成热修复。
五、完成热修复
ok,那么我们假设BugClass这个类有错误,需要修复:
package dodola.
public class BugClass
public String bug()
return "fixed class";
可以看到字符串变化了:bug class -& fixed class .
然后,编译,将这个类的class-&jar-&dex。步骤和上面是一致的。
jar cvf path.jar dodola/hotfix/BugClass.class
--dex --output path_dex.jar path.jar
拿到path_dex.jar文件。
正常情况下,这个玩意应该是下载得到的,当然我们介绍原理,你可以直接将其放置到sdcard上。
然后在Application的onCreate中进行读取,我们这里为了方便也放置到assets目录,然后在Application的onCreate中添加代码:
public class HotfixApplication extends Application
public void onCreate()
super.onCreate();
File dexPath = new File(getDir("dex", Context.MODE_PRIVATE), "hackdex_dex.jar");
Utils.prepareDex(this.getApplicationContext(), dexPath, "hack_dex.jar");
HotFix.patch(this, dexPath.getAbsolutePath(), "dodola.hackdex.AntilazyLoad");
this.getClassLoader().loadClass("dodola.hackdex.AntilazyLoad");
} catch (ClassNotFoundException e)
e.printStackTrace();
dexPath = new File(getDir("dex", Context.MODE_PRIVATE), "path_dex.jar");
Utils.prepareDex(this.getApplicationContext(), dexPath, "path_dex.jar");
HotFix.patch(this, dexPath.getAbsolutePath(), "dodola.hotfix.BugClass");
其实就是添加了后面的3行,这里需要说明一下,第一行依旧是复制到私有目录,如果你是sdcard上,那么操作基本是一致的,这里就别问:如果在sdcard或者网络上怎么处理~
ok,那么再次运行我们的app。
ok,最后说一下,说项目中有一个打补丁的按钮,在menu下,那么你也可以不在Application里面添加我们最后的3行。
你运行app后,先点击打补丁,然后点击测试也可以发现成功修复了。
如果先点击测试,再点击打补丁,再测试是不会变化的,因为类一旦加载以后,不会重新再去重新加载了。
ok,到此,我们的热修复的原理,已经解决方案,我相信已经很详细的介绍完成了,如果你有足够的耐心一定可以实现。中间制作补丁等操作,我们的操作比较麻烦,自动化的话,可以参考。
最后就是对于QQ空间团队,以及开源作者的感谢了~~
欢迎关注我的微博:
群号:,欢迎入群
微信公众号:hongyangAndroid
(欢迎关注,第一时间推送博文信息)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
积分:49559
积分:49559
排名:第62名
原创:202篇
评论:14939条
长期为您推荐优秀博文、开源项目、视频等,进入还有好玩的等着你,欢迎扫一扫。
请勿重复加群,Thx
文章:11篇
阅读:214805
文章:10篇
阅读:123978
文章:67篇
阅读:6098638您现在的位置: >
小米3系统降级的最简单方法教程 无需线刷
  小米3系统怎么降级?一些用户在更新系统之后觉得不好用想回到原系统,如何让小米3系统降级呢?现在小编来分享一个非常简单的小米3升级后降级回原系统的方法教程,不需要网络,不用下载ROM刷机包,也不用线刷即可降级回原系统,让你的小米3系统降级更加省时省力省心。
  【小米3系统降级的最简单方法】
  注意:确定你的小米手机3有足够的电量,因为在操作中的耗电量会比较大,避免不必要的问题产生,建议大家做好操作前的检查准备工作,检查完毕后,大家就可以按照以下方法操作即可。
  在教程开始之前,先说一下,这里先将小米手机3升级到开发版&MIUI V5 3.12.6&后,再教大家如何把小米手机3恢复到没有刷系统之前的开发版&MIUI V5 3.11.27&。具体步骤如下:
  1、打开手机桌面,点击&系统与安全&--&&系统更新&,进入系统升级的界面。
  2、在系统升级的界面,点击你小米手机下方键盘的最左边的&菜单键&,然后会弹出以下这些选项,点击&重启到Recovery&,点击确定,手机就会自动重启,进入Recovery模式。
  3、系统会自动重启,黑屏,并进入Recovery模式,当大家看到手机出现以下这个界面的情况下,就代表你的手机已经成功进入Recovery模式。Recovery模式选择语言的界面如下图。
  注:声音+-键来操作上下的选择选项,电源键作确认的按钮。
  4、选择完语言之后,你就会看到&重启手机&的字样,点击进去,然后你就会看到&重启进入系统一&和&重启进入系统二(最近)&这两个选项,最近的意思就是你当前最新的系统的意思,系统一就是你没有升级之前在用的系统,所以请点击&重启进入系统一&。
  5、按一下&声音+&将光标调到&重启进入系统一&选项上,然后再点击电源键确认一下,等待手机重启即可。
  6、手机会自动加载补丁,这些补丁就是之前系统的补丁,意思就是让手机回到过去,恢复到原来你正在用的系统。
  7、恢复系统之后,通知栏处就会弹出两个图标,一个是&提示有系统更新的图标&,一个是你现在更新系统后的通知图标,然后大家再进入一下&系统更新&界面。
  8、进入到系统升级的界面,便会弹出一个验证状态,这个就是验证有新系统的更新,这时你已经成功把系统恢复到你原来的系统了。
  小米3系统怎么降级?以上就是小米3系统降级最简单的方法了,小米3升级后如何降级恢复回原系统就是这么简单了。
相关文章:小米3 小米3系统降级 小米3系统怎么降级
图解新闻:
最新攻略:
24小时更新:
热门排行本周本月
推荐文章本周本月经验4661 米
在线时间74 小时
版本7.6.14
MIUI论坛坛主
机型小米Note 移动4G/联通4G
签到次数58
MIUI版本7.6.14
自从更新至安卓6.0的米柚8开始,米粉们都体验到了它的流畅、多功能、不一样的色彩等等,但随至而来的问题也突显而出,手机电池的续航时间相比较安卓4.4.4的米柚7那真是一个天一个地,为此许多米粉们纷纷寻求降级至安卓4.4.4之方法。
第一种就是磁盘模式线刷降级,&&但该种方法对于没刷机经验的米粉来说相当不安全,稍不注意就可能刷成黑砖,本人不建议使用该方法降级。
第二种方法就是用第三方RE进行卡刷降级,安全方便简单!
先下载4.4的卡刷包到手机上(刷机包论坛版块置顶贴都有),让手机进入刷机模式,刷入秋大的TWRP3.0.2的中文rec(),刷完成功后手机自动进入TWRP3.0.2,再进行清除数据,再安装上之前下好的4.4的卡刷包接下来就OK了!
今日本人的两台小米全都用该方法降级成功的。附图:
7EA8C9209D09FEF734097D.jpg (69.23 KB, 下载次数: 3)
4B9C523B6B4A1D83B106.jpg (184.43 KB, 下载次数: 0)
FABA3329EDDC4A.jpg (162.63 KB, 下载次数: 0)
(165.88 KB, 下载次数: 0)
18:11 上传
分享到微信朋友圈
打开微信,点击底部的“发现”,使用 “扫一扫” 即可将网页分享到我的朋友圈。
经验930 米
在线时间46 小时
版本7.6.14
积分 1073, 距离下一级还需 927 积分
积分 1073, 距离下一级还需 927 积分
机型小米手机3/4 WCDMA版
签到次数17
MIUI版本7.6.14
卡刷失败了
经验4661 米
在线时间74 小时
版本7.6.14
MIUI论坛坛主
机型小米Note 移动4G/联通4G
签到次数58
MIUI版本7.6.14
我今天两台小米都很顺利!
经验262 米
在线时间26 小时
版本5.12.4
积分 308, 距离下一级还需 192 积分
积分 308, 距离下一级还需 192 积分
机型小米手机3/4 WCDMA版
MIUI版本5.12.4
我的已经安全降级
经验4661 米
在线时间74 小时
版本7.6.14
MIUI论坛坛主
机型小米Note 移动4G/联通4G
签到次数58
MIUI版本7.6.14
弑神seraphim 发表于
我的已经安全降级
经验11081 米
在线时间222 小时
无量天尊版主
机型小米手机4
签到次数62
MIUI版本7.6.8
拥有小米手机就能把女人玩弄于股掌之中。
经验4661 米
在线时间74 小时
版本7.6.14
MIUI论坛坛主
机型小米Note 移动4G/联通4G
签到次数58
MIUI版本7.6.14
小航航同学 发表于
米柚8耗电太严重了
经验11081 米
在线时间222 小时
无量天尊版主
机型小米手机4
签到次数62
MIUI版本7.6.8
7.1.4能亮屏几小时,不玩游戏
拥有小米手机就能把女人玩弄于股掌之中。
经验11081 米
在线时间222 小时
无量天尊版主
机型小米手机4
签到次数62
MIUI版本7.6.8
我也想降了
拥有小米手机就能把女人玩弄于股掌之中。
经验4661 米
在线时间74 小时
版本7.6.14
MIUI论坛坛主
机型小米Note 移动4G/联通4G
签到次数58
MIUI版本7.6.14
小航航同学 发表于
<font color="#.1.4能亮屏几小时,不玩游戏
我测试一下明天告诉你,小航!
MIUI七周年
MIUI 9纪念勋章
“澎湃S1 ”芯片纪念勋章
参与活动回帖可得
参与红米Note 4X活动
Copyright (C) 2017 MIUI
京ICP备号 | 京公网安备34号 | 京ICP证110507号凤凰号出品
修正系统安全问题 黑莓安卓机迎来8月安全补丁
原标题:修正系统安全问题 黑莓安卓机迎来8月安全补丁
据外媒报道称,黑莓已经在推特上宣布,其开始对其安卓智能手机进行推送8月的安全补丁更新。修正系统安全问题 黑莓推送8月安全补丁
据悉,黑莓的Priv和KEYone将首批接收到更新推送,此次更新旨在修正安全性方面的一系列问题,从而提升系统的安全性能。而日前,只有通过黑莓公司在线商店ShopBlackBerry进行购买的机型才会收到此次更新的推送,而从其他渠道购买的手机,或许要等稍晚一些才能收到推送。
本文来自凤凰号,仅代表凤凰号自媒体观点。
用微信扫描二维码
分享至好友
用微信扫描二维码
分享至朋友圈
凤凰争鸣微信号
来点暖心的!扫这里
ZOL中关村在线}

我要回帖

更多关于 安卓版本升级包 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信