标签:
// -------------------------------------------------------------------- // 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), 0); 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 = 0 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 := 1; //设置,让线程从等待开启运行中退出,也就是从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 := -1; 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 := 1; 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 := 1; 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 <> 0; end;
标签:
原文地址:http://www.cnblogs.com/findumars/p/5379551.html