Delphi Android程序启动过程
activity->callbacks->onStart = onStart;
activity->instance = android_app_create(activity, savedState, savedStateSize);
// --------------------------------------------------------------------
// Native activity interaction (called from main thread)
// -------------------------------------------------------------------- function android_app_create(activity: PANativeActivity; savedState: Pointer; savedStateSize: size_t): Pandroid_app;
var
android_app: Pandroid_app;
PipeDescriptors: TPipeDescriptors;
attr: pthread_attr_t;
thread: pthread_t;
begin
android_app := Pandroid_app(__malloc(SizeOf(TAndroid_app)));
FillChar(android_app^, SizeOf(TAndroid_app), );
android_app^.activity := activity; pthread_mutex_init(android_app^.mutex, nil);
pthread_cond_init(android_app^.cond, nil);
if savedState <> nil then
begin
android_app^.savedState := __malloc(savedStateSize);
android_app^.savedStateSize := savedStateSize;
Move(PByte(savedState)^, PByte(android_app^.savedState)^, savedStateSize);
end; pipe(PipeDescriptors);
android_app^.msgread := PipeDescriptors.ReadDes;
android_app^.msgwrite := PipeDescriptors.WriteDes; pthread_attr_init(attr);
pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
pthread_create(thread, attr, @android_app_entry, android_app); pthread_mutex_lock(android_app^.mutex);
while android_app^.running = do
pthread_cond_wait(android_app^.cond, android_app^.mutex);
pthread_mutex_unlock(android_app^.mutex); Result := android_app;
end;
function android_app_entry(param: Pointer): Pointer; cdecl; // Delphi: init system unit and RTL.
procedure SystemEntry;
type
TMainFunction = procedure;
var
DlsymPointer: Pointer;
EntryPoint: TMainFunction;
begin
DlsymPointer := dlsym(RTLD_DEFAULT, '_NativeMain');
if DlsymPointer <> nil then
begin
EntryPoint := TMainFunction(DlsymPointer);
EntryPoint;
end;
end; var
android_app: Pandroid_app;
looper: PALooper;
begin
android_app := Pandroid_app(param);
android_app^.config := AConfiguration_new;//创建应用程序config
AConfiguration_fromAssetManager(android_app^.config, android_app^.activity^.assetManager); //从主线程获取消息用
android_app^.cmdPollSource.id := LOOPER_ID_MAIN;
android_app^.cmdPollSource.app := android_app;
android_app^.cmdPollSource.process := @process_cmd;//设置处理cmd的命令的函数
android_app^.inputPollSource.id := LOOPER_ID_INPUT;
android_app^.inputPollSource.app := android_app;
android_app^.inputPollSource.process := @process_input;//输入事件处理的函数 //创建一个looper消息循环,用来抓取消息
looper := ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
ALooper_addFd(looper, android_app^.msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, nil, @android_app^.cmdPollSource);
android_app^.looper := looper; pthread_mutex_lock(android_app^.mutex);
android_app^.running := ; //设置,让线程从等待开启运行中退出,也就是从android_app_create中退出
pthread_cond_broadcast(android_app^.cond);
pthread_mutex_unlock(android_app^.mutex); { Delphi: this will initialize System and any RTL related functions, call unit initialization sections and then
project main code, which will enter application main loop. This call will block until the loop ends, which is
typically signalled by android_app^.destroyRequested. }
SystemEntry;//这里才是调用了工程文件的Begin End之间的代码,是Delphi的一个封装,实际上,在Android Native中调用的是android_main(android_app);然后再这里执行一些消息的处理,等待程序运行结束
{ This place would be ideal to call unit finalization, class destructors and so on. }
// Halt; android_app_destroy(android_app);//销毁android_app退出线程。这里实际上才是Android程序的终结 Result := nil;
end;
function android_app_read_cmd(android_app: Pandroid_app): ShortInt; cdecl;
var
cmd: ShortInt;
begin
Result := -;
if __read(android_app^.msgread, @cmd, sizeof(cmd)) = SizeOf(cmd) then
begin
case cmd of
APP_CMD_SAVE_STATE:
free_saved_state(android_app);//释放当前的保存状态
end;
Result := cmd;
end;
end; procedure android_app_pre_exec_cmd(android_app: Pandroid_app; cmd: ShortInt); cdecl; //准备执行命令状态
begin
case cmd of
APP_CMD_INPUT_CHANGED:
begin
pthread_mutex_lock(android_app^.mutex);
if android_app^.inputQueue <> nil then
AInputQueue_detachLooper(android_app^.inputQueue);
android_app^.inputQueue := android_app^.pendingInputQueue;
if android_app^.inputQueue <> nil then
AInputQueue_attachLooper(android_app^.inputQueue, android_app^.looper, LOOPER_ID_INPUT, nil,
@android_app^.inputPollSource);
pthread_cond_broadcast(android_app^.cond);
pthread_mutex_unlock(android_app^.mutex);
end; APP_CMD_INIT_WINDOW:
begin
pthread_mutex_lock(android_app^.mutex);
android_app^.window := android_app^.pendingWindow;
pthread_cond_broadcast(android_app^.cond);
pthread_mutex_unlock(android_app^.mutex);
end; APP_CMD_TERM_WINDOW:
pthread_cond_broadcast(android_app^.cond); APP_CMD_RESUME, APP_CMD_START, APP_CMD_PAUSE, APP_CMD_STOP:
begin
pthread_mutex_lock(android_app^.mutex);
android_app^.activityState := cmd;
pthread_cond_broadcast(android_app^.cond);
pthread_mutex_unlock(android_app^.mutex);
end; APP_CMD_CONFIG_CHANGED:
AConfiguration_fromAssetManager(android_app^.config, android_app^.activity^.assetManager); APP_CMD_DESTROY:
android_app^.destroyRequested := ;
end;
end; procedure android_app_post_exec_cmd(android_app: Pandroid_app; cmd: ShortInt); cdecl;
begin
case cmd of
APP_CMD_TERM_WINDOW:
begin
pthread_mutex_lock(android_app^.mutex);
android_app^.window := nil;
pthread_cond_broadcast(android_app^.cond);
pthread_mutex_unlock(android_app^.mutex);
end; APP_CMD_SAVE_STATE:
begin
pthread_mutex_lock(android_app^.mutex);
android_app^.stateSaved := ;
pthread_cond_broadcast(android_app^.cond);
pthread_mutex_unlock(android_app^.mutex);
end; APP_CMD_RESUME:
{ Delphi: It is unclear why this line is necessary in original AppGlue, but it prevents FireMonkey applications
from recovering saved state. FireMonkey recovers saved state usually after APP_CMD_INIT_WINDOW, which happens
much later after CMD_RESUME. }
{ free_saved_state(android_app) };
end;
end; procedure process_cmd(app: Pandroid_app; source: Pandroid_poll_source); cdecl;
var
cmd: ShortInt;
begin
cmd := android_app_read_cmd(app);//先读取命令
android_app_pre_exec_cmd(app, cmd);//准备命令
if Assigned(app^.onAppCmd) then //程序内部的指令处理
app^.onAppCmd(app, cmd);
android_app_post_exec_cmd(app, cmd);//执行处理
end;
这些代码将在Android消息循环中处理调用
然后程序进入工程文件的Begin End之间,先进入SysInit.pas单元的_InitExe,然后会调用GetThisModuleHandle,这个会调用dlopen(Info.dli_fname, RTLD_LAZY)就是相当于加载Windows的DLL,会先加载(Lib+程序名.so)获得当前句柄,然后dlClose关闭,最后程序以这个工程的库句柄作为程序的Hinstance,也就是说我们的好多资源应该会都打包到这个so中去,最后如果是Android环境,会调用_StartExe,来启动程序,_StartExe中会调用InitUnits来初始化一些单元,这里就会调用程序所引用到的各个单元的Initialization中的内容,在这个过程中会初始化FMX.PlatForm这个跨平台单元的TPlatformServices类库,本库是跨平台单元服务管理,然后就会调用FMX.PlatForm下的initialization,里面的RegisterCorePlatformServices会根据选择的平台来判定到底调用哪个平台下的RegisterCorePlatformServices,这个判定通过编译预处理指令在Implemention下的Use中
procedure TApplication.Run;
var
AppService: IFMXApplicationService;
begin
{$IFNDEF ANDROID}
AddExitProc(DoneApplication);
{$ENDIF}
FRunning := True;
try
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationService, AppService) then
AppService.Run;
finally
FRunning := False;
end;
end;
procedure TPlatformAndroid.Run;
begin
{ Although calling this routine is not really necessary, but it is a way to ensure that "Androidapi.AppGlue.pas" is
kept in uses list, in order to export ANativeActivity_onCreate callback. }
app_dummy; repeat
InternalProcessMessages;
until FAndroidApp^.destroyRequested <> ;
end;
Delphi Android程序启动过程的更多相关文章
- Android程序启动过程深入解析
当按下Android设备电源键时究竟发生了什么? Android的启动过程是怎么样的? 什么是Linux内核? 桌面系统linux内核与Android系统linux内核有什么区别? 什么是引导装载程序 ...
- Zygote和System进程的启动过程、Android应用进程启动过程
1.基本过程 init脚本的启动Zygote Zygote进程的启动 System进程的启动 Android应用进程启动过程 2.init脚本的启动 +------------+ +-------+ ...
- Envoy 源码分析--程序启动过程
目录 Envoy 源码分析--程序启动过程 初始化 main 入口 MainCommon 初始化 服务 InstanceImpl 初始化 启动 main 启动入口 服务启动流程 LDS 服务启动流程 ...
- Android应用程序启动过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程 ...
- Android 应用程序启动过程源代码分析
本文转自:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程序的Activity的启动过程.在And ...
- Android应用程序启动过程(二)分析
本文依据Android6.0源码,从点击Launcher图标,直至解析到MainActivity#OnCreate()被调用. Launcher简析 Launcher也是个应用程序,不过是个特殊的应用 ...
- Delphi开发 Android 程序启动画面简单完美解决方案
原文在这里 还是这个方法好用,简单!加上牧马人做的自动生成工具,更是简单. 以下为原文,向波哥敬礼! 前面和音儿一起研究 Android 下启动画面的问题,虽然问题得到了解决,但是,总是感觉太麻烦,主 ...
- Android应用程序启动过程(一)总结
一.App启动方式 1,冷启动 冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用. 冷启动的特点:因为系统会重新创建一个新的进程分配给它,所以会创建和初始化App ...
- 比较windows phone程序启动和android程序启动原理
windows phone 程序是如何启动的了,他和android程序有什么区别,我们重点从native code 层面来分析 在windows phone 程序启动的时候是: 在XAML中使用应用程 ...
随机推荐
- MySQL大小写敏感说明
Linux环境下,不是windows平台下.区别很大.注意. 一图胜千言 mysql> show create table Ac; +-------+-------------------- ...
- Windows 8.1 应用再出发 - 几种更新的控件
Windows 8.1 除了新增了很多很有用的控件外,还对一些控件做出了更新.接下来我们一起对这些更新的控件一一做出讲解. 1. FlipView 更新 翻转视图控件,在应用中常用作图片等内容的翻页/ ...
- JSP标准标签库(JSTL)之核心标签(下)
前面记录了核心标签的前几种,现在来接着记录. 七.<c:import>标签 使用<c:import>标签可以包含一个FTP服务器中不同的网页内容.语法格式: <c:i ...
- SQL Server In-Memory OLTP 无损PPT分享
我在今年DTCC上SQL Server内存数据库分享 PPT.感兴趣的朋友可以看下,无闩锁的数据结构使得热区问题成为过去,并行很好的维护了CPU Cache的命中率,Native代码执行使得CPU流水 ...
- C#设计模式(9)——装饰者模式(Decorator Pattern)
一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...
- Linux上成功编译CoreCLR源代码
>>Build日期:2015-2-5下午(编译失败). 开始Linux发行版用的是CentOS 6.5,操作步骤: 1)配置git: git config --global http.ss ...
- C++ WIN32控制台异常关闭回调函数
/* This is an example of the SetConsoleCtrlHandler function that is used to install a control handle ...
- 如何给input[file]定义cursor
来源:http://stackoverflow.com/questions/1537223/change-cursor-type-on-input-type-file Simple question. ...
- CSS中一些不经意的细节问题1
CSS这样的语法,细节问题非常多,往往一些难以处理的问题,有可能是一些细节问题不到位,所以先记下一些,留给以后自己看看. 1.line-height:150%与line-height:1.5 的区别 ...
- iOS开发-代理模式
代理模式有的时候也被称之为委托模式,但是实际上两者是有分别的,代理模式为另一个对象提供一个替身或占位符访问这个对象,代理对象和控制访问对象属于同一类,委托对象和对象不一定属于同一类.两者都可以控制类的 ...