Android recovery模式为何物?
关于这个问题, baidu上已经有无数的答案。不理解的朋友先补习一下。
从纯技术角度来讲, recovery和android本质上是两个独立的rootfs, 仅仅是recovery这个rootfs存在的意义就是为android这个rootfs服务,因此被解释为Android系统的一部分。
recovery作为一个简单的rootfs, 提供了很有限的几个功能,仅仅包括了几个简单的库,UI的显示採用的是直接刷framebuffer的形式,作为android framework及app层的码农,对这样的形式相对陌生,特抽点时间梳理了一番。
首先,浏览一下reocvery的main函数代码中UI相关的语句
main(int argc, char **argv) { ...... Device* device = make_device(); ui = device->GetUI(); gCurrentUI = ui; ui->Init(); ui->SetLocale(locale); ui->SetBackground(RecoveryUI::NONE); if (show_text) ui->ShowText(true); ...... if (status != INSTALL_SUCCESS || ui->IsTextVisible()) { prompt_and_wait(device, status); } ...... }
1、首先新建了一个Device类的对象, Device类封装了一些操作,包含UI的操作
2、调用Device类的GetUI()返回一个DefaultUI对象,recovery中涉及到三个UI类,三个类之间为继承关系,分别为DefaultUI、
ScreenRecoveryUI、RecoveryUI
3、调用DefaultUI类的Init(), DefaultUI类没有Init()方法,因此将调用它的父类ScreenRecoveryUI的Init()
4、同理。调用ScreenRecoveryUI类的SetLocale()来标识几个比較特别的区域
5、同理。调用ScreenRecoveryUI类的SetBackground()设置初始状态的背景图
6、显示recovery的主界面,即一个选择菜单
void ScreenRecoveryUI::Init() { gr_init(); gr_font_size(&char_width, &char_height); text_col = text_row = 0; text_rows = gr_fb_height() / char_height; if (text_rows > kMaxRows) text_rows = kMaxRows; text_top = 1; text_cols = gr_fb_width() / char_width; if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1; LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]); backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; LoadBitmap("icon_error", &backgroundIcon[ERROR]); backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR]; LoadBitmap("progress_empty", &progressBarEmpty); LoadBitmap("progress_fill", &progressBarFill); LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]); LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]); LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]); LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); int i; progressBarIndeterminate = (gr_surface*)malloc(indeterminate_frames * sizeof(gr_surface)); for (i = 0; i < indeterminate_frames; ++i) { char filename[40]; // "indeterminate01.png", "indeterminate02.png", ... sprintf(filename, "indeterminate%02d", i+1); LoadBitmap(filename, progressBarIndeterminate+i); } if (installing_frames > 0) { installationOverlay = (gr_surface*)malloc(installing_frames * sizeof(gr_surface)); for (i = 0; i < installing_frames; ++i) { char filename[40]; // "icon_installing_overlay01.png", // "icon_installing_overlay02.png", ... sprintf(filename, "icon_installing_overlay%02d", i+1); LoadBitmap(filename, installationOverlay+i); } } else { installationOverlay = NULL; } pthread_create(&progress_t, NULL, progress_thread, NULL); RecoveryUI::Init(); }
1、gr_init() 初始化图形设备,分配Pixelflinger库渲染的内存
2、gr_font_size() 将字体相应的surface长宽赋值给char_width和char_height
3、LoadBitmap() 将png生成surface, 每一个png图片相应一个surface, 全部surface存放在一个数组中
4、LoadLocalizedBitmap() 将区域文字所在的图片中的text信息依据当前的locale提取出来,生成相应的surface, 所以
surface也存放在一个数组中
6、pthread_create(&progress_t, NULL, progress_thread, NULL)
创建一个线程,该线程的任务是一个死循环,在该循环中不停
地检測currentIcon以及progressBarType来决定是不是要更新进度条。
7、调用RecoveryUI的Init()。初始化输入事件处理。
void ScreenRecoveryUI::SetLocale(const char* locale) { if (locale) { char* lang = strdup(locale); for (char* p = lang; *p; ++p) { if (*p == '_') { *p = '