cocos2dx源码阅读-启动流程

##我对名词的定义

  1. app: 系统层面的应用,例如相对android就是整个一个apk程序
  2. 引擎: cocos2dx
  3. porject: cocos2dx 里的一个project

##Android

  1. AndroidManifest.xml 指定启动Activity为 android.app.NativeActivity

    <activity android:name="android.app.NativeActivity"
              android:label="@string/app_name"
              android:screenOrientation="landscape"
              android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
              android:configChanges="orientation|screenSize|smallestScreenSize">
    
        //设定回调的.so库
        <meta-data android:name="android.app.lib_name"
                   android:value="cocos2dcpp" />
    
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
  2. NativeActivity机制约定,Activity启动后会找AndroidManifest.xml文件中的android.app.lib_name配置项设定的(在cocos2d引擎就是是cocos2dcpp)这个.so, 并回调这个.so实现的android_main 函数;将控制权交回给APP应用 更多相关阅读

  3. 引擎在 $COCOS2DX_ROOT/cocos/2d/platform/android/nativeactivity.cpp 实现android_main回调函数,此时程序进入引擎层
    引擎做一系列初始化,监听AppCmd事件, 当事件为APP_CMD_INIT_WINDOW时回调project实现的 cocos_android_app_init, 让porject(cocos2d范围的应用)得以初始化;

void android_main(struct android_app* state) {

    ......

    //设置app事件回调函数
    state->onAppCmd = engine_handle_cmd;

    //设置input事件回调函数
    state->onInputEvent = engine_handle_input;
    engine.app = state;

    // Prepare to monitor accelerometer
    engine.sensorManager = ASensorManager_getInstance();

    ......

}
    static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
        struct engine* engine = (struct engine*)app->userData;
        switch (cmd) {
            case APP_CMD_SAVE_STATE:
                ......
            case APP_CMD_INIT_WINDOW:  //程序初始化
                if (engine->app->window != NULL) {
                    cocos_dimensions d = engine_init_display(engine);
                    if ((d.w > 0) &&
                        (d.h > 0)) {
                        ......
                        // 初始化事件, 进行引擎初始化
                        cocos_init(d, app);
                    }
                }
                break;
        }
    }

    static void cocos_init(cocos_dimensions d, struct android_app* app) {

        ......

        if (!cocos2d::Director::getInstance()->getOpenGLView())
        {
            cocos2d::EGLView *view = cocos2d::EGLView::getInstance();
            view->setFrameSize(d.w, d.h);

            //调用project实现的初始化方法,也就说,project实现cocos2d::Application , 见下节点
            cocos_android_app_init(app);

            //引擎run, 也就是project run
            cocos2d::Application::getInstance()->run();
        }

        ......

    }
  1. 游戏目录的jni/helloxxx/main.cpp 实现 cocos_android_app_init, 生成 AppDelegate

    void cocos_android_app_init (struct android_app* app) {

       /**
        * AppDelegate 继承自cocos2d::Application, cocos2dx里很多地方使用的都是'单例'模式;
        * 上面的 cocos2d::Application::getInstance()->run(); AppDelegate也就run起来了
       */
       AppDelegate *pAppDelegate = new AppDelegate();
    

    }

  2. $PROJECT/Classes目录下, AppDelegate 也是初始化一遍, 将scence场景 交给Director导演进行run

    bool AppDelegate::applicationDidFinishLaunching() {

       ......
    
       // 生成我自己的场景
       auto scene = HelloWorld::createScene();
    
       // 让框架帮我把场景跑(管理)起来;
       director->runWithScene(scene);
    

    }

  3. 这个时候,也就进入到了project的场景当中