年终盘点跨平台技术优劣势对比(Hybrid、RN、Weex、Flutter)

跨平台技术发展的三个阶段

  • 第一阶段是混合开发的web容器时代

    • 为了解决原生开发的高成本、低效率,出现了Hybrid混合开发
    • 原生中嵌入依托于浏览器的WebView
    • Web浏览器中可以实现的需求在WebView中基本都可以实现
    • 但是Web最大的问题是,它的性能和体验与原生开发存在肉眼可感知的差异
    • 因此并不适用于对性能和用户体验要求较高的场景
  • 第二阶段是以RN和Weex为代表的泛web容器时代

    • RN对Web标准进行了功能裁剪
    • 用户体验更接近于原生了
    • 由于进行了功能裁剪,所以RN对业务的支持能力还不到浏览器的5%
    • 因此仅适用于中低复杂度的低交互类页面。面对稍微复杂一点儿的交互和动画需求,都需要通过调用原生代码去扩展才能实现
  • 第三阶段是以Flutter为代表的自绘引擎时代

    • Flutter是构建Google物联网操作系统Fuchsia的SDK
    • 它使用Dart语言开发APP
    • 一套代码可以同时运行在iOS和Android平台上
    • Flutter采用自带的Native渲染引擎渲染视图,它是自己完成了组件渲染的闭环
    • 而RN、Weex之类的框架,只是通过JavaScript虚拟机扩展调用系统组件,最后是由Android或者iOS系统来完成组件的渲染

继续阅读年终盘点跨平台技术优劣势对比(Hybrid、RN、Weex、Flutter)

Android自动化测试--Espresso使用

相比上一篇文章所讲的Instrumented Unit Tests,本文所讲的自动化测试Espresso最显著的特点就是,可以与UI相交互。

使用

首先我们在Android Studio中新建一个项目,取名为EspressoTests。同时删除自动生成的一些文件,最终目录结构如下:

继续阅读Android自动化测试--Espresso使用

Espresso单元测试等待界面上某个元素显示出来/某个操作完成

在使用 Espresso 进行单元测试的时候,我们需要等待被测试界面上某个元素显示出来,这个时候需要进行等待,等待的时间需要我们自行控制。

继续阅读Espresso单元测试等待界面上某个元素显示出来/某个操作完成

WindowManager中removeView(View v)与removeViewImmediate(View v)的区别

问题及原因:

   我们在做UI相关的代码时有时候会碰到WindowLeak,也就是所谓的窗体泄露,泄露的原因是因为Android UI操作在主线程中操作,但是我们会需要在一些线程或者异步任务中操作UI界面元素的需求,那么这个时候可能会出现类似问题。我在做浮动窗口的时候碰到了这个问题,浮动窗口需要用到WindowManager, WindowManger又是一个Activity的一个变量,它依存于Activity,当横竖屏切换或者Activity销毁的时候这个变量会销毁。销毁的时候导致WindowManager通过AddView()方法添加的View没有依存,导致窗体泄露。那么问题来了,为什么这里会泄露了?

2.解决方法:我在onDestroy()里面调用了removeView方法,想要避免窗体泄露,但是这个方法并不管用,后来换成removeViewImmediate()就解决了这个问题,原因就是两个方法设计到线程同步问题,removeViewImmediate()是通知View立刻调用View.onDetachWindow(),这说明这个方法是通过一个监听或者观察者来实现的,因为线程的同步跟异步问题导致Activity销毁了,但View还没有被remove完,于是就产生了所谓的窗体泄露。说到这里,我想大家也能明白这两个方法的区别了。

参考链接


android WindowManager中removeView(View v)与removeViewImmediate(View v)的区别

NDK is missing a "platforms" directory.unset the NDK variable from ANDROID_NDK_HOME o...

首先这个错误之前没有的,可能是NDK升级到最新导致的编译失败。

尝试按照网上搜索的解决方法解决:

  • 1 删除NDK重新下载,最后删除重新下载后还下载失败,让我自己去看看错误的logAndroid Studio - Help - Show Log In Explorer打开查看log
  • 2 自己去官网下载NDK解压设置路径,都无济于事
  • 3 想到之前看到一篇类似错误的文章说过错误提示缺少哪个文件如果没有就新建一个空文件放在目录下,于是我看了解压后的android-ndk-r22,确实没有错误里提到的platforms,就新建了一个空的platforms文件夹,修改了项目的新NDK路径,再执行编译,奇迹发生了,编译成功!!!app按钮终于是绿色不带叉的了。

