Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Renegade

Alter Hase

  • »Renegade« ist der Autor dieses Themas

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

1

20.06.2016, 22:16

Callback von Unity/C# an Android/Java übergeben

Hey Leute,
wie der Titel schon sagt, interessiert mich ob es möglich ist über die Call-Methode von der AndroidJavaObject-Klasse (http://docs.unity3d.com/ScriptReference/…bject.Call.html) in Unity auch Callbacks an Java weiter zu geben. Kann man in Java diese dann problemlos Invoken?
Hier mal ein Beispiel:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class AndroidBridge {

    AndroidJavaClass _androidJavaUnityClass;
    AndroidJavaObject _currentActivity;

    public AndroidBridge() {
        _androidJavaUnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        _currentActivity = _androidJavaUnityClass.GetStatic<AndroidJavaObject>("currentActivity");
    }

    public void Foo() {
        Do(Callback);
    }

    void Do(Action<int> callback) {
        _currentActivity.Call("do", callback);
    }

    void Callback(int message) {
        //Do something fancy
    }
Liebe Grüße,
René

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

2

21.06.2016, 08:28

Wüsste jetzt nicht was dagegen spricht. Callbacks sind in Java auch nur Methoden. Ausprobiert?

Renegade

Alter Hase

  • »Renegade« ist der Autor dieses Themas

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

3

21.06.2016, 13:02

Noch nicht, aber ich sehe im Netz auch keine Möglichkeit für Delegates oder Actions in Java. Hierzu finde ich, dass es in Java keine Delegates gibt. Stattdessen wird überall mit Schnittstellen gearbeitet. Wie müsste denn die Methode auf Java Seite aussehen, die hier von der Do-Methode aufgerufen wird?
Liebe Grüße,
René

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Renegade« (21.06.2016, 13:07)


Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

4

21.06.2016, 15:10

Ich bezweifle zugegebenermaßen, dass du aus Java-Code heraus direkt ein delegate aus dem managed Mono-Code aufrufen kannst. Immerhin läuft das eine in einer JVM, während das andere in Mono läuft. Es wird irgendeine Art von Indirektion nötig sein.
Was mir eingefallen wäre, wäre das Ausführen von Aufruf-Methoden, bei denen mit Strings mitgeteilt wird, welches Event gefeuert werden soll, und auf der anderen Seite werden die Listener aufgerufen, die sich dafür registriert haben.

Für die Java-Seite vielleicht interessant: Lambdas (Und das dort verwendet Interface)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

5

21.06.2016, 15:11

Du hast dir die Antwort schon selbst gegeben: Das ist dann ein Interface mit einer Methode, die aufgerufen wird. Allerdings spielt es vermutlich eine Rolle, was du aufrufen willst. Wenn du deiner Activity einfach eine Public Methode gibst oder deine Activities, die du benachrichtigen willst, ein Interface implementieren lässt, dann musst du die denke ich einfach aufrufen. Vielleicht in etwa so:

Java Activity:

Quellcode

1
2
3
4
5
6
7
8
9
10
public interface UnityNotifyable { 
    void onActivate();
}

public class MyActivity extends Activity implements UnityNotifyable {
    @override
    void onActivate(){
       //do what you want.
    }
}


C#:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
_androidJavaUnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

//wir nehmen mal an, das ist unsere MyActivity-Instanz
_currentActivity = _androidJavaUnityClass.GetStatic<AndroidJavaObject>("currentActivity");

//eigene Methode
_currentActivity.Call("onActiviate");

//andere Methode, die eine Activity laut Doku hat:
_currentActivity.Call("onPause");

Renegade

Alter Hase

  • »Renegade« ist der Autor dieses Themas

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

6

21.06.2016, 22:44

@Sacaldur: Sowas in der Art habe ich bereits vermutet. Was meinst du mit Aufruf-Methoden und String Übergabe? Mir ist wichtig das ich von Java aus zu Unity keine UnitySendMessage verwende, da ich mich mit der Bridge-Klasse auch sowieso nicht im MonoBehavior/Component Raum bewege. Ich brauche irgendwie Zugang zu den konkreten nicht-MonoBehaviour Klassen/Objekten in C# von Java aus.
@TrommBomml: Das beantwortet die Frage nicht. Bei dir fehlt die Callback-Übergabe von C# zu Java. Wie würde Java jetzt die mitgelieferte Callback aus C# aufrufen? In deinem Beispiel müsste die onActivate in Java ein Parameter mit dem Typ einer Methode haben und diese dann aufrufen um damit C# zu benachrichtigen.

PS: @Sacaldur: Inwiefern können Lambda Expressions bei der Lösung helfen?
Liebe Grüße,
René

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Renegade« (21.06.2016, 22:53)


Mirlix

Supermoderator

Beiträge: 451

Beruf: Developer Advocate

  • Private Nachricht senden

7

22.06.2016, 00:39

Ich denke du wirst wohl ein eigene Java Plugin[1] schreiben müssen, damit kannst du dann auch Callbacks in Java erhalten und solltest diese weiter an C# geben können. Habe aber selber so was noch nicht gemacht, sollte aber möglich sein.

[1]https://docs.unity3d.com/Manual/PluginsForAndroid.html

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

8

22.06.2016, 09:44

Ich habe es wie folgt gemeint: auf Java-Seite gibt es eine Methode, die aufgerufen wird, sobald innerhalb Unitys ein Callback aufgerufen werden soll. Dieser Methode wird über einen String mitgeteilt, welche Callbacks aufgerufen werden sollen, also quasi welches Event gerade ausgelöst wurde.
Wie das Weiterleiten an die Unity-Seite funktioniert, sollte in der Doku nachzulesen sein.
Auf Seiten Unitys wird dann anhand dieser Bezeichnung geschaut, welche Callbacks sich dort für dieses Event registriert haben, welche dann aufgerufen werden.

Wenn du in deinem Java-Code keine selbst-definierten Schnittstellen verwendest, kannst du auch Lambda-Ausdrücke hin und her reichen. Effektiv verhält sich das Programm dabei nicht anders, allerdings wird es so etwas angenehmer, den Code zu schreiben.
Für die Lösung selbst ist es evtl. nur dann hilfreich, wenn auch aus dem C# Code heraus Java-Callbacks aufgerufen werden sollen.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

9

22.06.2016, 10:05

Ah, jetzt habe ich verstanden was du willst. Du willst Java -> C#. Allerdings stelle ich mir immer ehr die Frage, was du damit konkret machen willst?

Renegade

Alter Hase

  • »Renegade« ist der Autor dieses Themas

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

10

22.06.2016, 12:12

Ganz allgemein geht es darum, dass Prozesse von Seitens Unity in Java angestoßen werden müssen und diese sich Rückmelden sobald der Prozess abgeschlossen ist. Das Problem dabei ist, das ich NICHT das Unity Message System verwenden kann, da es sich bei den beteiligten Skripten um KEINE Ableitungen von MonoBehaviour handelt und demzufolge sie nicht auf GameObjects platziert werden können, was eine zwingende Voraussetzung für das Unity Message System ist. (Welches die vorgeschlagene Variante in der Dokumentation von Unity ist, die Mirlix verlinkt hat)


Hier nochmal ein kleines Beispiel, welches aber nicht möglich ist, da Java keine Delegates versteht:

So könnte die C# Seite aussehen:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public delegate void Message(int message);

public class AndroidBridge {

    AndroidJavaClass _androidJavaUnityClass;
    AndroidJavaObject _currentActivity;

    public AndroidBridge() {
        _androidJavaUnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        _currentActivity = _androidJavaUnityClass.GetStatic<AndroidJavaObject>("currentActivity");
    }

    public void Foo() {
        Do(Callback);
    }

    void Do(Message callback) {
        _currentActivity.Call("do", callback);
    }

    void Callback(int message) {
        //Do something fancy
       Debug.Log(message);
    }
}


So müsste die Java Seite aussehen. Das Problem ist der Parameter Message in der do-Methode. Wie mache ich hier Java bekannt, dass es sich um ein Funktionszeiger handelt?!

Quellcode

1
2
3
4
5
6
7
8
9
10
public class CurrentActivity {

    void do(Message message) {
       //do some stuff
       if(somethingHappened) {
          //this will Call the Callback(int message) Method in the above C# Skript with the argument 5
           message(5);
       }
    }
}
Liebe Grüße,
René

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »Renegade« (22.06.2016, 12:23)


Werbeanzeige