I’m writing a simple Android application in which some of the actions are implemented in JNI. The task is to perform some actions in a separate thread in the native part and then display the result in the corresponding field of the user interface.
public class MainActivity extends AppCompatActivity {
private static Handler staticHandler;
...
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
staticHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
binding.multilineText.setText(msg.what);
}
};
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
...
Button buttonStartThreads = findViewById(R.id.button2);
buttonStartThreads.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
start_runners();
}
});
}
@Override
protected void onDestroy() {
staticHandler = null;
super.onDestroy();
}
//Java method I'm calling from JNI
public static void sendMessage(int v){
Log.e("My Name->", "sendMessage called from JNI(" + v+ ")");
//staticHandler.sendEmptyMessage(0); // just the what() is filled with the id
}
...
public native void start_runners();
}
The native part has a method sendMessageFromJni, which calls SendMessage
from the Java part.
void sendMessageFromJni(const char* buffer, int bufferlen) {
JNIEnv * env;
int getEnvStat = javaVM->GetEnv((void **)&env, JNI_VERSION_1_4);
if (getEnvStat == JNI_EDETACHED) {
if (javaVM->AttachCurrentThread( &env, NULL) != 0) {
LOGE("Failed to attach");
return;
}
}
int value = 7;
jclass cls = env->FindClass("com/example/myapplication/MainActivity"); //<- return NULL
if(cls == NULL)
LOGE("cls == NULL");
jmethodID methodId = env->GetStaticMethodID(cls, "sendMessage", "(I)V");
env->CallStaticVoidMethod(cls, methodId, value);
}
So the call chain looks like this:
sendMessageFromJni
(C++) -> SendMessage
(Java) -> handler.handleMessage
(Java)
The problem is that if I uncomment the call in
public static void sendMessage(int v){
Log.e("My Name->", "sendMessage called from JNI(" + v+ ")");
//staticHandler.sendEmptyMessage(0); // just the what() is filled with the id
}
env->FindClass()
starts retuning NULL
in the native part.
I can’t figure out what the problem is