sm_pSharedApplication is false on specific Android smartphone

I develop a cocos2d-js game on Android and it runs fine on Nexus 5. On Sony Xperia C1505, Android 4.1.1 however, it stopps at following assertion in CCApplication.cpp and then crashes:

//////////////////////////////////////////////////////////////////////////
// static member function
//////////////////////////////////////////////////////////////////////////
Application* Application::getInstance()
{
CCAssert(sm_pSharedApplication, “”);
return sm_pSharedApplication;
}

The catlog lines:

D/Cocos2dxActivity( 2936): model=C1505
D/Cocos2dxActivity( 2936): product=C1505_1270-8762
D/Cocos2dxActivity( 2936): isEmulator=false
E/cocos2d-x assert( 2936): /Applications/MAMP/htdocs/42words/frameworks/runtime-src/proj.android/…/…/js-bindings/cocos2d-x/cocos/platform/android/CCApplication.cpp function:getInstance line:79
F/libc ( 2936): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 2966 (Thread-335)

I ran the app at an earlier development stage on this model. I think it was cocos2d-js 3.0alpha2.

What can I do?

It’s quite odd, the sm_pSharedApplication should be initialized since you instantiate an AppDelegate object, because AppDelegate is extended from Application, and the constructor of Application is like this:

Application::Application()
{
    CCAssert(! sm_pSharedApplication, "");
    sm_pSharedApplication = this;
}

And in the main.cpp of proj.android:

void cocos_android_app_init (JNIEnv* env, jobject thiz) {
    LOGD("cocos_android_app_init");
    AppDelegate *pAppDelegate = new AppDelegate();
}

The AppDelegate have been instantiated from the beginning, so sm_pSharedApplication should exist.

Can you post the constructor of your AppDelegate ?

The constructor is just like you posted it:

using namespace cocos2d;

void cocos_android_app_init (JNIEnv* env, jobject thiz) {
    LOGD(“cocos_android_app_init”);
    AppDelegate *pAppDelegate = new AppDelegate();
}

I do the same command: cocos run -p android, once with the Nexus plugged in and then with the Xperia plugged in. There is one anomaly with this Xperia. The SIM-card slot doesn’t work. Could that be the problem?

If you want, I could send it to you for testing …

So when the error happened, does the log “cocos_android_app_init” already shown ?

This is happening to me sometimes too.

Here is the crash dump

********** Crash dump: **********
Build fingerprint: 'samsung/jfltexx/jflte:4.4.2/KOT49H/I9505XXUFNC4:user/release-keys'
pid: 19589, tid: 19658, name: Thread-23257  >>> org.cocos2dx.hellocpp <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
Stack frame #00  pc 008bafe8  /data/app-lib/org.cocos2dx.hellocpp-31/libInteractiveBookReader.so (Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause+48): Routine Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause at <proj_path>/jni/../../cocos2d/cocos/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp:19
Stack frame #01  pc 00020bcc  /system/lib/libdvm.so (dvmPlatformInvoke+112)
Stack frame #02  pc 00051927  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
Stack frame #03  pc 000535d1  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+256)
Stack frame #04  pc 0002a060  /system/lib/libdvm.so
Stack frame #05  pc 00031510  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
Stack frame #06  pc 0002eba8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
Stack frame #07  pc 00063e75  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+336)
Stack frame #08  pc 00063e99  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
Stack frame #09  pc 00058b6b  /system/lib/libdvm.so
Stack frame #10  pc 0000d278  /system/lib/libc.so (__thread_entry+72): Routine ??
??:0
Stack frame #11  pc 0000d410  /system/lib/libc.so (pthread_create+240): Routine ??
??:0

So as we can see Cocos2dxRenderer.nativeOnPause is being called before Cocos2dxRenderer.nativeInit. This is a really weird behaviour from Android but can be easily prevented by checking in nativeInit has been called before calling nativeOnPause

So, check http://stackoverflow.com/questions/7345282/why-the-onpause-method-is-called-immediately-after-oncreate.

There is a very strong possibility of OnPause being called before onSurfaceCreated due to stupid ActivityManager behaviours.

Since I use my own custom renderer (Cocos2dxRenderer subclass) this is what I ended up doing

public class MyRenderer extends Cocos2dxRenderer {

private boolean bNativeInitCompleted = false;

@Override
public void handleOnPause() {
	if(!bNativeInitCompleted) return;
	super.handleOnPause();
}

@Override
public void onSurfaceCreated(GL10 pGL10, EGLConfig pEGLConfig) {
	super.onSurfaceCreated(pGL10, pEGLConfig);
	bNativeInitCompleted = true;
}

}
1 Like

@miguel12345 Thanks for your solution, @lavizrap can you test this and tell us whether it works ?

WOHAAA! It runs. Thanks a lot @miguel12345 and @pandamicro

The complete story for successors:

Create a file “MyRenderer.java” in frameworks/js-bindings/cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/lib of your project with following code:

package org.cocos2dx.lib;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView;

import org.cocos2dx.lib.Cocos2dxHelper;

public class MyRenderer extends Cocos2dxRenderer {

private boolean bNativeInitCompleted = false;

@Override
public void handleOnPause() {
    if(!bNativeInitCompleted) return;
    super.handleOnPause();
}

@Override
public void onSurfaceCreated(GL10 pGL10, EGLConfig pEGLConfig) {
    super.onSurfaceCreated(pGL10, pEGLConfig);
    bNativeInitCompleted = true;
}

}

In the file frameworks/js-bindings/cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java

Change line

this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());

to

this.mGLSurfaceView.setCocos2dxRenderer(new MyRenderer());

Then “cocos run -p android”

Thanks a lot for confirming it, we will consider to fix it in Engine too.

Thanks guys.
I fixed it in this PR: https://github.com/cocos2d/cocos2d-x/pull/7884.
There are other functions, such handleActionUp, handleOnResume, hope these functions will not be invoked before onSurfaceCreated.