11

我试图让一个游戏项目完全独立于平台,所以我把它分成三个项目,从低级到顶级 android 特定级别:引擎、游戏、android 游戏。

错误中涉及的类/接口是:

  1. (低级)引擎项目定义了这个接口:

    com.myteam.engine.IGame
    
  2. (中级)平台独立游戏项目定义了这些类:

    com.myteam.myproject.Game
    com.myteam.myproject.MyProject (derived from com.myteam.myproject.Game)
    
  3. (顶级)android项目实现活动等:

    com.myteam.myproject.android.MyAndroidActivity (using com.myteam.myproject.MyProject)
    

所有的编译都很好,并且在 Windows 下完美运行(在第 3 级的另一个 Windows 项目使用前两个)。

但是当使用 ADT 运行时,它会在 Activity 启动时在运行时失败。Android 应用程序基本上只显示一个带有“NoClassDefFoundError com.myteam.myproject.MyProject”异常的调用堆栈。

该异常似乎是由其超类(或超类的接口)在加载/解析时引起的,因为 LogCat 输出显示:

12-20 19:51:51.897: D/ddm-heap(218): Got feature list request
12-20 19:51:52.207: I/dalvikvm(218): Failed resolving Lcom/myteam/myproject/Game; interface 18 'Lcom/myteam/engine/IGame;'
12-20 19:51:52.217: W/dalvikvm(218): Link of class 'Lcom/myteam/myproject/Game;' failed
12-20 19:51:52.227: W/dalvikvm(218): Unable to resolve superclass of Lcom/myteam/myproject/MyProject; (52)
12-20 19:51:52.227: W/dalvikvm(218): Link of class 'Lcom/myteam/myproject/MyProject;' failed
12-20 19:51:52.227: E/dalvikvm(218): Could not find class 'com.myteam.myproject.MyProject', referenced from method com.myteam.myproject.android.MyAndroidActivity.onCreate
12-20 19:51:52.227: W/dalvikvm(218): VFY: unable to resolve new-instance 54 (Lcom/myteam/myproject/MyProject;) in Lcom/myteam/myproject/android/Youcode_AndroidActivity;
12-20 19:51:52.227: D/dalvikvm(218): VFY: replacing opcode 0x22 at 0x0008
12-20 19:51:52.227: D/dalvikvm(218): Making a copy of Lcom/myteam/myproject/android/Youcode_AndroidActivity;.onCreate code (88 bytes)

我尝试在 Android 游戏项目的“构建路径/顺序和导出”Eclipse 项目设置下添加前两个项目,如其他帖子和论坛中所述,但这并没有改变任何事情。

我的预感是 Manifest 或 Project 设置需要另外提及用于 apk 打包或运行时的包/类依赖项。有任何想法吗?

4

7 回答 7

12

我有一个三层的 Android/Java 应用程序,几乎和你一样:

  1. 用于低级网络通信的纯 Java 项目
  2. 用于抽象低级项目功能的纯 Java 项目
  3. 安卓应用

上面的每一件事都是一个单独的 Eclipse 项目,包含在一个工作区中。

这是您需要做的:

  1. 在 App 的项目属性->Java Build Path->Projects 下,添加 Java-only 项目
  2. 在 App 的项目属性->Java Build Path->Order and Export 下,检查 Java-only 项目(将它们标记为导出)

现在,您的应用程序应该可以构建和运行,而不会出现如下NoClassDefFoundError异常或错误:VFY

03-27 21:10:17.120: W/dalvikvm(420): VFY: unable to find class referenced in signature (Labstractionlayer/BaseStationManager;)
03-27 21:10:17.120: W/dalvikvm(420): VFY: unable to find class referenced in signature (Labstractionlayer/BaseStationManager;)
03-27 21:10:17.160: I/dalvikvm(420): Failed resolving Lcom/demo/log/AndroidLogWrapper; interface 253 'Lcommon/Logger/LogWrapper;'
03-27 21:10:17.160: W/dalvikvm(420): Link of class 'Lcom/demo/log/AndroidLogWrapper;' failed
03-27 21:10:17.160: E/dalvikvm(420): Could not find class 'com.demo.log.AndroidLogWrapper', referenced from method com.demo.Application.onCreate
03-27 21:10:17.160: W/dalvikvm(420): VFY: unable to resolve new-instance 218 (Lcom/demo/log/AndroidLogWrapper;) in Lcom/demo/Application;
03-27 21:10:17.170: D/dalvikvm(420): VFY: replacing opcode 0x22 at 0x0003
03-27 21:10:17.170: D/dalvikvm(420): VFY: dead code 0x0005-003c in Lcom/demo/Application;.onCreate ()V
03-27 21:10:17.170: D/AndroidRuntime(420): Shutting down VM
03-27 21:10:17.170: W/dalvikvm(420): threadid=1: thread exiting with uncaught exception (group=0x40015560)
03-27 21:10:17.180: E/AndroidRuntime(420): FATAL EXCEPTION: main
03-27 21:10:17.180: E/AndroidRuntime(420): java.lang.NoClassDefFoundError: com.demo.log.AndroidLogWrapper

