Android Plugin problem

Hello.
I started to deal with plug-ins for android and ran into a few problems.

Extending UnityPlayerActivity

public class MainActivity extends UnityPlayerActivity

works just fine.

Sending message from Java to C#

UnityPlayer.UnitySendMessage("Main Camera", "onDialogClick", "Yes");

works also great.

But I can’t send message from Unity(C#) to Java

In my MainActivity class I got method

public void showDialog() {
	AlertDialog.Builder builder = new AlertDialog.Builder(inst);
	builder.setMessage("Are you sure?").setPositiveButton("Yes", inst.dialogClickListener)
		      .setNegativeButton("No", inst.dialogClickListener).show();
}

method is working fine if I call it from Java code.

but when I’m trying to do this from C#

try {	
	AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 
	AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); 
	jo.Call("showDialog");
				
} catch(System.Exception ex) {
	DebugConsole.LogWarning(ex.Message);
}

Application simply crashes! :frowning: Event try / catch block does not stop application crash.
I probably need to use Android NDK to perform this call. But I can not figure out how. Will be grateful for the help.

Do you have a method in your main activity that’s called “ddd” ? Because that’s the method you’re calling with jo.Call(“ddd”);

try jo.Call(“showDialog”);

Basically, it works like : jo.Call(“methodname”, parameters);

Sorry, that was a typo. I got method showDialog and I calling showDialog. But application is simply crashes(

My guess is that you are calling the function from the wrong thread. Android usually requires you to use the UI thread to open Dialogs, or change anything UI related.

jo.Call("runOnUiThread", new AndroidJavaRunnable(() => { jo.Call("showDialog"); }));

Thx a lot for helping.

But can you explain a little bit more, why it works like this?

jo.Call("runOnUiThread", new AndroidJavaRunnable(() => { jo.Call("showDialog"); }));

Works great for java function

public void showDialog() {
	 AlertDialog.Builder builder = new AlertDialog.Builder(inst);
	builder.setMessage("Are you sure?").setPositiveButton("Yes", inst.dialogClickListener)
		 .setNegativeButton("No", inst.dialogClickListener).show();
}

and

AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); 
jo.Call("returnData");

Works great for java function

public void returnData() {
	UnityPlayer.UnitySendMessage("Main Camera", "onDialogClick", "Data");
}

So what kind of operation by which streams should be handled? (sorry for my English :()
And where I can read about it. Explane more please.

As I understand if I call functions of “currentActivity” in main thread I can do what ever I want in that functions. Or I have some limits? And what about java thread and calling back to unity via “UnitySendMessage

In my understanding if I call
UnityPlayer.UnitySendMessage("My Game Object", "MyFunctin", "myData")

function from Main thread (currentActivity) I can do any operation in “MyFunctin”, but if I call it from sub thread, call will be performed, but using unity API inside “MyFunctin” can crash the player. Am I right?

It has nothing to do with the function being a called from java or from inside Unity per se. It’s just that the Unity main thread is not the same as the Android main thread (UI Thread). As descried here Processes and threads overview  |  App quality  |  Android Developers , any UI manipulation has to be performed on the Android main thread.

When it comes to the UnityPlayer.UnitySendMessage() call, that should be ok to invoke from any thread - it is an async call that will be picked up by the Unity main thread during the next frame update.

1 Like

Thx for helping me out. Now everising clear, and I can start write plugins.

One last question.
Can you explain how to use this method?

As I understand this some kind of another methods of callig java methods from main (UI) thread. Do I need to download Android NDK for using it?

Thx for help one more time :slight_smile:

If you spawn your own threads that are not normally connected to the DalvikVM you should use AndroidJNI.AttachCurrentThread() to ensure local references will survive. This is pretty advanced stuff if you are not already familiar with JNI. I recommend reading up on the JNI spec before venturing down this road, especially the parts about local, global references and, how to push/pop local stack frames.
http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html

That said, if you can avoid spawning your own threads, and stick with AndroidJavaObject/Class, I think you are much better off. JNI can be tricky and it’s easy to end up in a state where you will be hit by localref table overflows etc.

Got it. Thank you for your help.

Hi lacost I am trying to use unitySendMessage but i did not succeed can you give me a sample code that work fine,

PM sent