文档章节

Android代码规范指北

叶大侠
 叶大侠
发布于 2017/03/23 20:25
字数 4231
阅读 637
收藏 102
点赞 1
评论 6

统一的代码风格在多人协作开发中的作用是不言而喻的,通过参考一些比较优秀的实践,这里大量参考了阿里巴巴 JAVA 开发手册 ,再结合了个人的思考,制定了这么一套规范,由于个人的认识是非常有限的,本规范也肯定存在很多不合理和需要补充的东西,在这里恳请大家根据自己的实践和工作中,提出一些中肯的建议和修改意见。

意义

  1. 高度有秩序的代码具有天然的美感,写代码的人心情会好很多。
  2. 减低开发人员流动带来的风险。
  3. 对于新人能更好地理解和参与到开发中。
  4. 更好的可维护性。
  5. 随之带来更好的产品质量和开发效率提升。

命名规约

  • 【强制】所有编程相关命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
  • 【强制】所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。
  • 【强制】方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从驼峰形式。

类的命名

  • 【强制】抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类的名称开始,以 Test 结尾。
  • 【强制】相关组件类应该以组件名作为后缀以便识别。
组件命名规则命名举例
Activity×××ActivityMainActivity
Fragment×××FragmentHomeFragment
Dialog×××DialogAlertDialog
Service×××ServiceDownloadService
BroadcastReceiver×××ReceiverLoginReceiver
ContentProvider×××ProviderUserProvider
Adapter名字+类型+AdapterArticleListAdapter, ImageGridAdapter
AsyncTask×××TaskLoginTask
Handler名字+所在线程+HandlerHomeUIHandler, CompressWorkHandler
ViewHolderVH + 名字VHArticle
  • 【推荐】实用工具类命名成 **Utils**Helper
  • 【推荐】EventBus 发布的事件名命名成以 Event 结尾,比如 LoginEvent
  • 【推荐】如果使用到了设计模式,建议在类名中体现出具体模式。
  • 【推荐】接口一般以大写 I 开头,回调的接口一般为 Listener 或者 Callback 结尾。

方法命名

  • 【强制】POJO 类中的任何布尔类型的变量,都不要加 is,否则部分框架解析会引起序列化错误。 ==反例==:定义为基本数据类型 boolean isSuccess; 的属性,它的方法也是 isSuccess() ,部分Json 框架在反向解析的时候,“以为”对应的属性名称是 success,导致属性获取不到,进而抛出异常。
  • 【强制】EventBus 回调的方法必须和相关 Event 类一致,比如LoginEvent类的方法签名为: public final void onLoginEvent(LoginEvent e);
  • 【推荐】客户端逻辑大部分是基于事件驱动的,应该以on来开头,比如登录按钮的点击可以是:onLoginClick()

变量命名

  • 【强制】常量命名全部大写,单词间用下划线隔开。
  • 【强制】局部变量和一般类变量以小写字母开头。
  • 【推荐】static 类变量名称以s开头,final类变量用f开头。
  • 【推荐】组件相关的可以用【全部首字母+名字】的命名,比如 id 是 R.id.tv_login 的控件名称是:tvLogin

资源文件命名

除了 attr 和 style 资源遵循驼峰命名之外,其他资源的命名统一用小写字母+下划线的风格。

  • 【推荐】布局文件命名
布局类型命名规则例子
Activityactivity_×××HomeActivity 对应 activity_home
Dialogdlg_×××LoginDialog 对应 dlg_login
Fragmentfrag_×××HomeFragment 对应 frag_home
页面标题title_×××title_main
列表Footerfooter_×××footer_article
列表Headerheader_×××header_article
列表的Itemitem_×××item_article
可重用嵌入布局include_ ×××include_navagator
分割线line_+颜色+大小line_gray_1px
  • 【推荐】id命名:截取相关组件首个字母作为开头,然后以下划线作为分割。比如【TextView:tv_name】。
  • 【推荐】图片命名:【类别+名称+状态(如果有)】,根据图片的用途可以分类为图标「ic」,背景「bg」,前景「fg」(比较少用到),图片「img」(比如引导图,开机页面),如果有多个状态用同一张图,那么首选声明为 【××_selected】 。
