zhengxiaoyong

Android Engineer.


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于
zhengxiaoyong

Flutter Engine与SDK的定制化与编译

发表于 2019-03-16 | 分类于 Flutter | | 阅读次数

概述

对于Flutter SDK相关的定制化,也就是两个地方,分别为Flutter Engine与Flutter SDK,对于定制化后的应用,则需要我们重新编译相关的代码产物,主要为Flutter Engine的编译和Flutter Tools的编译

Flutter Engine编译

编译配置

配置Depot_tools脚本工具集

获取Chromium的depot_tools脚本工具集,depot_tools是Google用来管理Chromium源码的工具集,它包含了一系列实用脚本,如:gclient、ninja、repo等。gclient和repo都是用来检出项目源码的脚本,主要区别是gclient主要依赖于.gclient与DEPS这两个配置文件进行多项目模块源码的依赖检出,而repo主要依赖于一个manifest.xml配置文件来进行多项目模块源码检出,gclient定制性相对高些,也更复杂些

获取depot_tools脚本工具集可以通过Git获取:

1
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

并配置到环境变量中:

1
$ export PATH=$PATH:/path/to/depot_tools

构建Flutter Engine产物使用的构建系统是Ninja,Chromium的构建也是使用它,它是一个专注于速度的小型构建系统,即它的输入文件是由更高级别的构建系统生成的产物,而GN就是一个专门生成Ninja构建文件的元构建系统,所以构建Flutter Engine的步骤是先用GN构建Ninja的输入文件,再由Ninja构建最终产物,即:

1
2
3
$ ./flutter/tools/gn
gn gen --check in out/path
$ ninja -C out/path
阅读全文 »
zhengxiaoyong

Flutter动态化探索

发表于 2019-03-10 | 分类于 Flutter | | 阅读次数

前言

Flutter的动态化,对于Android而言,一个很清晰的思路就是动态替换flutter_assets的所有资源文件,因为Flutter加载代码和资源的工作目录即是应用沙盒目录下的app_flutter目录,我们把这个目录下的文件进行对应替换即可,而对于IOS,由于本身系统的限制,官方目前也没相应方案,所以目前暂且说下Android平台上的Dynamic Patch

而目前Flutter Engine最新的Master分支上支持Flutter引擎的动态更新,所以Dynamic Patch支持JIT与AOT模式下的所有代码产物与资源的动态更新,以及模式互切,即下述文件:

isolate_snapshot_data :App代码数据段
isolate_snapshot_instr :App代码指令段
vm_snapshot_data :VM虚拟机数据段
vm_snapshot_instr :VM虚拟机指令段
kernel_blob.bin :Dart代码产物
flutter.so :Flutter引擎
assets :资源文件

阅读全文 »
zhengxiaoyong

Flutter Wrapper Workflow

发表于 2019-01-14 | 分类于 Flutter | | 阅读次数

The Wrapper Workflow

Use the Flutter Wrapper to get the following benefits:

  • Standardizes a project on a given Flutter version, each Flutter project has its own version of Flutter SDK
  • Provides the same Flutter SDK version for different users and execution environments in a Flutter project

Flutter Wrapper contains the following files:

flutterw
flutterw.bat
flutter/wrapper/flutter-wrapper.properties

阅读全文 »
zhengxiaoyong

一种Api兼容性检测方案

发表于 2018-12-27 | 分类于 技术沉淀 | | 阅读次数

简述

一般来说,SDK依赖库的Api兼容性问题一直是个隐藏的问题,通常没有很好的方式解决,即使使用语义化版本管理,在众多基础SDK的引用依赖下,不能100%保证其中一个基础SDK的Api发生不兼容的改变后,该改变可能是对外暴露方法的签名改变、方法名称改变亦或是类名包名等改变,而发生这些不兼容Api的变化后,不能保证所有依赖该基础SDK的上层SDK全部对应的升级依赖版本。当然,良好的开发模式对于基础SDK开发来讲,对外暴露的Api的改变,一般不能直接改变其方法签名以及包名类名等,而应该相应的标为@Deprecated提供向下兼容

