I want implement mechanism to run methods in main thread. I have code:
@Override
public void performOnMainThread(Runnable r) {
MainThreadTransporter transporter = new MainThreadTransporter(r);
SEL selector = new SEL("runOnMainThread:");
mainThreadHandler.performSelectorOnMainThreadWithObjectWaitUntilDone(selector, transporter, false);
}
and class:
@org.moe.natj.general.ann.Runtime(ObjCRuntime.class)
@ObjCClassName("MainThreadHandler")
@RegisterOnStartup
static class MainThreadHandler extends NSObject {
private MainThreadHandler(Pointer peer)
{
super(peer);
}
@Owned
@Selector("alloc")
public static native MainThreadHandler alloc();
@Selector("init")
public native MainThreadHandler init();
@Selector("runOnMainThread:")
private static void runOnMainThread(MainThreadHandler self, Selector cmd, IOSNativeUtilityFactory.MainThreadTransporter t) {
t.getRunnable().run();
}
}
With robovm that way works, but with MOE I see exception:
2017-01-10 13:10:54.198 myproject[2635:84834] -[MainThreadHandler runOnMainThread:]: unrecognized selector sent to instance 0x7fbf314adfc0
org.moe.natj.objc.ObjCException: -[MainThreadHandler runOnMainThread:]: unrecognized selector sent to instance 0x7fbf314adfc0
at apple.uikit.c.UIKit.UIApplicationMain(Native Method)
at com.company.AppClient.main(AppClient.java:20)
liliomk
(Kristóf Liliom - Migeran)
January 10, 2017, 12:17pm
2
Dear Ivan Bielko,
I would recommend using something like this:
public void runOnMain(Runnable r) {
Globals.dispatch_async(Globals.dispatch_get_main_queue(), r::run);
}
Test code:
@Override
public boolean applicationDidFinishLaunchingWithOptions(UIApplication application, NSDictionary launchOptions) {
Globals.dispatch_async(Globals.dispatch_get_global_queue(0, 0), () -> {
runOnMain(() -> {
System.out.println();
});
});
return true;
}
But if you want to use performSelectorOnMainThreadWithObjectWaitUntilDone, then:
import apple.NSObject;
import org.moe.natj.general.Pointer;
import org.moe.natj.general.ann.Owned;
import org.moe.natj.objc.SEL;
import org.moe.natj.objc.ann.Selector;
public class MainThreadPerformer extends NSObject {
@Owned
@Selector("alloc")
public static native MainThreadPerformer alloc();
@Selector("init")
public native MainThreadPerformer init();
private Runnable runnable;
protected MainThreadPerformer(Pointer peer) {
super(peer);
}
@Selector("run")
public void run() {
if (runnable != null) {
runnable.run();
}
}
public void dispatchAsync() {
performSelectorOnMainThreadWithObjectWaitUntilDone(new SEL("run"), null, false);
}
public static void dispatchAsyncOnMain(Runnable pRunnable) {
if (pRunnable == null) {
throw new NullPointerException();
}
final MainThreadPerformer performer = MainThreadPerformer.alloc().init();
performer.runnable = pRunnable;
performer.dispatchAsync();
}
}
Test code:
@Override
public boolean applicationDidFinishLaunchingWithOptions(UIApplication application, NSDictionary launchOptions) {
Globals.dispatch_async(Globals.dispatch_get_global_queue(0, 0), () -> {
MainThreadPerformer.dispatchAsyncOnMain(() -> {
System.out.println();
});
});
return true;
}
Best Regards,
Kristóf
1 Like
Thank you. Everything works fine.