状态示例
正常状态ic_login_primary
checkedic_login_checked
pressedic_login_pressed
selectedic_login_selected
disableic_login_disable
  • 【推荐】drawable命名
  1. xml定义图形:参考图片命名规则,在以上基础上添加辨识,比如: bg_login_shape, bg_login_vector, bg_login_shape_primary。
  2. 多个状态drawable: 命名为 【××_selector】,比如 bg_login_selector。
  • 【推荐】颜色命名
  1. 单色:命名规则为【类型+名字+状态(如果有)】,我把用到颜色的元素类型做了个归类,分别是字体「text」,背景「bg」,线「line」,还是一些常规色(比如白色,透明等),正例:text_black_primary, bg_black_selected, line_orange。
  2. 字体selector颜色:【名字 + text_selector】 ,比如 tab_item_text_selector。
  • 【推荐】尺寸命名:通用性比较强和需要适配的在 dimens.xml 中设置,一般的可以在代码中直接写。
  1. 字体大小: 【font_××】,××和设计稿保持一致的换算。
  2. 间距:组件外用【××_margin】,组件内用【××_padding】, 例子: app_left_margin。
  3. 控件大小:【宽度:××_width】,【高度:××_height】,其他【××_size】,例子: login_button_height。
  • 【推荐】其他:文字不得直接写到 java 代码和 layout 代码里面,应该抽离到相关的 strings 资源文件中;menu 和动画资源命名不需要加前缀或者后缀,能表达意图即可,因为 R.menu 或者 R.anim 已经携带了相关的信息。

代码风格

  • 【强制】大括号的使用约定。如果是大括号内为空,则简洁地写成{}即可,不需要换行;如果 是非空代码块则:
  1. 左大括号前不换行。
  2. 左大括号后换行。
  3. 右大括号前换行。
  4. 右大括号后还有 else 等代码则不换行;表示终止右大括号后必须换行。
  • 【强制】 左括号和后一个字符之间不出现空格;同样,右括号和前一个字符之间也不出现空格; 代码块缩进 4 个空格,如果使用 tab 缩进,请设置成 1 个 tab 为 4 个空格。
正例:
public static void main(String args[]) {
    // 缩进 4 个空格
    String say = "hello";
    // 运算符的左右必须有一个空格
    int flag = 0;
    // 关键词 if 与括号之间必须有一个空格,括号内 f 与左括号,1 与右括号不需要空格
    if (flag == 0) {
        System.out.println(say);
    }
    
    // 左大括号前加空格且不换行;左大括号后换行
    if (flag == 1) {
        System.out.println("world");
    // 右大括号前换行,右大括号后有 else,不用换行
    } else {
        System.out.println("ok");
    // 右大括号做为结束,必须换行
    }
} 

  • 【强制】任何运算符左右必须加一个空格。

说明:运算符包括赋值运算符 =、逻辑运算符 &&、加减乘除符号、三目运行符等。

  • 【强制】方法参数在定义和传入时,多个参数逗号后边必须加空格。
  • 【强制】单行字符数限制不超过 120 个,超出需要换行,换行时,遵循如下原则:
  1. 换行时相对上一行缩进 4 个空格。
  2. 运算符与下文一起换行。
  3. 方法调用的点符号与下文一起换行。
  4. 在多个参数超长,逗号后进行换行。
  5. 在括号前不要换行,见反例。
正例:
StringBuffer sb = new StringBuffer();
//超过 120 个字符的情况下,换行缩进 4 个空格,并且方法前的点符号一起换行
sb.append("zi").append("xin")…
    .append("huang");

反例:
StringBuffer sb = new StringBuffer();
//超过 120 个字符的情况下,不要在括号前换行
sb.append("zi").append("xin")…append
    ("huang");
//参数很多的方法调用也超过 120 个字符,逗号后才是换行处
method(args1, args2, args3, ...
    , argsX); 
  • 【强制】方法参数在定义和传入时,多个参数逗号后边必须加空格。

正例:下例中实参的 "a" ,后边必须要有一个空格。method("a", "b", "c");

  • 【强制】在 if/else/for/while/do 语句中必须使用大括号,即使只有一行代码,避免使用下面的形式:if (condition) statements;

  • 【推荐】推荐尽量少用 else, if-else 的方式可以改写成:

if(condition){
     …
    return obj;
} 
说明:如果使用要 `if-else if-else` 方式表达逻辑,【强制】请勿超过 3 层,超过请使用状态设计模式。
  • 【推荐】循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量,进行不必要的 try-catch 操作(这个 try-catch 是否可以移至循环体外),遍历长度的提前获取;避免使用 foreach,迭代器,尽量采用下标的形式
正例:
(for i=0 ;i <size; ++i)

反例:
for(int i : items)

