对于cocos2dx在android平台事件的响应过程很模糊,于是分析了下源码,cocos2dx 版本3.4,先导入一个android工程,然后看下AndroidManifest.xml

    <application android:label="@string/app_name"                 android:icon="@drawable/icon">                             <!-- Tell Cocos2dxActivity the name of our .so -->        <meta-data android:name="android.app.lib_name"                  android:value="cocos2dcpp" />        <activity android:name="org.cocos2dx.cpp.AppActivity"                  android:label="@string/app_name"                  android:screenOrientation="landscape"                  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"                  android:configChanges="orientation">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>

由此得知启动窗口类为org.cocos2dx.cpp.AppActivity,并继承之Cocos2dxActivity

package org.cocos2dx.cpp;import org.cocos2dx.lib.Cocos2dxActivity;public class AppActivity extends Cocos2dxActivity {}
public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener 

看下Cocos2dxActivity 的onCreate

    @Override    protected void onCreate(final Bundle savedInstanceState) {        Log.i(TAG, "------onCreate----");        super.onCreate(savedInstanceState);        CocosPlayClient.init(this, false);        onLoadNativeLibraries();//加载了一些静态库        sContext = this;        this.mHandler = new Cocos2dxHandler(this);                Cocos2dxHelper.init(this);                this.mGLContextAttrs = getGLContextAttrs();        this.init();//初始化        if (mVideoHelper == null) {            mVideoHelper = new Cocos2dxVideoHelper(this, mFrameLayout);        }                if(mWebViewHelper == null){            mWebViewHelper = new Cocos2dxWebViewHelper(mFrameLayout);        }    }

onCreate 调用了 init() 初始化

   public void init() {                // FrameLayout        ViewGroup.LayoutParams framelayout_params =            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,                                       ViewGroup.LayoutParams.MATCH_PARENT);        mFrameLayout = new FrameLayout(this);        mFrameLayout.setLayoutParams(framelayout_params);        // Cocos2dxEditText layout        ViewGroup.LayoutParams edittext_layout_params =            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,                                       ViewGroup.LayoutParams.WRAP_CONTENT);        Cocos2dxEditText edittext = new Cocos2dxEditText(this);        edittext.setLayoutParams(edittext_layout_params);        // ...add to FrameLayout        mFrameLayout.addView(edittext);        // Cocos2dxGLSurfaceView        this.mGLSurfaceView = this.onCreateView();        // ...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);        // Set framelayout as the content view        setContentView(mFrameLayout);    }

最终显示的视图为this.mGLSurfaceView = this.onCreateView();

    public Cocos2dxGLSurfaceView onCreateView() {        Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);        //this line is need on some device if we specify an alpha bits        if(this.mGLContextAttrs[3] > 0) glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);        Cocos2dxEGLConfigChooser chooser = new Cocos2dxEGLConfigChooser(this.mGLContextAttrs);        glSurfaceView.setEGLConfigChooser(chooser);        return glSurfaceView;    }

Cocos2dxGLSurfaceView 就是最终显示的视图,事件处理也在这个类中,包括 onResume,onPause,onSizeChanged,onKeyDown,onTouchEvent等主要看下onTouchEvent事件的处理过程

 @Override    public boolean onTouchEvent(final MotionEvent pMotionEvent) {                //Log.d(TAG, "------onTouchEvent action=----"+pMotionEvent.getAction());                // these data are used in ACTION_MOVE and ACTION_CANCEL        final int pointerNumber = pMotionEvent.getPointerCount();        final int[] ids = new int[pointerNumber];        final float[] xs = new float[pointerNumber];        final float[] ys = new float[pointerNumber];        for (int i = 0; i < pointerNumber; i++) {            ids[i] = pMotionEvent.getPointerId(i);            xs[i] = pMotionEvent.getX(i);            ys[i] = pMotionEvent.getY(i);        }        switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) {            case MotionEvent.ACTION_POINTER_DOWN:                final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;                final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown);                final float xPointerDown = pMotionEvent.getX(indexPointerDown);                final float yPointerDown = pMotionEvent.getY(indexPointerDown);                this.queueEvent(new Runnable() {                    @Override                    public void run() {                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idPointerDown, xPointerDown, yPointerDown);                    }                });                break;            case MotionEvent.ACTION_DOWN:                // there are only one finger on the screen                final int idDown = pMotionEvent.getPointerId(0);                final float xDown = xs[0];                final float yDown = ys[0];                this.queueEvent(new Runnable() {                    @Override                    public void run() {                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idDown, xDown, yDown);                    }                });                break;            case MotionEvent.ACTION_MOVE:                this.queueEvent(new Runnable() {                    @Override                    public void run() {                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionMove(ids, xs, ys);                    }                });                break;            case MotionEvent.ACTION_POINTER_UP:                final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;                final int idPointerUp = pMotionEvent.getPointerId(indexPointUp);                final float xPointerUp = pMotionEvent.getX(indexPointUp);                final float yPointerUp = pMotionEvent.getY(indexPointUp);                this.queueEvent(new Runnable() {                    @Override                    public void run() {                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idPointerUp, xPointerUp, yPointerUp);                    }                });                break;            case MotionEvent.ACTION_UP:                // there are only one finger on the screen                final int idUp = pMotionEvent.getPointerId(0);                final float xUp = xs[0];                final float yUp = ys[0];                this.queueEvent(new Runnable() {                    @Override                    public void run() {                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idUp, xUp, yUp);                    }                });                break;            case MotionEvent.ACTION_CANCEL:                this.queueEvent(new Runnable() {                    @Override                    public void run() {                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionCancel(ids, xs, ys);                    }                });                break;        }        /*        if (BuildConfig.DEBUG) {            Cocos2dxGLSurfaceView.dumpMotionEvent(pMotionEvent);        }        */        return true;    }

看下MotionEvent.ACTION_DOWN,调用了Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown

    public void handleActionDown(final int id, final float x, final float y) {        Log.i("Cocos2dxRenderer","-----handleActionDown--");        Cocos2dxRenderer.nativeTouchesBegin(id, x, y);    }

这里的nativeTouchesBegin 是一个jni方法,是现在cocos2d\cocos\platform\android\jni\TouchesJni.cpp里,

private static native void nativeTouchesBegin(final int id, final float x, final float y);
    JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesBegin(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {        intptr_t idlong = id;        log("----Info:nativeTouchesBegin id = %d, x=%f, y=%f",id,x,y);        cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &idlong, &x, &y);    }

最后调用GLView::handleTouchesBegin 通过EventDispatcher::dispatchEvent进行事件的分发,调用事件响应函数,都是C++里完成的,就不再往下分析了。

能力有限,分析有误处请指正。

更多相关文章

  1. Android(安卓)APK文件安装过程小结
  2. 【Android】进程间通信IPC——Binder
  3. android adb和串口调试.
  4. 详解 Android(安卓)的 Activity 组件
  5. Android项目---listview的那些属性,常用却不常见
  6. Android输入法之输入系统
  7. Android(安卓)IPC 通讯机制源码分析 二
  8. Android的IPC机制Binder的详解(转发)
  9. Android全屏显示的两种方式

随机推荐

  1. Android 耳机插入过程分析
  2. Android 3D 旋转的三角形(四)
  3. 【android】小知识点整理qwq(三)
  4. Android CheckedTextView
  5. ListView Video
  6. Android(安卓)-HandleThread-给线程传参
  7. android典型代码系列(二十二)------按键
  8. Android Activity加入半透明蒙板,实现夜
  9. AndroidStudio打包出现问题: `Error:Exec
  10. Android复选框(CheckBox)的现实