但是,作为团队多人协作开发模式下,不能100%保证所有基础SDK的开发都以兼容方式进行Api的改变,除此之外,使用到的一些三方开源SDK,这个也不能保证它提供的Api是否是兼容的,以及在进行组件化、插件化过程中,Api兼容性问题是必须要考虑的

为什么要考虑?这里所说的Api兼容性问题,不是发生在项目编译期,而是在运行期,因为项目中的SDK依赖库依赖进来时,是已经编译好的字节码文件,所以SDK依赖库内的兼容性问题,只有在程序运行期才可出现,一般表现为Crash或无响应,且出现上述情况的前提条件是代码刚好执行到了这段,否则还是不会有任何异常

阅读全文 »
zhengxiaoyong

Flutter混合开发组件化与工程化架构

发表于 2018-12-16 | 分类于 Flutter | | 阅读次数

一、简述

对于构建Flutter类型应用,因其开发语言Dart、虚拟机、构建工具与平时我们开发Native应用不同且平台虚拟机也不支持,所以需要Flutter SDK来支持,如构建Android应用需要Android SDK一样,下载Flutter SDK通常有两种方式:

  1. 在官网下载构建好的zip包,里面包含完整的Flutter基础Api,Dart VM,Dart SDK等
  2. 手动构建,Clone Flutter源码后,运行flutter --packages get或其它具有检测类型的命令如build、doctor,这时会自动构建和下载Dart SDK以及Flutter引擎产物

在团队多人协作开发下,这种依赖每个开发本地下载Flutter SDK的方式,不能保证Flutter SDK的版本一致性与自动化管理,在开发时如果Flutter SDK版本不一致,往往会出现Dart层Api兼容性或Flutter虚拟机不一致等问题,因为每个版本的Flutter都有各自对应的Flutter虚拟机,构建产物中会包含对应构建版本的虚拟机。Flutter工程的构建需要Flutter标准的工程结构目录和依赖于本地的Flutter环境,每个对应Flutter工程都有对应的Flutter SDK路径,Android在local.properties中,IOS在Generated.xcconfig中,这个路径会在Native工程本地依赖Flutter工程构建时读取,并从中获取引擎、资源和编译构建Flutter工程,而调用flutter命令时构建Flutter工程则会获取当前flutter命令所在的Flutter SDK路径,并从中获取引擎、资源和编译构建Flutter工程,所以flutter命令构建环境与Flutter工程中平台子工程的环境变量一定得保持一致,且这个环境变量是随flutter执行动态改变的,团队多人协作下这个得保证,在打包Flutter工程的正式版每个版本也应该有一个对应的Flutter构建版本,不管是本地打包还是在打包平台打包

我们知道Flutter应用的工程结构都与Native应用工程结构不一样,不一致地方主要是Native工程是作为Flutter工程子工程,外层通过Pub进行依赖管理,这样通过依赖下来的Flutter Plugin/Package代码即可与多平台共享,在打包时Native子工程只打包工程代码与Pub所依赖库的平台代码,Flutter工程则通过flutter_tools打包lib目录下以及Pub所依赖库的Dart代码。回到正题,因工程结构的差异,如果基于现有的Native工程想使用Flutter来开发其中一个功能模块,一般来说混合开发至少得保证如下特点:

  1. 对Native工程无侵入
  2. 对Native工程零耦合
  3. 不影响Native工程的开发流程与打包流程
  4. 易本地调试

显然改变工程结构的方案可以直接忽略,官方也提供了一种Flutter本地依赖到现有Native的方案,不过这种方案不加改变优化而直接依赖的话,则会直接影响了其它无Flutter环境的开发同学的开发,影响开发流程,且打包平台也不支持这种依赖方式的打包

