Java Question Events do not raise in a class but in Main-module it is working

moster67

Expert
Licensed User
Longtime User
I am bit stuck with an issue regarding raising events:

I have the following Java-code for raising the event:

B4X:
    private void addVideoOutputEvents() {
        player.getMp().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {

            @Override
            public void timeChanged(MediaPlayer mediaplayer, long newTime){
                if (ba.subExists(eventName + "_time")) {
                    ba.raiseEvent(B4JVlcj.this, eventName + "_time", new Object[] { newTime });
                 
//                      Tests
//                    ba.raiseEventFromDifferentThread(B4JVlcj.this, null, 0, eventName + "_time", false, new Object[] {newTime});
//                    ba.raiseEvent2(B4JVlcj.this,false,eventName + "_time", false,new Object[] {newTime});
//                    ba.raiseEventFromUI(B4JVlcj.this, eventName + "_time", new Object[] { newTime });
                }
            }
        });

    }

The event raises just fine in B4J when I use the library directly in Main but if I make a B4J-Class where I call the library, the event will not fire in the Class and obviously the event will not fire in Main.
However, all method-calls (and properties) work just fine so I know that the target-module is correct.

This is the event and callback in Class-code:
B4X:
Private Sub vlc_Time (NewTime As Long)
    'callbacks
    Log(NewTime)
    If SubExists(mModule, event & "_Time") Then
        CallSub2(mModule, event & "_Time", NewTime)
    End If
End Sub

and here is the event in Main:
B4X:
Sub vlc1_Time (NewTime As Long)
    Log("Current time is " & NewTime)
End Sub

Any ideas?
 

DonManfred

Expert
Licensed User
Longtime User
The differents in the eventname is known and you are aware of?
In main the eventname is set to vlc1
In the class vlc

I ust want to make sure you are aware of the little difference... If you are using identical codes then i would have expected vlc in both.
 

moster67

Expert
Licensed User
Longtime User
I don't think that is the problem. The idea using a Class is that I can create more than one instance of VLC in a simple way with some utility methods in the class.

In my class-code:

B4X:
Public Sub Initialize(module As Object, eventname As String)
 
    'setting class globals
    mModule = module
    event = eventname
 
    vlc.Initialize(eventname)

End Sub

which I initialize from Main as follows:

B4X:
'AppStart
vlc1.Initialize(Me, "vlc1")
'vlc2.Initialize(Me, "vlc2")

'event
Sub vlc1_Time (NewTime As Long)
Log("Current time is " & NewTime)
End Sub

Using two instances of VLC in Main (without using a class) works just fine.

I must be doing something really stupid....
 

moster67

Expert
Licensed User
Longtime User
It should be said that I have never written my own classes in B4J (or B4A) so maybe I am missing something...
 

JordiCP

Expert
Licensed User
Longtime User
Don't know in B4J but in B4A from inline Java (inside a class) this works

B4X:
   ba.raiseEvent(null, eventName + "_time", new Object[] { newTime });
 

moster67

Expert
Licensed User
Longtime User
I tried that @JordiCP but it did not work.

By logging, I noted that my event in my Java-code is triggered but the eventName is wrong - it is "vlc1" and not "vlc" and logically the event in not found in my class since I initialize the instance from the class with "vlc". So I guess @DonManfred is correct.

So it seems like I cannot use a Class to initialize more than one instance of the VLC-object from Main. I am wondering if I need /can rewrite the logic of the Java-wrapper to handle it...
 

moster67

Expert
Licensed User
Longtime User
So it seems like I cannot use a Class to initialize more than one instance of the VLC-object from Main

On seconds thoughts, the methods are working and clearly distinguishes between different instances and the Java-wrapper knows which instance to handle.
It seems to happen only with the events (and the eventName).
I guess I am too tired to think clear. Better try again in a few days..
 

JordiCP

Expert
Licensed User
Longtime User
Second try using reflection. I have made a small example for myself and adapted to this case. Should work except for syntax errors.

You will need to keep an instance of the class from where the VLC-object is created

B4X:
import java.lang.reflect.Method;     // add 

Object myInstance;                     // add to your class globals

public void SetEventTarget(Object mInstance){   // add this method or add this parameter to the the initializer
  myInstance=mInstance;
}

private void addVideoOutputEvents() {

  player.getMp().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {

    @Override
    public void timeChanged(MediaPlayermediaplayer, long newTime){

      try{
        Method m = myInstance.getClass().getMethod("_"+eventName+"_time", long.class);
        Object result = m.invoke( myInstance, new Object[] { newTime });     
      }
      catch (Exception e) {
      }
    }
  });
}

...and, from the B4A class where you instantiate your VLC1_object...
B4X:
  ...
  VLC1.initialize2(......., Me)      'add instance to the initializer
  'or 
  VLC1.SetEventTarget(Me)      'a separate method
  ...
[CODE]
 

moster67

Expert
Licensed User
Longtime User
I finally found some time to look into this further. I tried your suggestion but I couldn't get it to work although I might have not understood your suggestion fully.

Anyway, since it is the evenname which is the problem, I resolved it by adding another argument to the initialize method which corresponds to the name of the instance of the vlc-object declared in the B4A class. In this way, the events are raised properly in the B4A-class and thus also in the main-class. I created also a second initialize method for the original code which already works fine with the eventname and when vlc is used directly in main (and not in a class).

I am still unsure if this is the correct way but all events are now raised properly and the events trigger fine from 2 separate vlc-objects at the same time so this has to do for now.
 

JordiCP

Expert
Licensed User
Longtime User
I am still unsure if this is the correct way
Well, if it does exactly what you want, then it is the correct way ;) (yes, I know this is not always true)

I will try my solution in my library (haven't done it yet) , since your post has made think that, as I have it implemented now, also it will only work with main.
 
Top