继续阅读NDK is missing a "platforms" directory.unset the NDK variable from ANDROID_NDK_HOME o...

ubuntu编译weex_js_engine

weex早期在Android上使用的是V8,但经过测试,JavaScriptCore的性能比V8的性能更好,所以便用JavaScriptCore全面替代了V8

主分支默认使用由 UC 提供的 V8 引擎,默认只提供 armeabi-v7ax86 两个版本的引擎。

系统只能是ubuntu 16.04,因为编译的时候需要gcc-4.7的头文件。

继续阅读ubuntu编译weex_js_engine

PBKDF2加密的实现

PBKDF2(Password-Based Key Derivation Function)

通过哈希算法进行加密。由于哈希算法是单向的,能够将不论什么大小的数据转化为定长的“指纹”,并且无法被反向计算。

另外,即使数据源仅仅修改了一丁点。哈希的结果也会全然不同。

这种特性使得它很适合用于保存password。由于我们须要加密后的password无法被解密,同一时候也能保证正确校验每一个用户的password。可是哈希加密能够通过字典攻击和暴力攻击破解。

password加盐。盐是一个加入到用户的password哈希过程中的一段随机序列。

这个机制可以防止通过预先计算结果的彩虹表破解。每一个用户都有自己的盐,这种结果就是即使用户的password同样。通过加盐后哈希值也将不同。

为了校验password是否正确,我们须要储存盐值。通常和password哈希值一起存放在账户数据库中。或者直接存为哈希字符串的一部分。

首先要生成一个盐值salt,再把原始passwordsalt加密得到密文。验证的时候,把用户输入的password和同样的盐值salt使用同样的加密算法得到一个密文,将这个密文和原密文相比較,同样则验证通过,反之则不通过。


測试结果为:

参考链接


Magisk

Root —— 玩家与厂商间的博弈

Android 从诞生之日起就高举着开源的大旗,这也是它成功的原因之一。而它的开放性也成功的吸引到了一大批爱折腾的人,从而诞生出了 root(此处特制 Android 中的 root)。

根据 Wikipedia 的释义,root 指的是使用户取得 Android 操作系统的超级用户(Super User)许可权的技术。用户通过 root,可以越过手机制造商的限制,卸载手机制造商预装在手机中某些应用,以及运行一些需要超级用户权限的应用程序。同时,root 也可能会让手机变得“不安全”(并不是说 root 使手机变得不安全,而是一些用户的使用习惯会使 root 后的手机变得危险)。

但是从棉花糖(Android 6.0)开始,Google 基本阻止了以前版本中最流行的 root 方法 —— 即,将 su守护程序 放置到 /system 分区,并在启动时取得所需的权限。道高一尺,魔高一丈,于是就出现了 systemless 的 root 方式,因为它不采取任何方式修改 /system 分区。

出于增加安全性的考虑,Google 推出了 SafetyNet 这样的检测,以确保 Android Pay 等一些 App 的安全运行,玩家不得不在 root 权限和一些有价值的 App 之间作出选择。

这个时候 Magisk 诞生了。

Magisk

什么是 Magisk

Magisk 是出自一位台湾学生 @topjohnwu 开发的 Android 框架,是一个通用的第三方 systemless 接口,通过这样的方式实现一些较强大的功能。

看似很简单的一个框架,甚至与大名鼎鼎的 Xposed 框架在功能性上有点重复。很多人批评 Magisk的模块太少了,想替代 Xposed 根本不可能(在那个 Xposed Framework for Android 7.0 难产的时代,很多人将 Magisk 看是做是 Xposed 的替代品)。这是不正确的,因为 Magisk 从来没有想过要代替 Xposed ,Magisk 与 Xposed 是可以互相兼容的,你甚至可以通过 Magisk 来安装 Xposed(安装 Xposed 后就不能绕过 SafetyNet 了)。

Magisk 的厉害之处在于它实现了一种绕过 SafetyNet 使用 root 的方法。

实现原理:由于它是通过启动时在 boot 中创建钩子,把 /data/magisk.img 挂载到 /magisk,构建出一个在 system 基础上能够自定义替换,增加以及删除的文件系统,所有操作都在启动的时候完成,实际上并没有对 /system 分区进行修改(即 systemless 接口,以不触动 /system 的方式修改 /system)。