编码规约

OOP 规约

  • 【强制】过时的类或者方法不要使用,覆盖的方法要用Override声明。这样当写错覆盖方法时可以得到编译错误提示。
  • 【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。
  • 【强制】单例或者实用类构造方法应该声明为 private。
  • 【强制】如果用到 FastJson 来解析数据,必须在相关 getter 和 setter 方法上添加注解。
  • 【推荐】声明为 public 的方法要对参数进行校验,private 的可以不用。
  • 【推荐】当一个类有多个构造方法,或者多个同名方法,这些方法应该按顺序放置在一起,便于阅读。
  • 【推荐】 类内方法定义顺序依次是:公有方法或保护方法 > 私有方法 > getter/setter 方法。
  • 【推荐】循环体内,字符串的联接方式,使用 StringBuilder 的 append 方法进行扩展。
  • 【推荐】类成员与方法访问控制从严:
  1. 如果不允许外部直接通过 new 来创建对象,那么构造方法必须是 private。
  2. 工具类不允许有 public 或 default 构造方法。
  3. 类非 static 成员变量并且与子类共享,必须是 protected。
  4. 类非 static 成员变量并且仅在本类使用,必须是 private。
  5. 类 static 成员变量如果仅在本类使用,必须是 private。
  6. 若是 static 成员变量,必须考虑是否为 final。
  7. 类成员方法只供类内部调用,必须是 private。
  8. 类成员方法只对继承类公开,那么限制为 protected。

常量定义

  • 【强制】不允许出现任何魔法值(即未经定义的常量)直接出现在代码中。
  • 【强制】long 或者 Long 初始赋值时,必须使用大写的 L,不能是小写的 l ,小写容易跟数字 1 混淆,造成误解。
  • 【推荐】不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。如:缓存 相关的常量放在类:CacheConsts 下;系统配置相关的常量放在类:ConfigConsts 下。
  • 【推荐】避免使用枚举类型,用@IntDef进行替代。

异常处理

  • 【强制】捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。
反例:
void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) { }
}
  • 【强制】异常不要用来做流程控制,条件控制,因为异常的处理效率比条件分支低。
  • 【强制】finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。
  • 【强制】不能在 finally 块中使用 return,finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句。
  • 【强制】捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。==说明==:如果预期抛的是绣球,实际接到的是铅球,就会产生意外情况。
  • 【推荐】不要偷懒直接捕获顶级异常,这样会把Runtime的异常也囊括进来,要明确每种异常出现的场景被给出相应的处理。
反例:
try {
    someComplicatedIOFunction();        // may throw IOException
    someComplicatedParsingFunction();   // may throw ParsingException
    someComplicatedSecurityFunction();  // may throw SecurityException
    // phew, made it all the way
} catch (Exception e) {                 // I'll just catch all exceptions
    handleError();                      // with one generic handler!
}
  • 【推荐】除非有充分的理由,不要捕获 Java 类库中定义的继承自 RuntimeException 的运行时异常类,如:IndexOutOfBoundsException / NullPointerException,这类异常由程序员预检查来规避,保证程序健壮性。

代码注释

  • 【强制】类、类属性、类方法的注释必须使用 javadoc 规范,使用/*内容/格式,不得使用//xxx 方式。
  • 【强制】所有的抽象方法(包括接口中的方法)必须要用 javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
  • 【强制】所有的类都必须添加创建者信息。
  • 【强制】对那些临时性的、短期的、够棒但不完美的代码,请使用TODO注释。
// TODO: Change this to use a flag instead of a constant.
  • 【强制】方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
void method(){
    // 打个招呼
    sayHello();
    
    /*
      这里保持移动,
      并不断对步数加1
     */
    keepMove();
}
  • 【参考】好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的一 个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。

Android 实践

  • 【强制】避免对同个 View 进行多次查找,应该缓存起来,比如列表中使用的 ViewHolder 模式。
