cocos2d-x 3.2 启动过程分析 - win32 与 android 平台(二)

上篇文章试着分析了 cocos2d-x 3.2 在 win32平台下的启动过程。今天我们继续探寻,看看 Android 平台下,引擎又是如何启动的。

预备知识:

1. 对 jni ( java 调用 c++ 动态库) 技术略微了解

2. 大致了解 Android 应用的开发过程。 (不用太多)

一、入口

有过 Android 开发经验的朋友应该都清楚,普通的 Android 应用,其入口都是 Application 或它的子类类型,再看需要界面与否选择实现 Activity 或者 Service 类。cocos2d-x 虽然主要用 C++ 开发,在这一点上却也没什么特别。不同的是,在 cocos2d-x 中,这几个类真的只是起入口的作用,引擎的渲染过程以及所有的内部逻辑,都是用 c++实现的。我们自己写的c++代码,和引擎代码一起被编译成动态库,再由 java 层通过 jni 技术进行调用,从而进入到引擎的核心部分。这样说概念比较模糊,接下来我们具体的进行分析。

 

二、工程目录

显然,这次我们关注的应该是工程中与 Android 相关的部分:

image

进入 proj.android 目录,里面是一些 eclipse 项目的配置文件以及一些目录,其中:

    src 目录存放的是 java 源文件。

    jni 目录存放的是 c++源文件以及 NDK 的编译脚本 (makefile)。

image

src 目录

image

jni 目录

打开 hellocpp/main.cpp,里面只有一个函数: 

   1:  void cocos_android_app_init (JNIEnv* env, jobject thiz) 
   2:  {
   3:      LOGD("cocos_android_app_init");
   4:      AppDelegate *pAppDelegate = new AppDelegate();
   5:  }
 

 是不是有点奇怪,明明叫做 main.cpp, 里面却没有 main 函数,这也就算了,函数里居然只是定义了一个 AppDelegate类型的对象,却没有使用它。别急,我们暂且接受这个现实,将目光转向另一个方面。

转到 src 目录,只有一个 org 文件夹,一路打开,最后找到 AppActivity.java 这个文件,这也是该目录下唯一的源文件。打开它:

   1:  package org.cocos2dx.cpp;
   2:   
   3:  import org.cocos2dx.lib.Cocos2dxActivity;
   4:   
   5:  public class AppActivity extends Cocos2dxActivity {
   6:  }

这里面也没什么内容,只不过定义了一个 AppAcvivity 类作为游戏的界面入口(可参照 AndroidManifest.xml ),看来真正的玄机就在它继承的 Cocos2dxActivity 类上了。

那么这个类在哪里呢?让我们离开 proj.android 目录,进入同级的 cocos2d 目录,这里就是引擎的核心代码存放之处。进入 cocos/cocos/platform,里面放的是引擎中各个平台代码的实现。

image../cocos2d/cocos/platform/

进入 android/java/src/org/cocos2dx/lib:

image 

都在这里了!看看 Cocos2dxActivity.java 里面都有什么,首先关注 onCreate():

   1:      @Override
   2:      protected void onCreate(final Bundle savedInstanceState) {
   3:          super.onCreate(savedInstanceState);
   4:   
   5:          onLoadNativeLibraries();    //加载 c++ 编译而成的动态库,这里是libcocos2dcpp.so
   6:   
   7:          sContext = this;            
   8:          this.mHandler = new Cocos2dxHandler(this);    //Cocos2dxHandler 继承自 Handler,处理一些显示对话框类似的请求。
   9:          
  10:          Cocos2dxHelper.init(this);        //Cocos2dxHelper 工具类,处理一些 Activity 生命周期事件以及发起一些请求
  11:          
  12:          this.init();            //初始化自身
  13:          if (mVideoHelper == null) {
  14:              mVideoHelper = new Cocos2dxVideoHelper(this, mFrameLayout);    //顾名思义
  15:          }
  16:      }

可以看到,onCreate()初始化了一系列辅助类,详见注释,我们再看init()函数:

   1:      public void init() {
   2:          
   3:          // 设置Activity的布局为FrameLayout
   4:          // FrameLayout
   5:          ViewGroup.LayoutParams framelayout_params =
   6:              new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
   7:                                         ViewGroup.LayoutParams.MATCH_PARENT);
   8:          mFrameLayout = new FrameLayout(this);
   9:          mFrameLayout.setLayoutParams(framelayout_params);
  10:   
  11:          //这里有点奇怪,此处的Cocos2dxEditText我还不清楚其作用,期待高人解答~
  12:          // Cocos2dxEditText layout
  13:          ViewGroup.LayoutParams edittext_layout_params =
  14:              new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
  15:                                         ViewGroup.LayoutParams.WRAP_CONTENT);
  16:          Cocos2dxEditText edittext = new Cocos2dxEditText(this);
  17:          edittext.setLayoutParams(edittext_layout_params);
  18:   
  19:          // ...add to FrameLayout
  20:          mFrameLayout.addView(edittext);
  21:   
  22:          //创建一个Cocos2dxGLSurfaceView
  23:          // Cocos2dxGLSurfaceView
  24:          this.mGLSurfaceView = this.onCreateView();
  25:          
  26:          //将Cocos2dxGLSurfaceView加入布局中
  27:          // ...add to FrameLayout
  28:          mFrameLayout.addView(this.mGLSurfaceView);
  29:   
  30:          //如果是Android模拟器,设置OpenglES的一些参数
  31:          // Switch to supported OpenGL (ARGB888) mode on emulator
  32:          if (isAndroidEmulator())
  33:             this.mGLSurfaceView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
  34:   
  35:          //设置Cocos2dxGLSurfaceView的Render
  36:          this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());
  37:          this.mGLSurfaceView.setCocos2dxEditText(edittext);
  38:   
  39:          // Set framelayout as the content view
  40:          setContentView(mFrameLayout);
  41:      }
 

我们知道,cocos2d-x是通过Opengl进行渲染的,可以断定,代码中的这两句话一定起了比较重要的作用:

 

image 

image

进入Cocos2dxRenderer里面:

image 

image

不言自明了吧! 正是在这里,java层与本地代码(c++代码)之间产生了联系,我们看到,Cocos2dxRenderer类型中声明了很多本地方法,在其中的 nativeInit() 中进入了C++层面,进而开始一系列引擎的初始化。那么 nativeInit() 方法在哪里呢?进入 cocos2d\cocos\platform\android 目录,打开其中的 javaactivity.cpp :

image

你看,是不是和Win32下面的入口差不多了呢? 后面的就留给大家自己看了吧! 可以参考我上一篇写Win32平台下启动过程的文章。

 

后面写的比较仓促,也是刚学着写博客不久,如有不足之处,还望各位海涵。

转载请注明。

posted @ 2014-11-18 11:39  wqshare  阅读(384)  评论(0编辑  收藏  举报