android_app c++框架

笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述android_app c++框架相关的知识,希望能为你提供帮助。
找遍了全网,没有一个完整的可用的框架。ndk自带的android_native_app_glue确实不太好用,闭关几天,写出了一个框架。完全的消息队列调用,目前测试的主体框架是没有什么问题了,程序入口还是android_main。调用过程:

void android_main(android_app* app) { //APP_LOG("main : 程序启动"); //设置消息回调函数,就一个,整体和win32编程差不多了。 app-> onEvent = on_app_event; //循环等待事情以进行处理。 while (app-> running){//app处于运行状态 app-> process_message(); //处理消息主函数 if(!app-> pause()){ //draw_frame(); //绘制我们的游戏,相当于MainLoop事件 } else{ //APP_LOG("PAUSE"); } } //APP_LOG("main : 程序结束"); }

 
【android_app c++框架】消息事件结构:
#pragma pack(push, 1) struct APP_EVENT { int id; union{ void* data; struct{//input motion int16_t x, y, z, w; }; struct{//input_keyboard int32_t key; int32_t flag; }; struct{//ARect int16_t left, top, right, bottom; }; }; }; #pragma pack(pop)


主消息处理函数,完全防win32编程设计,当然,事件处理做的还不够全面。现在只是初期框架,但这个框架已经比glue那个清晰多了。
主消息回调函数: 
void on_app_event(android_app* app, APP_EVENT& event) { switch(event.id) { case APP_START://activity启动 break; case APP_STOP://停止 break; case APP_RESUME://返回 break; case APP_PAUSE://暂停 break; case APP_DESTROY://销毁退出 break; case APP_SAVE://保存状态 break; case APP_WINDOW_CREATE://窗口创建,app-> window有效 break; case APP_WINDOW_CLOSE://窗口销毁 break; case APP_WINDOW_ACTIVATE://窗口获得焦点 break; case APP_WINDOW_DEACTIVATE://窗口失去焦点 break; case APP_WINDOW_RESIZE://窗口大小改变 break; case APP_TOUCH_DOWN://触摸按下 //这三个事件,都使用event.x, event.y作为坐标 //event.z代表pointerid break; case APP_TOUCH_MOVE://触摸滑动 break; case APP_TOUCH_UP: break; default: //APP_LOG("unknow msg:%d", cmd); break; } } 

 
ndk的activity入口函数其实是:
void ANativeActivity_onCreate(ANativeActivity* activity, void*  savedState, size_t savedStateSize);
这个函数由主进程调用,主进程创建一个activity,通知native库创建环境并处理,如果这个函数不返回,app就会卡死无响应。所以我们native库的过程要在一个新的线程里面处理。直接使用主线程的回调也不是不可以,但无法处理MainLoop这个事件,这个事件主线程没给。如果新建一个线程,如何处理主线程回调的事件,就是一个根本的问题。glue库用了pipe,并大把大把的mutex lock处理。下面这个库,把lock基本都去掉了,不再使用ALooper进行消息处理。主线程和线程之间的通信还是用的pipe,因为简单易用。
方式很简单:(执行标准)
一:所有ANativeActivity_onCreate里面指定的回调函数,执行过程都在主线程里面,这个我们要打包。用APP_EVENT把事件封装,通过pipe发送到我们线程的事件队列,不对android_app内部数据进行操作。
二:android_main()过程里面,循环执行process_message(),进行事件处理。process_message()的执行过程就是,从pipe里面读取打包的APP_EVENT,并进行预处理、回调执行、后续处理。
三:所有事件方法,过程尽量保证清晰,可读性高。
 
目前库封装了部分输入交互操作,后续会继续封装。也欢迎大家评论,有用的着的尽可拿去用,public domain协议!
 

 
1 #ifndef ANDROID_APP_HPP 2 #define ANDROID_APP_HPP 3 4 #include < errno.h> 5 #include < fcntl.h> 6 #include < poll.h> 7 #include < pthread.h> 8 #include < sched.h> 9 #include < stdlib.h> 10 #include < string.h> 11 #include < unistd.h> 12 #include < sys/resource.h> 13 14 #include< sys/ioctl.h> 15 16 #include < jni.h> 17 18 #include < android/configuration.h> 19 #include < android/looper.h> 20 #include < android/native_activity.h> 21 #include < android/log.h> 22 23 #include "pipefile.hpp"//封装的pipe操作,之后会发表 24 25 #include < cgl/public.h> //#define null NULL 26 #include < cgl/thread/mutex.hpp> //封装的锁操作,之后发表 27 28 using namespace cgl; 29 30 #define ANDROID_APP_LOG(...) ((void)__android_log_print(ANDROID_LOG_INFO, "android_app", __VA_ARGS__)) 31 #define ANDROID_APP_ERROR(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "android_app", __VA_ARGS__)) 32 33 #define ANDROID_APP_DEBUG//debug 模式 34 35 #ifdef ANDROID_APP_DEBUG 36 #define ANDROID_APP_LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "android_app", __VA_ARGS__)) 37 #else 38 #define ANDROID_APP_LOGV(...) ((void)0) 39 #endif 40 41 //android app events 42 enum ANDROID_APP_EVENT 43 { 44APP_START, 45APP_STOP, 46APP_RESUME, 47APP_PAUSE, 48APP_DESTROY, 49APP_SAVE, 50APP_CONFIG, 51APP_LOW_MEMORY, 52 53APP_WINDOW_CREATE,//set app.window 54APP_WINDOW_CLOSE,//reset app.window 55APP_WINDOW_ACTIVATE, 56APP_WINDOW_DEACTIVATE, 57APP_WINDOW_RESIZE, 58APP_WINDOW_RECT_CHANGED, 59APP_WINDOW_PAINT, 60 61APP_INPUT,//set app.inputQueue 62APP_TOUCH_DOWN, 63APP_TOUCH_UP, 64APP_TOUCH_MOVE, 65 66APP_KEY_UP, 67APP_KEY_DOWN, 68APP_KEY_PRESS 69 }; 70 71 #pragma pack(push, 1) 72 struct APP_EVENT 73 { 74int id; 75union{ 76void* data; 77struct{//input motion 78int16_t x, y, z, w; 79}; 80struct{//input_keyboard 81int32_t key; 82int32_t flag; 83}; 84struct{//ARect 85int16_t left, top, right, bottom; 86}; 87}; 88 }; 89 #pragma pack(pop) 90 91 class android_app; 92 93 extern void android_main(android_app* app); 94 95 void android_app_post_event(android_app* app, const APP_EVENT& event); 96 void android_app_post_event(android_app* app, int id); 97 98 class android_app 99 { 100 public: 101ANativeActivity* activity; 102AConfiguration* config; 103ALooper* looper; 104ANativeWindow* window; 105 106void* savedState; 107size_t savedStateSize; 108int stateSaved; 109 110void* userData; 111 112void (*onEvent)(android_app* app, APP_EVENT& event); 113 114int activityState; 115bool running; 116 public: 117pthread_t thread; 118mutex_t mutex; 119cond_tcond; 120 public: 121io::pipefile message; 122AInputQueue* inputQueue; 123int destroyed; 124 public: 125android_app() : activity(null), config(null), looper(null), window(null), 126savedState(null), savedStateSize(0), stateSaved(0), 127userData(null), 128onEvent(null), 129activityState(0), 130thread(), mutex(), cond(), 131message(), 132inputQueue(null), 133destroyed(0) 134{ 135running = false; 136} 137 138void dispose(); 139 140bool pause()const 141{ 142return activityState == APP_PAUSE; // || activityState == APP_STOP; 143} 144 145int process_message() 146{ 147APP_EVENT event; 148int bytes; 149ioctl(message.in(), FIONREAD, & bytes); 150while(bytes){ 151if(this-> read_event(event)){ 152//ANDROID_APP_LOGV("process message %d - %p", event.id, event.data); 153this-> process_begin(event); 154if(this-> onEvent){ 155this-> onEvent(this, event); 156} 157this-> process_end(event); 158} 159ioctl(message.in(), FIONREAD, & bytes); 160} 161ALooper_pollAll(0, NULL, NULL, NULL); 162//如果传感器有数据,立即处理。ident == USER 163//ANDROID_APP_LOG("pollAll %d", ident); 164return 0; 165} 166 167 public://log 168void print_config(); 169 public: 170void cond_wait() 171{ 172cond.wait(mutex); 173} 174 175 public: 176static int on_input(int fd, int events, void* data); 177int on_input_event(AInputEvent* event); 178 private: 179bool read_event(APP_EVENT& event); 180void process_begin(APP_EVENT& event); 181void process_end(APP_EVENT& event); 182 183int on_input_motion(AInputEvent* event); 184int on_input_keyboard(AInputEvent* event); 185 }; 186 187 void free_saved_state(android_app* app) 188 { 189//auto_lock lock(app-> mutex); 190if (app-> savedState != NULL) { 191free(app-> savedState); 192app-> savedState = NULL; 193app-> savedStateSize = 0; 194} 195 } 196 197 void android_app::print_config() 198 { 199char lang[2], country[2]; 200AConfiguration_getLanguage(config, lang); 201AConfiguration_getCountry(config, country); 202 203ANDROID_APP_LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d " 204"keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d " 205"modetype=%d modenight=%d", 206AConfiguration_getMcc(config), 207AConfiguration_getMnc(config), 208lang[0], lang[1], country[0], country[1], 209AConfiguration_getOrientation(config), 210AConfiguration_getTouchscreen(config), 211AConfiguration_getDensity(config), 212AConfiguration_getKeyboard(config), 213AConfiguration_getNavigation(config), 214AConfiguration_getKeysHidden(config), 215AConfiguration_getNavHidden(config), 216AConfiguration_getSdkVersion(config), 217AConfiguration_getScreenSize(config), 218AConfiguration_getScreenLong(config), 219AConfiguration_getUiModeType(config), 220AConfiguration_getUiModeNight(config)); 221 } 222 223 #ifdef ANDROID_APP_DEBUG 224 const char* input_motion_name(int action) 225 { 226switch(action){ 227case AMOTION_EVENT_ACTION_DOWN://触摸按下 228return "MOTION_DOWN"; 229case AMOTION_EVENT_ACTION_UP://触摸弹起 230return "MOTION_UP"; 231case AMOTION_EVENT_ACTION_MOVE://触摸移动 232return "MOTION_MOVE"; 233case AMOTION_EVENT_ACTION_CANCEL: 234return "MOTION_CACEL"; 235case AMOTION_EVENT_ACTION_OUTSIDE: 236return "MOTION_OUTSIDE"; 237default: 238break; 239} 240return null; 241 } 242 #endif 243 244 int android_app::on_input_motion(AInputEvent* inputEvent) 245 { 246APP_EVENT event; 247 248//motion source 249switch(AInputEvent_getSource(inputEvent)) 250{ 251case AINPUT_SOURCE_TOUCHSCREEN: 252//消息来源于触摸屏 253break; 254case AINPUT_SOURCE_TRACKBALL: 255//消息来源于trackball,轨迹球 or 鼠标? 256break; 257default: 258break; 259} 260 261switch(AMotionEvent_getAction(inputEvent)) 262{ 263case AMOTION_EVENT_ACTION_DOWN://触摸按下 264event.id = APP_TOUCH_DOWN; 265break; 266case AMOTION_EVENT_ACTION_UP://触摸弹起 267event.id = APP_TOUCH_UP; 268break; 269case AMOTION_EVENT_ACTION_MOVE://触摸移动 270event.id = APP_TOUCH_MOVE; 271break; 272case AMOTION_EVENT_ACTION_CANCEL: 273break; 274case AMOTION_EVENT_ACTION_OUTSIDE: 275break; 276default: 277break; 278} 279 280//getX()是表示view相对于自身左上角的x坐标, 281//getRawX()是表示相对于物理屏幕左上角的x坐标值 282//AMotionEvent_getXPrecision 283 284size_t count = AMotionEvent_getPointerCount(inputEvent); 285for(int i=0; i < count; ++i){ 286event.x = AMotionEvent_getX(inputEvent, i); 287event.y = AMotionEvent_getY(inputEvent, i); 288event.z = i; 289 290if(this-> onEvent){ 291this-> onEvent(this, event); 292} 293 294#ifdef ANDROID_APP_DEBUG 295ANDROID_APP_LOGV("%s : index=%d, pointer=%d, flag=%d state=%d x=%d, y=%d ", 296input_motion_name(AMotionEvent_getAction(inputEvent)), 297i, 298AMotionEvent_getPointerId(inputEvent, i), 299AMotionEvent_getFlags(inputEvent), 300AMotionEvent_getMetaState(inputEvent), 301event.x, event.y); 302#endif 303} 304return this-> onEvent ? 1 : 0; 305 } 306 307 int android_app::on_input_keyboard(AInputEvent* inputEvent) 308 { 309//键盘控制键管用,字符键不管用 310ANDROID_APP_LOGV("keyinput : action=%d flag=%d keycode=%d", 311AKeyEvent_getAction(inputEvent), 312AKeyEvent_getFlags(inputEvent), 313AKeyEvent_getKeyCode(inputEvent)); 314 315APP_EVENT event; 316switch(AKeyEvent_getAction(inputEvent)){ 317case AKEY_STATE_UNKNOWN: 318break; 319case AKEY_STATE_UP: 320event.id = APP_KEY_UP; 321break; 322case AKEY_STATE_DOWN: 323event.id = APP_KEY_DOWN; 324break; 325case AKEY_STATE_VIRTUAL: 326event.id = APP_KEY_PRESS; 327break; 328default: 329break; 330} 331 332event.key = AKeyEvent_getKeyCode(inputEvent); 333event.flag = AKeyEvent_getFlags(inputEvent); 334if(this-> onEvent){//if processed, reutrn 1 335this-> onEvent(this, event); 336return 1; 337} 338 339return 0; 340 } 341 342 // input event callback 343 int android_app::on_input_event(AInputEvent* inputEvent) 344 { 345if(AInputEvent_getType(inputEvent) == AINPUT_EVENT_TYPE_MOTION){ 346return this-> on_input_motion(inputEvent); 347} 348else if(AInputEvent_getType(inputEvent) == AINPUT_EVENT_TYPE_KEY){ 349return this-> on_input_keyboard(inputEvent); 350} 351return 0; 352 } 353 354 // inputQueue callback 355 int android_app::on_input(int fd, int events, void* data) 356 { 357ANDROID_APP_LOGV("on_input %p", data); 358android_app* app = (android_app*)data; 359AInputEvent* event = NULL; 360while (AInputQueue_getEvent(app-> inputQueue, & event) > = 0) { 361//ANDROID_APP_LOGV("New input event: type=%d ", AInputEvent_getType(event)); 362if (AInputQueue_preDispatchEvent(app-> inputQueue, event)) { 363continue; 364} 365AInputQueue_finishEvent(app-> inputQueue, event, app-> on_input_event(event)); 366} 367return 1; 368 } 369 370 //读取事件 371 bool android_app::read_event(APP_EVENT& event) 372 { 373return message.read(& event, sizeof(event)) == sizeof(event); 374 } 375 376 #ifdef ANDROID_APP_DEBUG 377 const char* app_event_name(int id) 378 { 379switch (id) 380{ 381case APP_START:return "APP_START"; 382case APP_STOP:return "APP_STOP"; 383case APP_RESUME:return "APP_RESUME"; 384case APP_PAUSE:return "APP_PAUSE"; 385case APP_DESTROY:return "APP_DESTROY"; 386case APP_SAVE:return "APP_SAVE"; 387case APP_CONFIG:return "APP_CONFIG"; 388case APP_WINDOW_CREATE:return "APP_WINDOW_CREATE"; 389case APP_WINDOW_CLOSE:return "APP_WINDOW_CLOSE"; 390case APP_WINDOW_ACTIVATE:return "APP_WINDOW_ACTIVATE"; 391case APP_WINDOW_DEACTIVATE: return "APP_WINDOW_DEACTIVATE"; 392case APP_WINDOW_RESIZE:return "APP_WINDOW_RESIZE"; 393case APP_INPUT:return "APP_INPUT"; 394default: 395break; 396} 397return null; 398 } 399 #endif 400 401 //预处理事件 402 void android_app::process_begin(APP_EVENT& event) 403 { 404switch (event.id){ 405case APP_START: 406case APP_STOP: 407case APP_RESUME: 408case APP_PAUSE: 409ANDROID_APP_LOGV("APP_STATE = %s ", app_event_name(event.id)); 410this-> activityState = event.id; 411break; 412case APP_DESTROY: 413ANDROID_APP_LOGV("APP_DESTROY "); 414this-> running = false; 415break; 416case APP_SAVE: 417//free_saved_state(this); 418break; 419case APP_CONFIG: 420ANDROID_APP_LOGV("APP_CONFIG "); 421AConfiguration_fromAssetManager(this-> config, this-> activity-> assetManager); 422this-> print_config(); 423break; 424 425case APP_WINDOW_CREATE: 426ANDROID_APP_LOGV("APP_WINDOW_CREATE : %p ", event.data); 427this-> window = (ANativeWindow*)event.data; 428break; 429case APP_INPUT:{ 430ANDROID_APP_LOGV("APP_INPUT : %p ", event.data); 431if(this-> inputQueue){ 432AInputQueue_detachLooper(this-> inputQueue); 433} 434this-> inputQueue = (AInputQueue*)event.data; 435if(this-> inputQueue){ 436AInputQueue_attachLooper(this-> inputQueue, this-> looper, 0, android_app::on_input, this); 437} 438break; 439} 440default: 441ANDROID_APP_LOGV("APP_EVENT : %s", app_event_name(event.id)); 442break; 443} 444 } 445 446 //后续处理事件 447 void android_app::process_end(APP_EVENT& event) 448 { 449switch (event.id) { 450case APP_WINDOW_CLOSE: 451ANDROID_APP_LOGV("APP_WINDOW_CLOSE "); 452this-> window = NULL; 453break; 454case APP_SAVE: 455ANDROID_APP_LOGV("APP_SAVE "); 456this-> stateSaved = 1; 457break; 458case APP_RESUME: 459//free_saved_state(this); 460break; 461default: 462break; 463} 464 } 465 466 void android_app::dispose() 467 { 468ANDROID_APP_LOGV("android_app::dispose!"); 469free_saved_state(this); 470//auto_lock lock(app-> mutex); 471if(this-> inputQueue){ 472AInputQueue_detachLooper(this-> inputQueue); 473} 474AConfiguration_delete(this-> config); 475this-> destroyed = 1; 476this-> cond.broadcast(); 477// Can‘t touch android_app object after this. 478 } 479 480 // app main thread 481 void* android_app_main(void* param) 482 { 483android_app* app = (android_app*)param; 484 485app-> config = AConfiguration_new(); 486AConfiguration_fromAssetManager(app-> config, app-> activity-> assetManager); 487app-> print_config(); 488 489app-> looper = ALooper_prepare(0); 490app-> running = true; 491 492android_main(app); //android_main 493 494app-> dispose(); 495 496return NULL; 497 } 498 499 // -------------------------------------------------------------------- 500 // 501 // Native activity interaction (主线程调用的函数) 502 // 503 // -------------------------------------------------------------------- 504 505 android_app* android_app_create(ANativeActivity* activity, void* savedState, size_t savedStateSize) 506 { 507android_app* app = new android_app; 508app-> activity = activity; 509 510if (savedState != NULL) { 511/* 512app-> savedState = malloc(savedStateSize); 513app-> savedStateSize = savedStateSize; 514memcpy(app-> savedState, savedState, savedStateSize); 515*/ 516} 517 518if(app-> message.create()){ 519ANDROID_APP_ERROR("could not create pipe: %s", strerror(errno)); 520return NULL; 521} 522 523//int flag = fcntl(app-> message.in(), F_GETFL, 0 ); 524//fcntl(app-> message.in(), F_SETFL, flag | O_NONBLOCK); 525 526pthread_attr_t attr; 527pthread_attr_init(& attr); 528pthread_attr_setdetachstate(& attr, PTHREAD_CREATE_DETACHED); 529pthread_create(& app-> thread, & attr, android_app_main, app); 530 531return app; 532 } 533 534 void android_app_post_event(android_app* app, const APP_EVENT& event) 535 { 536//ANDROID_APP_LOGV("write event %d", event.id); 537if(app-> message.write(& event, sizeof(event)) != sizeof(event)) { 538ANDROID_APP_ERROR("Failure writing android_app event: %s ", strerror(errno)); 539} 540 } 541 542 void android_app_post_event(android_app* app, int id) 543 { 544APP_EVENT event = {id}; 545android_app_post_event(app, event); 546 } 547 548 // 549 // 主线程回调函数 550 // 551 552 // 553 // app 554 // 555 556 void onStart(ANativeActivity* activity) 557 { 558ANDROID_APP_LOGV("Activity Start: %p ", activity); 559android_app_post_event((android_app*)activity-> instance, APP_START); 560 } 561 562 void onStop(ANativeActivity* activity) 563 { 564ANDROID_APP_LOGV("Activity Stop: %p ", activity); 565android_app_post_event((android_app*)activity-> instance, APP_STOP); 566 } 567 568 void onResume(ANativeActivity* activity) 569 { 570ANDROID_APP_LOGV("Activity Resume: %p ", activity); 571android_app_post_event((android_app*)activity-> instance, APP_RESUME); 572 } 573 574 void onPause(ANativeActivity* activity) 575 { 576ANDROID_APP_LOGV("Activity Pause: %p ", activity); 577android_app_post_event((android_app*)activity-> instance, APP_PAUSE); 578 } 579 580 void onDestroy(ANativeActivity* activity) 581 { 582ANDROID_APP_LOGV("Activity Destroy: %p ", activity); 583android_app* app = (android_app*)activity-> instance; 584//auto_lock lock(app-> mutex); 585android_app_post_event(app, APP_DESTROY); 586while (!app-> destroyed) { 587//app-> cond_wait(); 588} 589 590app-> message.close(); 591delete app; 592 } 593 594 void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) 595 { 596android_app* app = (android_app*)activity-> instance; 597void* savedState = NULL; 598 599ANDROID_APP_LOGV("Activity SaveInstanceState: %p ", activity); 600/* 601auto_lock lock(app-> mutex); 602app-> stateSaved = 0; 603android_app_post_event(app, APP_SAVE); 604while (!app-> stateSaved) { 605app-> cond_wait(); 606} 607 608if (app-> savedState != NULL) { 609savedState = app-> savedState; 610*outLen = app-> savedStateSize; 611app-> savedState = NULL; 612app-> savedStateSize = 0; 613} 614*/ 615return savedState; 616 } 617 618 void onConfigurationChanged(ANativeActivity* activity) { 619ANDROID_APP_LOGV("Activity ConfigurationChanged: %p ", activity); 620android_app_post_event((android_app*)activity-> instance, APP_CONFIG); 621 } 622 623 void onLowMemory(ANativeActivity* activity) 624 { 625ANDROID_APP_LOGV("Activity LowMemory: %p ", activity); 626android_app_post_event((android_app*)activity-> instance, APP_LOW_MEMORY); 627 } 628 629 // 630 // window 631 // 632 633 void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) 634 { 635ANDROID_APP_LOGV("NativeWindowCreated: %p -- %p ", activity, window); 636APP_EVENT event; 637event.id = APP_WINDOW_CREATE; 638event.data = https://www.songbingjia.com/android/window; 639android_app_post_event((android_app*)activity-> instance, event); 640 } 641 642 void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) 643 { 644ANDROID_APP_LOGV("NativeWindowDestroyed: %p -- %p ", activity, window); 645android_app_post_event((android_app*)activity-> instance, APP_WINDOW_CLOSE); 646 } 647 648 void onWindowFocusChanged(ANativeActivity* activity, int focused) 649 { 650ANDROID_APP_LOGV("WindowFocusChanged: %p -- %d ", activity, focused); 651android_app_post_event((android_app*)activity-> instance, focused ? APP_WINDOW_ACTIVATE : APP_WINDOW_DEACTIVATE); 652 } 653 654 void onNativeWindowResized(ANativeActivity* activity, ANativeWindow* window) 655 { 656ANDROID_APP_LOGV("NativeWindowResized: %p -- %p ", activity, window); 657android_app_post_event((android_app*)activity-> instance, APP_WINDOW_RESIZE); 658 } 659 660 void onContentRectChanged(ANativeActivity* activity, const ARect* rect) 661 { 662ANDROID_APP_LOGV("ContentRectChanged: [%d, %d - %d, %d] ", rect-> left, rect-> top, rect-> right, rect-> bottom); 663/* 664APP_EVENT event; 665event.id= APP_WINDOW_RECT_CHANGED; 666event.left= rect-> left; 667event.top= rect-> top; 668event.right= rect-> right; 669event.bottom = rect-> bottom; 670android_app_post_event((android_app*)activity-> instance, event); 671*/ 672 } 673 674 void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window) 675 { 676ANDROID_APP_LOGV("NativeWindowRedrawNeeded: %p -- %p ", activity, window); 677android_app_post_event((android_app*)activity-> instance, APP_WINDOW_PAINT); 678 } 679 680 // 681 // input 682 // 683 684 void android_app_set_input(android_app* app, AInputQueue* inputQueue) 685 { 686APP_EVENT event; 687event.id = APP_INPUT; 688event.data = https://www.songbingjia.com/android/inputQueue; 689android_app_post_event(app, event); 690 } 691 692 void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) 693 { 694ANDROID_APP_LOGV("InputQueueCreated: %p -- %p ", activity, queue); 695android_app_set_input((android_app*)activity-> instance, queue); 696 } 697 698 void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) 699 { 700ANDROID_APP_LOGV("InputQueueDestroyed: %p -- %p ", activity, queue); 701android_app_set_input((android_app*)activity-> instance, NULL); 702 } 703 704 // 705 // native activity entry 706 // 707 708 JNIEXPORT 709 void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize) 710 { 711ANDROID_APP_LOGV("NativeActivity create: %p ", activity); 712 713//app 714activity-> callbacks-> onStart= onStart; 715activity-> callbacks-> onStop= onStop; 716activity-> callbacks-> onResume= onResume; 717activity-> callbacks-> onPause= onPause; 718activity-> callbacks-> onDestroy = onDestroy; 719activity-> callbacks-> onSaveInstanceState= onSaveInstanceState; 720activity-> callbacks-> onConfigurationChanged = onConfigurationChanged; 721activity-> callbacks-> onLowMemory = onLowMemory; 722 723//window 724activity-> callbacks-> onNativeWindowCreated= onNativeWindowCreated; 725activity-> callbacks-> onNativeWindowDestroyed= onNativeWindowDestroyed; 726activity-> callbacks-> onWindowFocusChanged= onWindowFocusChanged; 727activity-> callbacks-> onNativeWindowResized= onNativeWindowResized; 728activity-> callbacks-> onContentRectChanged= onContentRectChanged; 729activity-> callbacks-> onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded; 730 731//input 732activity-> callbacks-> onInputQueueCreated= onInputQueueCreated; 733activity-> callbacks-> onInputQueueDestroyed = onInputQueueDestroyed; 734 735//create android app 736activity-> instance = android_app_create(activity, savedState, savedStateSize); 737 738//ANDROID_APP_LOGV("NativeActivity create successed."); 739 } 740 741 #endif /* ANDROID_APP_HPP*/

 

    推荐阅读