反例:
view.findViewById(R.id.iv_toolbar_right).setOnClickListener(this);
view.findViewById(R.id.iv_toolbar_right).setEnabled(true);
  • 【强制】不要使用 System.out.println() ,printf() 打印日志。
  • 【强制】调试日志要有个开关,在正式发布的时候不能出现应用日志打印。
  • 【强制】读文件,数据库,网络请求等一些耗时操作必须在异步线程中执行。
  • 【强制】不能粗暴的把 Activity, Service 对象或者一些比较重的对象直接声明为 static 变量,如果必须这么做,请注意它们的生命周期变化。
  • 【强制】每引入一个第三方库,要检查是否加入相关的混淆规则。
  • 【强制】自定义属性动画 (ObjectAnimator) 的 getter 和 setter 方法时要注意防止混淆。
  • 【强制】在 (Activity,Fragment) 组件退出时要保证相关资源得到释放,比如 EventBus 订阅的事件,注册的广播,轮播任务等。
  • 【强制】对于Api Level大于等于23的设备要进行运行时权限检查。
  • 【推荐】在使用 Thread,Handler,AsyncTask,Timer,耗时的匿名回调类,内部类时,考虑声明成静态的内部类,并且弱引用或者软引用来处理相关的大对象,并且要注意生命周期的变化,避免出现内存泄漏问题。
  • 【推荐】利用 TextView 的drawableLeft等来减少 ImageView 的使用。
  • 【推荐】通过使用 RelativeLayout 或者 ConstraintLayout 来减少布局的层次。
  • 【推荐】在 findViewById 尽可能选取一个比较近的父节点来减少查找时间。
  • 【推荐】Bundle 中的常量 Key 值统一在一个文件中,而不是直接在 Activity 或者 Fragment 中,比如 BundleKeys 文件中。
  • 【推荐】可滑动列表复用的 ViewHolder 对象中,对于一些事件对象应该尽可能地复用。
  • 【推荐】对隐式 Intent 的运行时调用 resolveActivity 进行检查保护。
  • 【推荐】使用 NotificationCompat 兼容包来处理消息通知。
  • 【推荐】延迟创建没有用到的对象,比如 Adapter 的列表对象,应该在请求数据取到之后再去创建,而不是提前创建好。
  • 【推荐】使用 ArrayMap,Sparse×× 系列对象来减少内存消耗和避免AutoBoxing。
  • 【推荐】更新列表局部数据避免粗暴地调用 Adapter.notifyDataSetChanged,应该只更新变化的部分。
  • 【推荐】用 @Nullable, @NonNull, @IdRes, @MainThread 等Support Annotations注解来增强代码的编译期检查和可读性。
  • 【参考】如果不用getColor(int id, Theme theme)等相关方法,至少使用 ContextCompat 来获取相关 Color 或者图片资源。
  • 【参考】尽可能通过 Fragment 来实现视图层,Activity 只是负责嵌入和管理。
  • 【参考】通过 Picasso,Glide 等开源组件去加载和缓存你的图片。

资料参考

  1. 阿里巴巴 JAVA 开发手册
  2. Android Code Style Rules
  3. 常见的八种导致 APP 内存泄漏的问题
  4. Android开发最佳实践
  5. Android Support Annotations

github博客原文:Android代码规范指北

© 著作权归作者所有

共有 人打赏支持
叶大侠

叶大侠

粉丝 56
博文 44
码字总数 67312
作品 5
广州
程序员
加载中

评论(6)

叶大侠
叶大侠

引用来自“大神都是从菜鸟进化的”的评论

请问问文章中的避免使用foreach怎么讲?好多文章都让尽量使用foreach,而且在用AS的时候,lint也会提示使用foreach
在Android Performance Patterns 系列视频中有一级对比过各种迭代方法的性能, 具体哪集忘记了。
摘抄笔记:左边是迭代的方法,右边是相同次数的迭代时间:
[for index(ArrayList),2603]
[for index(Vector), 4664]
[for simple(ArrayList), 5133](for each)
[Iterator(ArrayLust), 5142](迭代器next的方式)
[Iterator(Vector), 11778]
[for simple(Vector), 11783]
大神都是从菜鸟进化的
请问问文章中的避免使用foreach怎么讲?好多文章都让尽量使用foreach,而且在用AS的时候,lint也会提示使用foreach
a
app-developer
非常好的文章,赞!
巴拉迪维
巴拉迪维
有意思
凉拌牛肉
凉拌牛肉
学习了
Android ------ 美团的Lint代码检查实践

概述 Lint是Google提供的Android静态代码检查工具,可以扫描并发现代码中潜在的问题,提醒开发人员及早修正,提高代码质量。除了Android原生提供的几百个Lint规则,还可以开发自定义Lint规则...

切切歆语 ⋅ 04/16 ⋅ 0

移动开发:美团外卖Android Lint代码检查实践

概述 Lint是Google提供的Android静态代码检查工具,可以扫描并发现代码中潜在的问题,提醒开发人员及早修正,提高代码质量。除了Android原生提供的几百个Lint规则,还可以开发自定义Lint规则...

