Cocos2dx Android工程的启动过程
1、安卓工程下的设置启动activity为src下面的AppActivity,启动调用的onCreate并没有做过多的事情,只是调用了父类Cocos2dxActivity的onCreate。AppActivity代码如下:
import org.cocos2dx.lib.Cocos2dxActivity;
public class AppActivity extends Cocos2dxActivity {
	@Override
	protected void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		......
    }
}
2、Cocos2dxActivity在cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java里,查看onCreate,代码如下:
@Override
	protected void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		initFMOD(); //加载声音库
		try {
			Class.forName("android.os.AsyncTask");
		} catch (Throwable ignor) {
			ignor.printStackTrace();
		}
		sContext = this;
		PSNetwork.init(sContext); //初始化安卓网络连接服务
		if (Build.VERSION.SDK_INT >= 23) {
			requestUserPermissions(); //系统的部分授权
		}
		mMacAddress = MacAddressUtil.getMacAddress(sContext);//获取wifi的MAC地址
		CocosPlayClient.init(this, false); //暂时无用
		boolean isLoadOK = onLoadNativeLibraries(); //把工程中libs下面的so文件load进来,定义在AndroidManifest, meta-data标签下,android.app.lib_name. 最终在包的data/data/com.XXX.XXX/lib下面
		if (false == isLoadOK) {
			return;
		}
		this.mHandler = new Cocos2dxHandler(this);//处理安卓的弹窗等
		Cocos2dxHelper.init(this);
		this.mGLContextAttrs = getGLContextAttrs();//获取OpenGLEs的相关属性
		this.init(); //说明如下文
		if (mVideoHelper == null) {
			mVideoHelper = new Cocos2dxVideoHelper(this, mFrameLayout);
		}
		if (mWebViewHelper == null) {
			mWebViewHelper = new Cocos2dxWebViewHelper(mFrameLayout);
		}
        if(mEditBoxHelper == null){
            mEditBoxHelper = new Cocos2dxEditBoxHelper(mFrameLayout);
        }
		if (null == mScreenListener) {
			mScreenListener = new ScreenListener(this);
			mScreenListener.begin(this);
		}
	}
3、Cocos2dxActivity的init函数如下:
	public void init() {
		// FrameLayout
		ViewGroup.LayoutParams framelayout_params = new ViewGroup.LayoutParams(
				ViewGroup.LayoutParams.MATCH_PARENT,
				ViewGroup.LayoutParams.MATCH_PARENT);
		mFrameLayout = new ResizeLayout(this); //继承自FrameLayout,看成是一块画布(canvas),其他控件添加在上面
		mFrameLayout.setLayoutParams(framelayout_params);
		// Cocos2dxEditText layout
		ViewGroup.LayoutParams edittext_layout_params = new ViewGroup.LayoutParams(
				ViewGroup.LayoutParams.MATCH_PARENT,
				ViewGroup.LayoutParams.WRAP_CONTENT);
		Cocos2dxEditBox edittext = new Cocos2dxEditBox(this);
		edittext.setLayoutParams(edittext_layout_params);//输入框
		// ...add to FrameLayout
		mFrameLayout.addView(edittext);
		// Cocos2dxGLSurfaceView
		this.mGLSurfaceView = this.onCreateView();//创建游戏的渲染,接受输入事件的OpenGL类
		// ...add to FrameLayout
		mFrameLayout.addView(this.mGLSurfaceView);//添加到画布上
		// Switch to supported OpenGL (ARGB888) mode on emulator
		if (isAndroidEmulator())
			this.mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
		this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());//注册自主实现的渲染器,内容如下
		this.mGLSurfaceView.setCocos2dxEditText(edittext);//输入框
		this.onCreateFrameLayout();
		// Set framelayout as the content view
		setContentView(mFrameLayout);//设置这个Activity的显示界面
	}
4、Cocos2dxRenderer,cocos2dx的渲染器,继承自android.opengl.GLSurfaceView.Renderer,当3中的GLSurfaceView被创建的时候会调用render的onSurfaceCreated()方法; 当GLSurfaceView大小或者横竖屏发生变化的时候调用render的onSurfaceChanged()方法; 当系统每一次重新画GLSurfaceView的时候,调用onDrawFrame()方法。所以Cocos2dxRender对这三个方法进行了重写。
	@Override
	public void onSurfaceCreated(final GL10 GL10, final EGLConfig EGLConfig) {
		Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);//此处调用了一个定义为native的函数,设置glview等,通过jni来访问c++实现的方法,接口实现在cocos/platform/android/javaactivity-android.cpp里面,下面的5会继续讲
		this.mLastTickInNanoSeconds = System.nanoTime();
		mNativeInitCompleted = true;
		try{
			Cocos2dxActivity activity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
			activity.onSurfaceCreated(this, GL10, EGLConfig);
		}catch( Throwable e ){
			e.printStackTrace();
		}
	}
