最近在作一个在recovery中显示文字的工作,所以对这块研究较多,现在把研究的一点新的结果分享出来,如果有什么错误也欢迎大家在下面评论。

 

Android的Recovery中,利用 boottable/recovery下的minui库作为基础,采用的是直接存取framebuffer的方式,来完成recovery中所需的各种UI的绘制。

在recovery的源码中,跟ui显示相关的代码的大致结构为:

1 boottable/recovery下的 ui.h , ui.cpp, screen_ui.h,screen_ui.cpp,以及 mi_screen_ui.h,**_screen_ui.cpp,

这部分的主要作用是:

1.1 定义并实现几个类,如ScreenRecoveryUIScreenRecoveryUIRecoveryUI,这几个类由抽象到具体一层层继承下来,在recovery.cppmain中实例化并被使用

1.2 将minui库里resources.cpp,graphics.cpp提供的基本api封装到几个方法中,这几个方法在类中基本被按功能划分,单独负责一个ui单元的显示,如draw_background_locked、draw_battery_locked、draw_logo_locked、draw_progress_locked、draw_progressbar_locked、draw_state_locked等

1.3 之后再将这些方法进一步按照设计需求组合,实现了一些完成更多功能的方法,如SetBackground,ShowProgress

2 boottable/recovery/minui下的resources.cpp,graphics.cpp

其中resources.cpp提供的api主要用于图片资源的读取和加载,graphics.cpp负责具体完成各类ui的绘制

3 recovery下面根据分辨率不同保存的图片资源,如boottable/recovery/res-xxhdpi等

 

下面我们以android6.0的原生代码为例,对在进入recovery的过程中,各类ui被加载并显示的过程来具体分析

由于之前所述,recovery的UI已经把大部分实现细节放在了screen_ui.cpp等文件中,因此在recovery的main中,要完成ui显示,所需要的操作主要可分为如下几步:

Device* device = make_device();

ui = device->GetUI();

ui->SetLocale(locale);

ui->Init();

ui->SetBackground(RecoveryUI::NONE);

首先在reocvery.cpp的main中,全局变量ui通过Device类的GetUI()返回,由于RecoveryUI为虚基类,因此依次实际执行的是ScreenRecoveryUI中的SetLocale()标识所属区域,保存在全局变量locale中,这个值在原声recovery中显示国际化里的不同地域的文字时起到了重要作用。

SetLocale负责读取系统之前保存的地区信息,并复制给recovery中的全局变量locale。具体过程是先从/cahe/recpvery/command文件中读取, command文件中会设置locale的命令如"-- locale =zh_CN“,如果没有传入locale, 初始化过程中会尝试从/cache/recovery/last_locale中读取locale, 如果该文件也没有,则locale不会被赋值,就默认用English。

然后在ScreenRecoveryUI的Init()中,调用gr_init() 初始化图形设备,加载之后所需要的各种图片资源,将其保存到各类GRSurface结构体中,具体为调用LoadBitmap,将每个png图片存放在一个数组GRsurface数组中,调用LoadLocalizedBitmap,将区域文字所在的图片中的text信息根据当前的locale提取出来,生成对应的surface。在最后,调用pthread_create(&progress_t, NULL, progress_thread, NULL) 创建一个线程,该线程的任务是一个死循环,在该循环中不停检测currentIcon以及progressBarType,以此来决定是否更新进度条

调用ScreenRecoveryUI类的SetBackground()设置初始显示背景,其中重点是update_screen_locked,这个函数的主要作用是刷新屏幕背景。在Recovery中负责显示的部分将会一直调用update_screen_locked或者 update_progress_locked,其中update_progress_locked用来更新进度条。

void ScreenRecoveryUI::update_screen_locked()

{

    draw_screen_locked();

    gr_flip();

}

主要包含两个操作,一是更新screen, 二是切换前后buffer。

在draw_screen_locked中,将整个渲染buffer填充为黑色,然后计算背景surface的长宽,文字surface的长宽,在调用minui库,计算出整个framebuffer的长宽,结合framebuffer的长宽计算出背景surface以及文字surface显示的坐标,

计算出这些数据后,就可以调用png库进行渲染。

同理,draw_progress_locked函数的原理与 update_screen_locked函数类似, 最终是将进度条的surface输出到渲染buffer。

总体而言,recovery中上层通过调用minui库实现了图形的描绘以及固定大小的文字显示,minui库调用了png库来实现最后的渲染。

 

下一篇里我打算介绍google在recovery中根据地区信息的不同,来显示国际化文字的一个机制。

更多相关文章

  1. ReactNative Android 实现加载本地图片
  2. Android Tween动画之RotateAnimation实现图片不停旋转
  3. android:scaleType="matrix"布局文件加载图片时候的显示方式
  4. android Matrix处理图片原理及方法整理
  5. 全屏显示布局随机图片的显示
  6. Android TextView(EditView)文字底部或者中间 加横线
  7. android TextView 的圆角背景
  8. android 图片内存溢出
  9. Android实现图片随意拖动、缩放

随机推荐

  1. 技术解析|如何绘制密度分布图
  2. 动画:面试算法之重建二叉树
  3. 不能再简单了|手把手教你爬取美国疫情实时
  4. 一次爬美团网美食团购的经历
  5. 那些年,我在大学接过的外包项目
  6. JDBC自定义工具类(properties配置文件方式
  7. COVID-19每日据整理|04-02
  8. 怎样绘制漂亮的统计图表|第一期
  9. 手把手教你调试代码并使用Echarts进行数
  10. COVID-19每日数据|04-03