meituantech ⋅ 04/13 ⋅ 0

Android系统源码分析团体项目BeesAndroid正式上线啦

嗨,BeesAndroid开源技术小组正式成立啦,Bees,即蜜蜂,取义分享、合作与奉献的意思,这也是BeesAndroid小组的宗旨,我们第一个团体项目BeesAndroid也于2018年3月6日同步上线,该项目的前 ...

郭孝星 ⋅ 03/08 ⋅ 0

【我的Android进阶之旅】Android自定义Lint实践

一、Lint介绍 android lint是一个静态代码分析工具,通过lint工具,你可以不用边运行边调试,或者通过单元测试进行代码检查,可以检测代码中不规范、不和要求的问题,解决一些潜在的bug。lin...

qq446282412 ⋅ 05/19 ⋅ 0

安卓应用安全指南 5.2.1 权限和保护级别 示例代码

5.2.1 权限和保护级别 示例代码 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 5.2.1.1 如何使用 Android OS 的系统权限 Android 操作...

apachecn_飞龙 ⋅ 04/01 ⋅ 0

慧荣科技发布全球首款商用SD 5.1控制器解决方案

2015年11月22日,台湾台北 —— 在设计和推广固态存储设备专用NAND闪存控制器方面处于全球领导地位的慧荣科技公司(Silicon Motion Technology Corporation, 纳斯达克交易代码: SIMO)今日宣...

玄学酱 ⋅ 05/08 ⋅ 0

android沉浸状态栏实现、地图多线路规划、Retrofit+RxJava+Jsoup+Mvp模式资讯类App等源码

Android精选源码 Android各种沉浸式状态栏实现源码(http://www.apkbus.com/thread-598927-1-1.html) Android自定义View实现炫酷的星期日期选择控件源码(http://www.apkbus.com/thread-59893...

逆鳞龙 ⋅ 05/08 ⋅ 0

android --------学习流程图

如何快速入门和进阶安卓开发,是很多技术小白的疑问。 大家都知道,Android开发要学的技能非常多,技术更新速度还快,但是总的来说:掌握最核心的技术,最规范的开发流程,成为专业、出色的安...

切切歆语 ⋅ 05/06 ⋅ 0

我的Android重构之旅:框架篇

在我这几年的学习和成长中,慢慢的意识到搭建一个优秀的 Android 开发框架是一件非常困难以及痛苦的事情,它不仅需要满足不断增长的业务需求,还要保证框架自身的整洁与扩展性,这让事情变得...

codeGoogle ⋅ 06/13 ⋅ 0

安卓应用安全指南 4.5.3 使用 SQLite 高级话题

安卓应用安全指南 4.5.3 使用 SQLite 高级话题 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 4.5.3.1 在 SQL 语句的断言中使用通配符...

apachecn_飞龙 ⋅ 03/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 28分钟前 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

eclipse酷炫大法之设置主题、皮肤

eclipse酷炫大法 目前两款不错的eclipse 1.系统设置 Window->Preferences->General->Appearance 2.Eclipse Marketplace下载【推荐】 Help->Eclipse Marketplace->搜索‘theme’进行安装 比如......

anlve ⋅ 昨天 ⋅ 0

vim编辑模式、vim命令模式、vim实践

vim编辑模式 编辑模式用来输入或修改文本内容,编辑模式除了Esc外其他键几乎都是输入 如何进入编辑模式 一般模式输入以下按键,均可进入编辑模式,左下角提示 insert(中文为插入) 字样 i ...

蛋黄Yolks ⋅ 昨天 ⋅ 0

大数据入门基础:SSH介绍

什么是ssh 简单说,SSH是一种网络协议,用于计算机之间的加密登录。 如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码...

董黎明 ⋅ 昨天 ⋅ 0

web3j教程

web3j是一个轻量级、高度模块化、响应式、类型安全的Java和Android类库提供丰富API,用于处理以太坊智能合约及与以太坊网络上的客户端(节点)进行集成。 汇智网最新发布的web3j教程,详细讲解...

汇智网教程 ⋅ 昨天 ⋅ 0

谷歌:安全问题机制并不如你想象中安全

腾讯科技讯 5月25日,如今的你或许已经对许多网站所使用的“安全问题机制”习以为常了,但你真的认为包括“你第一个宠物的名字是什么?”这些问题能够保障你的帐户安全吗? 根据谷歌(微博)安...

问题终结者 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部