1

我正在尝试将功能添加到现有的 iOS libGDX 应用程序(使用 RoboVM),以便在按下 scene2d.ui 按钮时,显示一个 MFMailComposeViewController 弹出窗口,其中附加了一组预定义的 CSV 文件,这些文件存储在应用程序的 Library > local文件夹。这是我到目前为止的代码:

进口和成员:

import org.robovm.apple.foundation.*;
import org.robovm.apple.messageui.MFMailComposeResult;
import org.robovm.apple.messageui.MFMailComposeViewController;
import org.robovm.apple.messageui.MFMailComposeViewControllerDelegate;
import org.robovm.apple.uikit.*;
import org.robovm.objc.ObjCObject;

private UIWindow mailWindow;
private UIViewController mailViewController;
private MFMailComposeViewController mailPicker;

方法:

private void createMailWindow() 
{
    mailWindow = new UIWindow(UIScreen.getMainScreen().getBounds());
    mailViewController = new UIViewController();
    mailWindow.setRootViewController(mailViewController);
}

private void sendEmail(String fileName, String subject, String body) 
{
    mailPicker = new MFMailComposeViewController();
    mailPicker.addStrongRef(mailWindow);
    String path = NSBundle.getMainBundle().getResourcePath();

    if (fileName != null)
    {
        path = path.substring(0, path.lastIndexOf('/')) + "/Library/local/" + fileName;
    }

        MFMailComposeViewControllerDelegate delegate = new MFMailComposeViewControllerDelegate()
        {
            public void mailComposeControllerDidFinish(MFMailComposeViewController controller, MFMailComposeResult result, NSError error) 
            {
                controller.dismissViewController(true, null);
                mailPicker.removeFromParentViewController();
                mailPicker.removeStrongRef(mailWindow);
                mailWindow.setHidden(true);
                mailPicker = null;
            }

            @Override
            public void didFinish(MFMailComposeViewController controller, MFMailComposeResult result, NSError error) 
            {

            }
        };

        mailPicker.setMailComposeDelegate(delegate);
        mailPicker.addStrongRef((ObjCObject) delegate);

        if (fileName != null)
        {
                // attach CSVs here...
        }

        mailPicker.setSubject((subject != null ? subject : "Test Results"));
        mailPicker.setMessageBody((body != null ? body : "Please find attached the latest results data."), false);

        if (MFMailComposeViewController.canSendMail())
        {
            mailWindow.getRootViewController().presentViewController(mailPicker, true, null);
            mailWindow.makeKeyAndVisible();
        }
    }
}

我有这段代码,并且 Eclipse 在我尝试构建之前不会标记任何问题,因此我收到以下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: org/robovm/rt/bro/NativeObject
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at com.mmu.cfa.DesktopMain.main(DesktopMain.java:26)
Caused by: java.lang.ClassNotFoundException: org.robovm.rt.bro.NativeObject
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 49 more

我已将 RoboVM Cocoa Touch 库和 RoboVM 运行时库添加到我的主项目的构建路径中。如果我删除这两种方法,我的项目将毫无错误地构建。我还需要设置其他东西来让它运行吗?

4

1 回答 1

1

问题

在 Libgdx 应用程序中,主项目由所有支持平台的项目共享。

所以主项目必须包含平台无关的代码

RoboVM Cocoa Touch LibraryRoboVM Runtime Library依赖于平台,只能在 iOS 上运行,不能在桌面、android、html 等上运行。


解决方案

  1. 从主项目中删除RoboVM Cocoa Touch LibraryRoboVM Runtime Library依赖项。
  2. 将这些依赖项添加到 RoboVM 项目。(如果它们不存在。)
  3. 创建一个表示您在主项目中需要的功能的界面。

    public interface EmailHandler {
        public void createMailWindow();
        public void sendEmail(String fileName, String subject, String body);
    }
    
  4. 使用您已经编写的代码在 robovm 项目中创建一个实现类。

    public class RobovmEmailHandler implements EmailHandler {
    
        @Override
        public void createMailWindow() {
            // Your code goes here.
        }
    
        @Override
        public void sendEmail(String fileName, String subject, String body) {
            // Your code goes here.
        }
    }
    
  5. EmailHandler 参数添加到ApplicationListener(主项目中的主游戏类)的构造函数中。

    public class MyAwesomeGame extends Game {
    
        private EmailHandler emailHandler; // Use it wherever you like.
    
        public MyAwesomeGame(EmailHandler emailHandler) {
            this.emailHandler = emailHandler;
            // Rest of constructor.
        }
    }
    
  6. 在(robovm 项目的主类)中提供实现参数。RobovmLauncher

    public class RobovmLauncher extends IOSApplication.Delegate {
    
        @Override
        protected IOSApplication createApplication() {
            EmailHandler emailHandler = new RobovmEmailHandler();
            IOSApplicationConfiguration config = new IOSApplicationConfiguration();
            return new IOSApplication(new MyAwesomeGame(emailHandler), config);
        }
    }
    

注意:
其他平台的项目会开始向你大喊大叫,EmailHandler向他们提供一个。这是自然的,也是意料之中的。您应该为要定位的每个平台提供特定于平台的接口实现。

希望这可以帮助。
祝你好运。

于 2014-06-19T04:05:06.107 回答