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)