@Override
	public void onDrawFrame(final GL10 gl) { //系统自动每秒钟调用60次这个函数
		/*
		 * No need to use algorithm in default(60 FPS) situation, since
		 * onDrawFrame() was called by system 60 times per second by default.
		 */
		if( true == mIsPaused ){
			return;
		}
		if( mDelayResumeCount <= DELAY_RESUME_COUNT ){
			mDelayResumeCount = mDelayResumeCount + 1;
			if( mDelayResumeCount == DELAY_RESUME_COUNT ){
				Cocos2dxRenderer.nativeOnResume();
				try{
					Cocos2dxActivity activity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
					activity.nativeResume();
				}catch( Throwable e ){
					e.printStackTrace();
				}
			}
			return;
		}
		if (sAnimationInterval <= 1.0 / 60 * Cocos2dxRenderer.NANOSECONDSPERSECOND) {
			Cocos2dxRenderer.nativeRender(); //大于等于每秒60帧则不经过算法处理,直接执行nativeRender,将在6中有说明
		} else {
			final long now = System.nanoTime();
			final long interval = now - this.mLastTickInNanoSeconds;
			if (interval < Cocos2dxRenderer.sAnimationInterval) { //按照设置的帧数,如果没有到时间,则sleep到相应的时间
				try {
					Thread.sleep((Cocos2dxRenderer.sAnimationInterval - interval)
							/ Cocos2dxRenderer.NANOSECONDSPERMICROSECOND);
				} catch (final Exception e) {
				}
			}
			/*
			 * Render time MUST be counted in, or the FPS will slower than
			 * appointed.
			 */
			this.mLastTickInNanoSeconds = System.nanoTime();
			Cocos2dxRenderer.nativeRender();
		}
		try{
			Cocos2dxActivity activity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
			activity.onDrawFrame(this, gl);
		}catch( Throwable e ){
			e.printStackTrace();
		}
	}
	@Override
	public void onSurfaceChanged(final GL10 GL10, final int width,
			final int height) {
		Cocos2dxRenderer.nativeOnSurfaceChanged(width, height);
		try{
			Cocos2dxActivity activity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
			activity.onSurfaceChanged(this, GL10, width, height);
		}catch( Throwable e ){
			e.printStackTrace();
		}
	}
5、 4里面onSurfaceCreated的nativeInit的实现放在cocos/platform/android/javaactivity-android.cpp,方法如下:
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)
{
    auto director = cocos2d::Director::getInstance();
    auto glview = director->getOpenGLView();
    if (!glview)
    {
        glview = cocos2d::GLViewImpl::create("Android app");
        glview->setFrameSize(w, h);
        director->setOpenGLView(glview); //设置glview
        //cocos_android_app_init(env, thiz);
        cocos2d::Application::getInstance()->run(); //程序开始运行,android的Application实现放在CCApplication-android.cpp,run的代码如下
    }
    else
    {
        cocos2d::GL::invalidateStateCache();
        cocos2d::GLProgramCache::getInstance()->reloadDefaultGLPrograms();
        cocos2d::DrawPrimitives::init();
        cocos2d::VolatileTextureMgr::reloadAllTextures();
        cocos2d::EventCustom recreatedEvent(EVENT_RENDERER_RECREATED);
        director->getEventDispatcher()->dispatchEvent(&recreatedEvent);
        director->setGLDefaultValues();
    }
}
int Application::run()
{
    // Initialize instance and cocos2d.
    if (! applicationDidFinishLaunching()) //applicationDidFinishLanunching在自己的Classes/AppDelegate进行重写,游戏已经启动
    {
        return 0;
    }
    return -1;
}
bool AppDelegate::applicationDidDinishLaunching()
{
	......
	director->setOpenGLView(glview);
	director->setAnimationInterval(1/30.f); //设置帧数,会调用Application-android的setAnimationInterval,再通过JniHelper调用Cocos2dxRenderer中的setAnimationInterval
	director->runWithScene(scene); //
	return true
}
6、关于4中onDrawFrame涉及到的函数nativeRender,它也是一个native类型的函数,实现放在cocos/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp
    JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender(JNIEnv* env) {
        cocos2d::Director::getInstance()->mainLoop(); //进入游戏的主循环,Director的mainLoop,事件的分发,渲染,内存池的管理
    }
