【问题标题】:Build error with MFMailComposeViewController in a libGDX / RoboVM project在 libGDX / RoboVM 项目中使用 MFMailComposeViewController 构建错误
【发布时间】:2014-06-18 20:44:10
【问题描述】:

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

进口和会员:

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 运行时库添加到我的主项目的构建路径中。如果我删除这两种方法,我的项目将毫无错误地构建。我还需要设置其他什么东西才能让它运行吗?

【问题讨论】:

    标签: java libgdx robovm


    【解决方案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. 提供实现argumentRobovmLauncher(robovm项目的主类)。

      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。这是自然的,也是意料之中的。您应该为要定位的每个平台提供特定于平台的接口实现。

    希望这会有所帮助。
    祝你好运。

    【讨论】:

    • 感谢详细的回复。
    • 很高兴知道它有帮助。
    猜你喜欢
    • 1970-01-01
    • 2016-02-12
    • 2019-08-20
    • 2018-06-09
    • 2016-06-14
    • 2015-11-22
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    相关资源
    最近更新 更多