再讲讲Flutter SDK,平时进行Flutter开发过程中,难免避免不了因Flutter SDK的Bug亦或是需要改Flutter SDK中平台链接的脚本代码导致直接改动或者定制Flutter SDK,这种方式虽然可以解决问题或定制化,不过极其不推荐,这种方式对后续Flutter SDK的平滑升级极不友好,且带来更多的后期维护成本

接下来,本文主要是介绍如何对上述问题解决与实现:

  1. Flutter SDK版本一致性与自动化管理
  2. 无侵入Flutter SDK源码进行BugFix或定制化
  3. Flutter混合开发组件化架构
  4. Flutter混合开发工程化架构
阅读全文 »
zhengxiaoyong

也谈Manifest与资源Merge

发表于 2017-07-12 | 分类于 技术沉淀 | | 阅读次数

前言

我们知道构建一个apk时必然存在的一个过程—res与manifest的合并,因为资源与manifest除了存在于主资源集中,对于第三方aar或构建变体中也可存在,当构建一个apk时,必然会对它们所含有的资源或manifest进行合并,而不是把所有存在的资源或manifest全打包进apk中,构建一个apk时,主要有以下三种资源会进行merge:

1、主资源集(src/main/)
2、构建变体(buildType、productFlavor、productFlavorBuildType)
3、三方依赖(aar)

当一个资源名在上述资源集中唯一存在时,那么将直接打包进apk中,当一个资源名在不同资源集中存在多个版本时(资源类型与资源限定符相同情况下),这时将只有一个会被打包进apk中,这种情况就是通过merge进行处理,同理,manifest也一样,对于相同的标签存在多个版本时,也将进行merge。资源和manifest的merge都遵循如下优先级:

build variant > build type > product flavor > main source set > library dependencies

阅读全文 »
zhengxiaoyong

也谈图片压缩

发表于 2017-04-23 | 分类于 技术沉淀 | | 阅读次数

简介

随着目前设备像素的不断提高,基本随便一张照片即是M级别的大小,对于如此大的图片,不管是在内存空间、带宽资源和服务器数据空间上都是非常耗费的,特别是在移动端,由图片引起的OOM和图片上传质量过大等问题我想大家都遇到过,所以对于图片内存占用上和物理空间占用上进行压缩很有必要,在Android上,我们使用到的图片格式无非这五种:PNG、JPEG、Webp、SVG、GIF。其中GIF的位深为8位,所以文件通常比较小而且支持alpha通道以及动画,Webp在等质量的大小上和等大小的清晰度上都占极大优势,而SVG矢量图是由xml文件进行描述的,可以适配于任何分辨率的设备而保证图像不失真,Google的官方视频中也提到可用这两种格式进行某些场景下替换PNG或JPEG图像,这不但能节约带宽资源还能提高图片加载速度,所以图片压缩主要是对PNG和JPEG这两种格式,关于图片的压缩,有无损压缩和有损压缩两种方式,这两种压缩方式区别如下:

无损压缩:通过对冗余数据的存储方式进行优化,该方式不会丢失文件内容,压缩率受冗余度的影响,所以压缩率较低
有损压缩:通过丢失不会对文件造成太大影响的数据来达到压缩效果,所以压缩率较高

其中PNG是无损压缩格式图片,JPEG是有损压缩格式图片,所以对应的也有各自的压缩算法,在Android系统中,png的压缩是使用libpng进行压缩,场景有两个:编译阶段以及api层调用方式进行压缩。其中在编译阶段通过aapt打包工具会对drawable目录下png图片进行压缩,压缩率大约在40%以下,如果我们对编译后的apk进行解压,可以发现解压后drawable目录下的png图片比原先的变小了,但是,也有例外,对于NinePatch(.9)图片却变大了,这里先讲下原因,因为对于.9图片在编译过程中aapt会对它额外进行处理,使得.9图片会增加2~3个不同类型的Chunk块(注:api层调用方式进行压缩不会对.9进行额外处理),而jpeg的压缩是用libjpeg(7.0后有变化,后面另外说)进行压缩,场景只有在api层进行调用方式进行压缩。下面将主要围绕图片的压缩原理、压缩策略以及在Android上的运用进行讲解。