Cocos2dx Android工程的启动过程的更多相关文章
- Android Activity的启动过程
		文章编辑的太长了,请移步我的csdn博客:http://blog.csdn.net/xyh269 Android Activity的启动过程原文链接:http://blog.csdn.net/xyh2 ... 
- Android 6.0启动过程具体解析
		在之前的一篇文章中.从概念上学习了Andoird系统的启动过程.Android系统启动过程学习 而在这篇文章中,我们将从代码角度细致学习Android系统的启动过程,同一时候,学习Android启动过 ... 
- Android应用程序启动过程源代码分析
		文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程 ... 
- Android 应用程序启动过程源代码分析
		本文转自:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程序的Activity的启动过程.在And ... 
- Android工程的编译过程
		现在很多人想对Android工程的编译和打包进行自动化,比如建立每日构建系统.自动生成发布文件等等.这些都需要我们对Android工程的编译和打包有一个深入的理解,至少要知道它的每一步都做了什么,需要 ... 
- Android系统进程Zygote启动过程的源代码分析
		文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6768304 在Android系统中,所有的应用 ... 
- Android AudioPolicyService服务启动过程
		AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备.某种Stream类型的音频对应什么设备等等.而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如 ... 
- android 性能优化 -- 启动过程 冷启动 热启动
		一.应用的启动方式 通常来说,启动方式分为两种:冷启动和热启动. 1.冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动. 2.热启动:当启 ... 
- Android应用程序启动过程(一)总结
		一.App启动方式 1,冷启动 冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用. 冷启动的特点:因为系统会重新创建一个新的进程分配给它,所以会创建和初始化App ... 
随机推荐
- 常见模块(二) logging模块
			logging模块是专门做日志系统的.分为函数版和自定义函数. (一)logging模块初级版 缺点,不能指定字符集,不能把屏幕输出和文件日志同时记录.只能选择其一. 文件记录日志 import lo ... 
- 运行gunicorn失败:[ERROR] Connection in use: ('0.0.0.0', 8000)
			参考:https://pdf-lib.org/Home/Details/5262 执行命令:gunicorn -w 4 -b 0.0.0.0:8000 wsgi:app,遇到如下错误: [2019-0 ... 
- MySQL 和 Oracle 在 MyBatis 使用中的区别
			MySQL 和 Oracle 在 MyBatis 使用中的区别: 区别 MySQL Oracle 存储过程的参数模式 mode 为 IN 时,是否需要指定 jdbcType 不需要:MyBatis 为 ... 
- select2  清除选中项解决办法
			在项目中使用select2:选中项 设置可清除. 代码中加上了allowClear : true $.get("/Work/Ajax/Select.ashx", function ... 
- Excel技巧--巧用差异化插入空行
			假设有上面这一列,要求在不同城市之间插入一空行相隔开.数据少的时候可以手动操作,但数据量大时,就需要以下技巧: 1.复制该列(除去标题),并粘贴到右侧一列,但上方要隔开一个单元格B2: 2.将这两列选 ... 
- 多版本opencv管理; find_package()的原理解析
			近期用cmake编译程序时,报错找不到opencv2.由于我电脑里安装了多个版本的opencv,管理不善,借此机会梳理一下思路. 1. Cmake -- find_package(Opencv REQ ... 
- Resilience4j usage
			1. pom 1) normal <dependency> <groupId>io.github.resilience4j</groupId> <artifa ... 
- k8s学习笔记之二:使用kubeadm安装k8s集群
			一.集群环境信息及安装前准备 部署前操作(集群内所有主机): .关闭防火墙,关闭selinux(生产环境按需关闭或打开) .同步服务器时间,选择公网ntpd服务器或者自建ntpd服务器 .关闭swap ... 
- RabbitMQ--windows10环境下的RabbitMQ安装步骤(转)
			https://blog.csdn.net/weixin_39735923/article/details/79288578 
- leetcode14:最长公共字符串
			编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ... 
