小知识集锦【1】

继续总结本司机在工作过程中涉及到的一些小知识点或小的技巧,其中有代码片段,也有知识点,经验总结和分享。因为工作比较忙,真的没法保证每天都有一篇公号文章发出,所以标题再叫“每天一点小知识”就不太合适了,因此改名为“小知识集锦”。后续使用这个名称,继续为大家总结各种小知识或技巧。

1、Drawable和Bitmap区别

Bitmap - 称作位图文件(Bitmap),扩展名可以是.bmp或者.dib。位图是Windows标准格式图形文件,它将图像定义为由点(像素)组成,每个点可以由多种色彩表示,包括2、4、8、16、24和32位色彩。例如,一幅1024×768分辨率的32位真彩图片,其所占存储字节数为:1024×768×32/(8*1024)=3072KB。

位图文件图像效果比较好,但是是非压缩格式的,需要占用较大存储空间,不利于在网络上传送。jpg格式则恰好弥补了位图文件这个缺点。

Drawable -是 Android平台通用的图形处理对象,它可以装载常用格式的图像,比如 GIF、PNG、JPG,以及 BMP,另外还提供一些高级的可视化对象,比如渐变、图形等。

2、Android编译器一点知识

最近在调试一些开源项目时遇到如下报错,

Error:Jack is required to support java 8 language features. Either enable Jack or remove sourceCompatibility JavaVersion.VERSION_1_8.错误解决

经过在网上查找资料,找到一个知识点需要跟大家普及一下。

2016 年 3 月,Google 向外界发布了 Android N 的预览版的同时,指出 Android N 增加了一项的新特性,这个特性是一项新的工具链,它与 Android 生态圈的所有开发者关系,即 Jack & Jill 编译器的引入。我们知道,Android一直依赖 Sun/Oracle 的 Java 编译器达十年之久,而Google和Sun/Oracle一直在为Java的版权问题打官司,所以,Google研发了自己的Java编译器--Jack。Jack 是 Java Android Compiler Kit 的缩写,它可以将 Java 代码直接编译为 Dalvik 字节码,可以进行 Minification, Obfuscation, Repackaging, Multidexing, Incremental compilation等工作。它可以取代 javac/dx/proguard/jarjar/multidex 库等目前已有的这些工具。

而Android N 7.0(API24)在对JAVA8的支持上,采用了新的编译器。所以这个变异错误的解决方法是在app的gradle文件defaultConfig 段中,增加如下声明语句,

jackOptions {

      enabled true

}

即可解决问题。

参考官网定义如下,

android {

  ...

  defaultConfig {

    ...

    jackOptions {

      enabled true

    }

  }

  compileOptions {

    sourceCompatibility JavaVersion.VERSION_1_8

    targetCompatibility JavaVersion.VERSION_1_8

  }

}

注意: 需要使用Android N 也就是API24

3、Canvas 和和 Paint 的关系

Canvas - 画布。

我们可以看作处理工具,使用其提供的方法可以管理 Bitmap、或Path 所在的图形对象,同时它可以配合 Matrix 矩阵类给图像做旋转、缩放等操作,以及可以进行裁剪、选取等操作。

Paint - 画笔。

可以把它看做一个画图工具,比如画笔、画刷。用它可以设置画图时的字体、颜色、样式等。

4、插件化和热修复的区别

这两个概念对于新手来说,比较容易混淆,这里简单介绍一下二者的区别。

实际上,两者的表现并不相同,而且差别也较明显,虽然有些框架实现上可能有相同之处,比如利用ClassLoad进行hook等。

插件化或者叫组件化的目的是为了减小模块耦合,方便在项目体量变大之后实现更好地团队协作。说白一些就是让你把部分功能提取出来,放到插件里面,而不是一股脑都放到主APK里面,等你需要用到这个插件对应的功能的时候再把它下载下来,这样可以充分减少你主APK的大小。还有一个好处是可以灵活扩展功能,比如版本迭代,引入新的功能。

热更新或者热修复主要目的是不用重新下载和安装新的apk,使用户可以在无感知的情况下修复线上的问题,避免了应用在遇到问题后或者严重bug后频繁发布新版本。

5、比较新和有权威的插件化框架

插件化或组件化:

DroidPlugin -- 360团队出品

质量有保证,成功案例——360手机助手

Replugin -- 360出品

2017年06月30日开源,360 公司几乎所有的亿级用户量的 APP ,以及多款主流第三方 APP ,都采用了 RePlugin 方案

Small--wequick推出的框架

轻巧的插件化框架,酷狗音乐等著名开发团队在使用。

Atlas--阿里框架

淘宝开发和实用的组件化开发框架。

VirtualAPK--滴滴

2017年6月3号开源,良好的兼容性,且入侵性较低,可以作为加载耦合插件方案是较好选择。

