Android:将 Java View 添加到 OpenGl View

标签 android cocos2d-x

我已经使用 ndk 和 cocos2dx 将我的 iphone 应用程序移植到 android。 这非常有效,我认为 cocos2dx 非常酷!

现在我想在 Java 环境中向我的主 opengl View 添加一些 Java View 。 这对我来说并不是真的有用。我认为我需要有关在 Java 环境中使用 View 、 Activity 、Intent 等的基本知识。

具体来说,我需要在运行时向我的 opengl View 添加一个 TextView (java)。 我尝试了以下方法,但是当我调用函数 void testSetText() 时它崩溃了。

public class myTest extends Cocos2dxActivity{
    private static final String TAG = "MY_TEST";

    private FrameLayout mainFrame; 
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        Log.e(TAG, "onCreate");

        String packageName = getApplication().getPackageName();
        super.setPackageName(packageName);

        mainFrame = new FrameLayout(this);

        mGLView = new Cocos2dxGLSurfaceView(this);

        mainFrame.addView(mGLView);

        RelativeLayout base = new RelativeLayout(this);
        base.addView(mainFrame);
        setContentView(base);

    }

    private GLSurfaceView mGLView;

    static {
        System.loadLibrary("cocos2d");
        System.loadLibrary("cocosdenshion");
        System.loadLibrary("game");
    }

     @Override
     protected void onPause() {         
         super.onPause();
         Log.i("TAG"," onPause");         
         mGLView.onPause();

     }

     @Override
     protected void onResume() {         
         super.onResume();
         Log.i("TAG"," onResume");         
         mGLView.onResume();
     }

    @Override
    protected void onStart() {
        // TODO Auto-generated method stub                
        super.onStart();
        Log.e(TAG, "onStart");

    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub        
        super.onStop();        
        Log.e(TAG, "onStop");
    }

    public void testSetText(){
        Log.e(TAG, "testSetText");    

        TextView textView = new TextView(this);         
        textView.setText("Hello, Android");

        LinearLayout testLayout = new LinearLayout(this);

        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);        
        lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        testLayout.addView(textView ,lp);
        mainFrame.addView(testLayout);

    }
}

如果我改为尝试运行另一个 Activity - 或者在 function public void testSetText() 中调用 setContentView(R.layout.test_screen),我的游戏也会崩溃。

谁能给我一些好的建议吗?

更新:
谢谢马卡斯 这是堆栈跟踪:

08-16 15:19:52.121: INFO/TAG(8352):  canITalktoPIT 
08-16 15:19:52.121: ERROR/MY_APP(8352): test call PIT 2
08-16 15:19:52.203: WARN/dalvikvm(8352): threadid=11: thread exiting with uncaught exception (group=0x40015560)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352): FATAL EXCEPTION: GLThread 10
08-16 15:19:52.214: ERROR/AndroidRuntime(8352): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.view.ViewRoot.checkThread(ViewRoot.java:2932)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.view.ViewRoot.requestLayout(ViewRoot.java:629)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.view.View.requestLayout(View.java:8267)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.view.View.requestLayout(View.java:8267)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.view.View.requestLayout(View.java:8267)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:257)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.view.View.requestLayout(View.java:8267)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.view.ViewGroup.addView(ViewGroup.java:1869)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.view.ViewGroup.addView(ViewGroup.java:1851)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at dk.comp.testApp.testAppB.calling(testAppB.java:289)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at dk.comp.testApp.SigletonJohn.canITalktoPIT(SigletonJohn.java:43)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at org.cocos2dx.lib.testAppJavaCppComunication.pitTestJNI(testAppJavaCppComunication.java:47)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at org.cocos2dx.lib.Cocos2dxActivity.pitTestJNI(Cocos2dxActivity.java:177)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at org.cocos2dx.lib.Cocos2dxRenderer.nativeTouchesEnd(Native Method)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at org.cocos2dx.lib.Cocos2dxRenderer.handleActionUp(Cocos2dxRenderer.java:49)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at org.cocos2dx.lib.Cocos2dxGLSurfaceView$9.run(Cocos2dxGLSurfaceView.java:288)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1326)
08-16 15:19:52.214: ERROR/AndroidRuntime(8352):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1118)
08-16 15:19:52.238: WARN/ActivityManager(116):   Force finishing activity dk.comp.testApp/.testAppB
08-16 15:19:52.242: INFO/SOUND(8352):  PAUSE 
08-16 15:19:52.246: INFO/TAG(8352):  onPause



更新#2:
好的,我仍在处理这个问题,只是无法解决 :( 但是我发现了一些有趣的事情:

总结一下我的问题: 我的 android 应用程序有一个运行完美的 cocos2dx 场景。然后当用户按下按钮时:

myBut = CCMenuItemImage::itemFromNormalImage("some.png", "some.png.png", this, menu_selector(Cocos2dMenuScene::butPushed));

我通过 JNI 调用 Java 环境,并请求添加某种 View (例如 TextView )(参见 testSetText() )。此时我的应用程序崩溃了——崩溃日志:

WARN/dalvikvm(8352): threadid=11: thread exiting with uncaught exception (group=0x40015560) 08-16 15:19:52.214: ERROR/AndroidRuntime(8352): FATAL EXCEPTION: GLThread 10 08-16 15:19:52.214: ERROR/AndroidRuntime(8352):

现在我也用Java端集成的Admob。当 Admob 通过一些委托(delegate)(例如 onReceiveAd )调用我的主类( myTest 见上文)时 - 我试图调用 testSetText() 并在此时添加我的 TextView - 和一切正常!

所以我认为它与线程有关 - 但我不是这方面的专家,所以我非常需要一些帮助。

有什么建议吗?

最佳答案

我有同样的问题,但我刚刚修复并意识到 android 和 cocos2d-x 发生了什么。

基本上,在android系统中,只有创建UI的主线程才能更新UI本身。

因此您需要使用处理程序和消息来通知主线程更新 UI。

更进一步,当你通过JNI通过c/c++函数调用java方法时。

静态方法可能是最好的选择,你可以先抓取JavaVM,通过这个JavaVM和env获取staticmethodid。

希望对您有所帮助。

关于Android:将 Java View 添加到 OpenGl View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7050626/

相关文章:

android - Javacameraview 全宽作为边界布局的宽度

android - 无法请求 READ_EXTERNAL_STORAGE 权限

c++ - C++ 中的 NSNotificationCenter 等价物

ios - Applovin 识别广告类型(IOS, Objective-C )

cocos2d-x - 如何拉伸(stretch) Cocos2d-x 3.0 按钮以适应它们的文本内容?

c++ - 当我从父节点中删除一个节点时调用哪个方法

c++ - Cocos2d Portrait Mode 对象位置搞砸了

java - Android:如何存储用户位置并稍后在服务器端 Web 应用程序中显示用户走过的路线

android - Proguard 与 Ormlite "no such column"

android - Android 的重用技巧