Java JNI GetEnv()在JNI_OnLoad中返回null

Java JNI GetEnv()在JNI_OnLoad中返回null,java,android,c++,android-ndk,java-native-interface,Java,Android,C++,Android Ndk,Java Native Interface,出于某种原因,当我调用GetEnv()时,它返回NULL。 我知道,当从没有连接到VM对象的线程调用它时,这是一种正常行为,但在我的例子中,我是从JNI_OnLoad调用它的,当我调用JAVA上的System.loadLibrary时调用它,如果它不应该为空的话 JNI.h: class JNI { public: static jint OnLoad( JavaVM * pJavaVM, void * reserved ); static JNIEnv * GetEnv()

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

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...
}
日志:


知道为什么它可能是空的吗?谢谢。

您应该从
GetEnv
检查返回值。可能是
JNI\u VERSION\u 1\u 4
不受支持,在这种情况下
GetEnv
将返回
JNI\u版本
。谢谢您的回答。可能是这样,但它以前使用相同的NDK、相同的SDK、相同的eclipse版本、相同的JNI版本、相同的一切都可以工作。我只是在代码中做了一些大的修改之后才遇到这个问题。还是要检查一下以防万一。@Michael Well它会返回JNI_OK:(你已经声明了
pEnv
作为常量指针。如果你想让
GetEnv
更改
pEnv
(?)的值,我不明白你为什么要这么做。).是的,警察不应该在这里,我只是没有注意到。但在移除警察后,我仍然遇到了问题:(我也尝试过更改为JNI 1.6,但行为相同。您应该检查
GetEnv
的返回值。可能是
JNI\u版本1\u 4
不受支持,在这种情况下
GetEnv
将返回
JNI\u版本
。感谢您的回答。可能是这样,但它以前使用相同的NDK、相同的SDK、sa我的eclipse版本,相同的JNI版本,所有的东西都一样。我只是在代码中做了一些大的更改后才遇到这个问题。我还是要检查一下,以防万一。@Michael,它会返回JNI_OK:(您已将
pEnv
声明为常量指针。如果您打算让
GetEnv
更改
pEnv
(?)的值,我不明白您为什么要这样做。是的,常量不应该在这里,我只是没有注意到。但在删除常量后,我仍然遇到了问题。)(我也试着改为JNI1.6,但行为相同。
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)