除了以上,还有写比较老一些的或者个人开发者框架如,AndroidDymnamicLoader,dynamic-load-apk,CJFrameForAndroid,direct-load-api。

6、比较有名的热修复框架

Weex--阿里

不仅可以实现热修复,还支持跨平台。

andfix(或hotfix)--阿里

2015年下半年开源,提供了一种运行时在Native修改Filed指针的方式,实现方法的替换,达到即时生效无需重启。

dexposed--阿里

阿里大部分App客户端采用的热修复、线上调试能力的框架。

Sophix--阿里

2017年阿里新开源的框架,Sophix 可以说是博采众长,前面提到的Tinker及AndFix 都在某一方面存在缺陷。

Robust--美团

Robust 兼容性与成功率较高,但是它与 AndFix 一样,无法新增变量与类只能用做的 bugFix 方案。

QQ 空间超级补丁方案--腾讯

采用Dex分包机制实现,让修复后的类替换原有的类。

Tinker--腾讯

它是微信官网的Android热补丁解决方案

7、UID和PID区别

UID是用户ID。每个应用程序只有一个。

Android中的UID和计算机不一样,计算机指的是每个用户都具有一个Uid,而Android中每个程序都有一个Uid,默认情况下,Android会给每个程序分配一个普通级别互不相同的 Uid,Android规定只有Uid相同的组件才可以互相调用,因此同一个应用下的Activity是可以互相调用的。

可以通过读取文件data/system/packages.list来查看应用对应的UID。

也可以通过如下代码获取UID,

ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

ApplicationInfo appinfo = getApplicationInfo();

List run = am.getRunningAppProcesses();

for (RunningAppProcessInfo runningProcess : run) {

    if ((runningProcess.processName != null) && runningProcess.processName.equals(appinfo.processName)) {

    uid = String.valueOf(runningProcess.uid);

    break;

    }

}

PID是进程ID。每个进程对应一个ID,但一个应用可能会有多个进程,因此应用的PID并不是唯一的,它可能会有多个。

可以通过如下shell指令查看应用对应的PID。

ps|grep XXX

XXX表示程序的包名。

8、模拟产生点击事件

有些同学不知道,在Android原生系统中有一个input工具,位于/system/bin目录下,国内大部分国产手机是保留这个二进制可执行文件的,而有些手机却将其阉割掉了。它的使用方法如下:

input keyevent xxx<按键名或者按键值>

xxx指具体的事件,如KEYCODE_BACK,表示一个返回键,对应的值为3,再比如KEYCODE_HOME模拟一个home键。按键名或者值可以从官方文档查询,只要是以KEYCODE_开头的都可以。

但是这个指令的执行需要root权限才行。

9、如何判断activity是否已经被销毁

一般我们使用activity.isFinishing()方法来判断activity是否已经被销毁,若Activity被结束,这返回true,否则的话返回false。但是在实际的项目中还是有问题,需要增加activity.isDestoryed()方法来判断activity是否被销毁,但是isDestoryed()方法支持的最低版本为Level 17,因此这个方法也不是太靠谱?

官方给出一个方法,

FragmentManager的API doc 中有这样的定义:

/**

* Returns true if the final {@link Android.app.Activity#onDestroy() Activity.onDestroy()}

* call has been made on the FragmentManager's Activity, so this instance is now dead.

*/

public abstract boolean isDestroyed();

因此可以借助FragmentManager对象来判断,即

 if(fragmentManager.isDestroyed) return;

10、Opus文件格式

前一段时间协助遥控器端调节智能语音遥控器,需要将遥控器端用户输入的语音数据由遥控器的智能芯片通过蓝牙BLE传输给盒子端,然后盒子端进行解码后用来识别,从而控制盒子的操作。我们使用的这个芯片支持三种语音格式,broadvoice,adpcm和opus这三种格式。于是对opus进行了一下了解,以下内容来自于网上。这里带大家了解一下这种音频压缩格式。

Opus编码器 是一个有损声音编码的格式,由互联网工程任务组近来开发的。Opus 格式是一种声音编码格式,并且是一个开放的格式,使用上没有任何专利或限制。它前身是celt编码器。在当今的有损音频格式争夺上,拥有众多不同编码器的AAC格式打败了颇有潜力的Musepack、Vorbis等格式,而在Opus格式诞生后,情况有所变化。通过诸多的对比测试,低码率下Opus完胜曾经优势明显的HE AAC,中码率就已经可以媲敌码率高出30%左右的AAC格式,而高码率下更接近原始音频。


小知识集锦【1】_第1张图片
本公众号将以推送Android各种碎片化小知识或小技巧,以及整理老司机日常工作中踩过的坑涉及到的知识点为主,也会不定期将正在学习使用的React Native一些知识点总结出来进行分享。每天一点干货小知识把你的碎片时间充分利用起来。

你可能感兴趣的:(小知识集锦【1】)