功能

截至目前版本(v14.0),Magisk 可以实现的功能包括:

  • 集成 root(MagiskSU)
  • root 和 Magisk 的日志功能
  • Magisk Hide(隐藏 Magisk 的 root 权限,针对 Snapchat、Android Pay、PokémonGo、Netflix 等)
  • 为广告屏蔽应用提供 systemless hosts 支持
  • 通过 SafetyNet 检查
  • Magisk 功能模块

支持的版本:Android 5.0+

安装方法

安装 Magisk 需要解锁 Bootloader 并刷入第三方 Recovery。所以每个品牌的手机都或多或少的有点不一样,这里只介绍一个标准的流程,具体操作方法请自行 Google(只需要 Google 你使用的手机解锁 Bootloader 和刷入第三方 Recovery 的方法就可以了,其他的安我说的做)。

  1. 解锁手机 Bootloader(BL)
    方法:自行 Google
  2. 刷入第三方 Recovery(例如 TWRP)
    方法:自行 Google
  3. 下载官方 Magisk 包,然后通过第三方 Recovery 刷入
    方法:首先将下好的包放入手机的硬盘中(你可以使用 QQ数据线 也可以使用 XX手机助手,whatever)然后,进入第三方 Recovery(以 twrp 为例),安装刷机包 -> 找到我让你放在硬盘中的那个包(后缀为 .zip)-> 滑动滑块,开始刷机 -> 刷好后立即重启
  4. 享受完整 Magisk 的 systemless root 和神奇的 Magisk 模块
    重启后找到一个名为 Magisk Manager(图标是一个面具,绿色背景),这是 Magisk 的管理程序,你可以在这里下载、安装、升级、卸载你的 Magisk 和 Magisk 模块。
  5. 卸载 Magisk
    卸载 Magisk 有两种方法:在 Magisk Manager 中卸载,或者通过第三方 Recovery 刷入卸载包卸载。通过 Magisk Manager 卸载很好理解,通过第三方 Recovery 卸载的意思是刷一个名为 Magisk-uninstaller.zip 的刷机包,方法和刷 Magisk 一样。两种方法我都没试过。
一些推荐的功能模块

App Systemizer

这是一个能把用户 App 挂载为系统 App 的模块,如 Google Play 服务、绿色守护、蟒蛇音效等。

Magisk SELinux Permissive Script

使 Android 的 SELinux 默认以 Permissive 运行,关于 SELinux 模式的介绍,请点击这里

ViPER4Android FX

大名鼎鼎的蝰蛇音效的 Magisk 模块,需要配合 VIPERFX 的管理器使用,请在 XDA 论坛搜索下载。关于ViPER4Android

Xposed

强大的 Xposed 框架的 systemless 实现,关于 Xposed 的介绍点击这里

待续...

一些资源

如果你不知道这么找 Magisk 或者 VIPERFX。我这里提供了一些资源。不能保证是最新的。

  • Magisk_v17.1.zip

    Magisk 卡刷包,版本:17.1

  • VIPERFX

    ViPER4Android FX 的管理程器,版本:2.5.0.5

  • ViPER4Android_full.zip

    我收集的蝰蛇音效的音效配置、脉冲反馈 和 DDC。完整版,质量良莠不齐

  • ViPER4Android.zip

    还是音效配置、脉冲反馈 和 DDC。但这是我精选过的版本,也是目前再用的版本

参考链接


Android中的@SmallTest,@MediumTest和@LargeTest注解的目的是什么?

Android中的@SmallTest,@MediumTest和@LargeTest注解的目的是什么?

例如:

参考下图:

继续阅读Android中的@SmallTest,@MediumTest和@LargeTest注解的目的是什么?

Robolectric 3.x编写屏幕分辨率/多语言/资源文件相关测试用例

在编写 Android 测试用例的时候,有时候我们需要涉及到屏幕分辨率相关测试用例。

比如不同分辨率得到不同的像素数值,可以参考如下:

比如不同语言得到不同的字符串,可以参考如下:

其他相关的测试参数,参考 Device Configuration

注意需要在 build.gradle 中增加资源包含信息,否则在测试的时候会找不到指定的资源文件,默认只测试代码,被测试的资源文件不打包进入应用。

参考如下:

参考链接