阅读全文 »
zhengxiaoyong

Android图片压缩框架-Tiny

发表于 2017-04-23 | 分类于 开源框架 | | 阅读次数

目的

为了简化对图片压缩的调用,提供最简洁与合理的api压缩逻辑,对于压缩为Bitmap根据屏幕分辨率动态适配最佳大小,对于压缩为File优化底层libjpeg的压缩,整个图片压缩过程全在压缩线程池中异步压缩,结束后分发回UI线程。

支持的压缩类型

Tiny图片压缩框架支持的压缩数据源类型:

1、Bytes
2、File
3、Bitmap
4、Stream
5、Resource
6、Uri(network、file、content)

Tiny支持单个数据源压缩以及批量压缩,支持的压缩类型:

1、数据源—>压缩为Bitmap
2、数据源—>压缩为File
3、数据源—>压缩为File并返回压缩后的Bitmap
4、批量数据源—>批量压缩为Bitmap
5、批量数据源—>批量压缩为File
6、批量数据源—>批量压缩为File并返回压缩后Bitmap

阅读全文 »
zhengxiaoyong

简述RTMPDump与编译移植

发表于 2016-11-20 | 分类于 流媒体 | | 阅读次数

RTMPDump概述

RTMPDump主页,RTMPDump库主要包含三部分:

1、一个基本的客户端程序
2、两个服务器程序(rtmpsrv、rtmpsuck)
3、一个支持rtmp协议的库—librtmp

下载RTMPDump最新源码,可以通过git拉取master分支上的最新代码:

1
git clone git://git.ffmpeg.org/rtmpdump

或者下载以前版本的代码—Download old version

下面主要介绍librtmp和librtmp的编译

librtmp概述

librtmp库提供了大量客户端函数和少部分的服务器端的函数用来支持RTMP、RTMPT(RTMP使用Http通道),RTMPE(加密的RTMP),RTMPS(基于SSL/TLS的RTMP)和RTMPTE、RTMPTS(使用Http通道的加密和基于SSL/TLS的RTMP)协议

使用librtmp库进行的流媒体交互都是使用FLV封包格式进行传输的,当然编码不限定,不过为了拉流端同时也支持HLS协议,最好使用H264编码视频和AAC编码音频数据

阅读全文 »
zhengxiaoyong

初识FFmpeg编译那些事

发表于 2016-11-13 | 分类于 流媒体 | | 阅读次数

FFmpeg简介

FFMPEG是一套具有非常强大功能的多媒体处理工具,它几乎涵盖了目前所有主流的多媒体数据封装格式、多媒体传输协议以及音视频编解码器,并且支持多媒体后处理,视频色彩转换、滤镜和缩放等,也支持众多主流的协议:HTTP、RTP、RTSP、RTMP、HLS、UDP等
安装可以通过Homebrew

FFmpeg它主要含有以下几个核心库:

1、libavcodec-提供了更加全面的编解码实现的合集
2、libavformat-提供了更加全面的音视频容器格式的封装和解析以及所支持的协议
3、libavutil-提供了一些公共函数
4、libavfilter-提供音视频的过滤器,如视频加水印、音频变声等
5、libavdevice-提供支持众多设备数据的输入与输出,如读取摄像头数据、屏幕录制
6、libswresample,libavresample-提供音频的重采样工具
7、libswscale-提供对视频图像进行色彩转换、缩放以及像素格式转换,如图像的YUV转换
8、libpostproc-多媒体后处理器

以及包含以下几个工具:

1、ffmpeg-一个流媒体的编解码、格式转换以及多媒体流的内容处理工具
2、ffplay-一个使用FFmpeg编解码的播放器
3、ffprobe-一个多媒体分析工具
4、ffserver-一个流多媒体服务器

阅读全文 »
123
郑晓勇

郑晓勇

21 日志
5 分类
58 标签
RSS
Github
© 2016 - 2019 郑晓勇