顺便说一句,在 ADT r17 之前,您只需要执行上述第 1 步(添加纯 Java 项目)。但从 r17 开始,您还需要执行第 2 步(标记仅 Java 项目以供导出)。

于 2012-03-28T18:05:04.363 回答
2

我找到了这个线程,它实际上对我有用,只要确保检查依赖项目

使用 jar 依赖项测试 Android 项目

于 2012-09-14T20:24:40.757 回答
2

将您的依赖项目的名称添加到您的 android 项目的 .claspath 文件中。像那样:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src"/>
    <classpathentry kind="src" path="gen"/>
    <classpathentry combineaccessrules="false" kind="src" path="/DependentProject1"/>
    <classpathentry combineaccessrules="false" kind="src" path="/DependentProject2"/>
    <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
    <classpathentry kind="output" path="bin"/>
</classpath>
于 2012-03-11T07:38:28.877 回答
2

据我所知,我很久以前一直试图为此找到一个简单的解决方案,使 ADT 导出具有依赖库类的最终 apk 的唯一方法是显式添加所有外部 lib.jar(从您的其他项目)到您的 Android 项目的构建路径。

当前版本的 Eclipse ADT 插件有一个非常不灵活的预定义构建生命周期(特别是在 dexing 步骤中),显然它不支持除了这三种类型的 Android 项目(经典、库和测试)之外的项目分组。换句话说,ADT 不知道如何使用构建路径下的常规 java 依赖项目构建您的 Android 项目,并自动将依赖项目生成的 lib.jar 添加到主项目的构建路径中(即使您将它们添加到 Order和导出列表),除非您明确地将外部 lib.jar 添加到其中。假设您将 C:\workspace\game\target\game.jar 和 C:\workspace\engine\target\engine.jar 添加到您的 android-game 项目的构建路径中,生成 dex 文件的命令应该是这样的:

java [-Xmx1024M, -jar, C:\android-sdk-r16\platform-tools\lib\dx.jar, --dex, --output=C:\workspace\android-game\target\classes.dex, C:\workspace\android-game\target\classes, C:\workspace\game\target\game.jar, C:\workspace\engine\target\engine.jar]

如果您打算采用一些外部构建工具来管理您的项目构建生命周期,我知道 Maven 在 Android 构建生命周期上提供了更灵活的配置。它支持多模块项目(项目分组),可以正确处理常规的java项目依赖。

我的知识基于 Eclipse,期待听到来自 Android 源或其他复杂 IDE 用户的一些噪音。

从 ADT 17.0.0 更新:

带有 ADT 17.0.0 的最新版本 SDK r17 声称现在可以正确处理此用例:

Eclipse 特定更改

名为“Library Projects”的动态类路径容器已重命名为“Android Dependencies”,因为它现在不仅仅包含 Library Projects。

该容器现在也将填充库项目引用的纯 Java 项目。如果这些 Java 项目还引用其他 Java 项目和/或 jar 文件,它们将被自动添加(也支持通过用户库引用的 jar 文件)。

重要提示:仅当引用设置为在引用项目中导出时才会发生这种情况。请注意,将项目或 jar 文件添加到项目构建路径时,这不是默认设置。库项目(及其 libs/*.jar 文件的内容)始终会被导出。此更改仅影响纯 Java 项目及其自己的 jar 文件。

再次检测并删除重复项(项目和 jar 文件)。

查看更新日志

于 2012-03-11T22:18:38.877 回答
1

我猜中级项目的Java Build 路径包括低级项目。您是否检查过那里的低级项目(选项卡“订购和导出”)?否则,低级项目依赖不会转发到高级项目,从APK中排除IGame,这实际上触发了失败。

但是,如果您的项目包含特定于 Android 的内容(如资源等),则此解决方案 AFAIK 将不起作用。

于 2012-03-16T09:56:55.683 回答
0

我知道这是一个老问题,但我发现了一种解决此错误的新方法,这可能会帮助其他人进行最近的更新。

我在 R.id 上使用switch/case语句时遇到了这个错误。“常数”。最新的更新不再将 R.java 声明视为代码中的常量,即使它们被声明为 final。发生的情况是 .apk 将编译和安装,但会产生那些 Lcom 错误。

为了解决这个问题(在 Eclipse 中),将光标放在开关声明上并使用 Ctrl+1 将开关转换为if then else的列表。请注意,如果您在case语句中有嵌套中断,则需要重写该代码块(可能使用额外的else)。

于 2013-07-07T16:50:24.670 回答
0

我怀疑你和你的项目。从我的角度来看,我看到你的设计很好。但你为什么要和Build Path / Order and Export? 老实说,从我使用 Eclipse 的第一天起,我就从来没有去过那个选项卡。

要将 jar 文件作为库导入,请使用 tab Libraries-> add external Jars。

很抱歉我不了解游戏编程,这只是一个建议:确保您的引擎适合 Android 支持的内容。例如 Android 不支持javax.imageio. 如果没有,应用程序可以使用外部 jar 进行编译,但可能会在运行时崩溃。

于 2012-03-17T22:48:40.143 回答