JNI GetEnv()在JNI_OnLoad中返回null

时间:2015-10-01 11:20:16

标签: java android c++ android-ndk java-native-interface

出于某种原因,当我调用GetEnv()时,它返回NULL。 我知道这是从一个没有连接到VM对象的线程调用它时的正常行为,但在我的情况下,我是从JNI_OnLoad调用它,当我调用System.loadLibrary时调用它在JAVA上,它应该不是NULL。

JNI.h:

class JNI
{
public:

    static jint OnLoad( JavaVM * pJavaVM, void * reserved );

    static JNIEnv * GetEnv();

    // Etc...
};

JNI.cpp:

jint JNI::OnLoad( JavaVM * pJavaVM, void * reserved )
{
    static bool bFirstCall = true;

    if( ! bFirstCall )
    {
        LOGCAT_E( "Tnx::JNI::OnLoad() - Cannot call this function more than once." );
        return -1;
    }

    bFirstCall = false;

    LOGCAT_I( "Tnx::JNI::OnLoad() - Begin, pJavaVM = %p.", pJavaVM );

    s_pJavaVM = pJavaVM;

    try
    {
        JNIEnv * pEnv = GetEnv(); // THROWS HERE

        // More stuff...
    }
    catch( const exception & oExc )
    {
        LOGCAT_E( "Tnx::JNI::OnLoad() - Failed, exception : '%s'.", oExc.what() );
        return false;
    }
    catch( ... )
    {
        LOGCAT_E( "Tnx::JNI::OnLoad() - Failed, unknown exception." );
        return false;
    }

    LOGCAT_I( "Tnx::JNI::OnLoad() - End, success." );
    return JNI_VERSION_1_4;
}

JNIEnv * JNI::GetEnv()
{
    JNIEnv * const pEnv = NULL;

    if( NULL == s_pJavaVM )
        throw runtime_error( "Tnx::JNI::GetEnv() - s_pJavaVM is NULL." );

    s_pJavaVM->GetEnv( (void **) & pEnv, JNI_VERSION_1_4 );

    if( NULL == pEnv )
        throw runtime_error( "Tnx::JNI::GetEnv() - Failed to get JNI environment." );

    return pEnv;
}

jint JNICALL JNI_OnLoad( JavaVM * pJavaVM, void * reserved )
{
    return Tnx::JNI::OnLoad( pJavaVM, reserved );
}

.java:

public class XXXXActivity extends Activity
{
    static
    {
        System.loadLibrary( "XXXXNative" );
    }

    private native static boolean initializeNative( XXXXActivity XXXXActivity, TermScreenView termScreenView );

    private native static boolean finalizeNative();

    private native boolean initializeInstance();

    private native boolean finalizeInstance();

    private TermScreenView mTermScreenView = null;

    @Override
    protected void onCreate( Bundle savedInstanceState )
    {
        Log.v( "", "XXXXActivity#onCreate() - Begin." );

        super.onCreate( savedInstanceState );

        try
        {
            this.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE );

            setContentView( R.layout.activity_XXXX );
            mTermScreenView = (TermScreenView) findViewById( R.id.termScreenView );
        }
        catch( Exception exc )
        {
            exc.printStackTrace();
        }

        if( null == savedInstanceState )
        {
            Log.v( "", "XXXXActivity#onCreate() - First call to onCreate, initializing native layer." );

            if( ! (initializeNative( this, mTermScreenView ) && initializeInstance()) )
                Toast.makeText( getBaseContext(), "Failed to initialize", Toast.LENGTH_LONG ).show();
        }

        Log.v( "", "XXXXActivity#onCreate() - End." );
    }

    // Etc...
}

记录:

10-01 13:07:14.460: D/dalvikvm(29694): Trying to load lib /data/data/XXXX.XXXX/lib/libXXXXNative.so 0x41970d10
10-01 13:07:14.460: D/dalvikvm(29694): Added shared lib /data/data/XXXX.XXXX/lib/libXXXXNative.so 0x41970d10
10-01 13:07:14.463: I/XXXX.XXXX(29694): Tnx::JNI::OnLoad() - Begin, pJavaVM = 0x40f34948.
10-01 13:07:14.463: E/XXXX.XXXX(29694): Tnx::JNI::OnLoad() - Failed, exception : 'Tnx::JNI::GetEnv() - Failed to get JNI environment.'.
10-01 13:07:14.463: W/dalvikvm(29694): JNI_OnLoad returned bad version (0) in /data/data/XXXX.XXXX/lib/libXXXXNative.so 0x41970d10
10-01 13:07:15.123: D/dalvikvm(29694): threadid=1: still suspended after undo (sc=1 dc=1)

知道为什么它可能是NULL吗?感谢。

0 个答案:

没有答案