【问题标题】:How can I use Eclipse's new Xtend language in my Android project?如何在我的 Android 项目中使用 Eclipse 的新 Xtend 语言?
【发布时间】:2011-11-06 11:27:49
【问题描述】:

我想用 Xtend 语言编写 Java 类(仅仅是因为它更简洁),并将其编译回 Java 类,我可以在我的 Java 项目中使用这些类。就像咖啡脚本一样。我该怎么做?

我尝试像创建一个新类一样创建一个 Xtend 文件,但是我收到了这个错误:

在类路径中找不到强制库包 'org.eclipse.xtext.xbase.lib'

这会禁用智能感知(自动完成)。另外,即使我确实可以正常工作,我怎样才能将其编译为 Java 类?

【问题讨论】:

    标签: java android eclipse xtext xtend


    【解决方案1】:

    在 Xtend 中,内部类使用美元符号 ('$') 取消引用,静态成员使用双冒号 ('::') 访问。

    HelloAndroid 活动代码如下所示:

    class XtendActivity extends Activity {
    
        override void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R$layout::main);
        }
    }
    

    【讨论】:

    • Facepalm 谢谢!之后,就很明显了。至少它现在可以编译。尽管如此,它还是不会启动,因为 Android 在打包时包含所有 Xtext 库,并且那里有重复的文件(例如 about.html)(Android APK 构建器无法处理)。由于我们无法使用 Maven 构建 Xtend,因此拆卸和重建这些 JAR(仅限类)似乎是唯一的方法,不是吗?
    • 我试图从 repos 中获取所有资源,但事实证明您还必须包含来自 EMF 的依赖项,因为 XText 需要这些。我会等待一个不那么老套的方法:(
    • 啊,这解释了很多。如果这类东西出现在 Xtend 文档中,那将会很有用。至少现在我们知道了。顺便说一句,关于那些 JAR 文件,只需将它们作为 ZIP 文件打开并删除有问题的文件。据我所知,它不会破坏任何东西。
    • 而且您不需要 EMF 或 Xtext 罐子。唯一需要的是 org.eclipse.xtext.xbase.lib、org.eclipse.xtext.xtend2.lib(都只包含几个类)和 google guava。不幸的是,我们仍然检查 google injection,这实际上是没有必要的(我已经删除了它,所以它在下一个版本中不再存在)。您可以通过在类路径中的某处使用类型 com.google.inject.Inject 来使检查满意。
    • @NicodePoel 我是这样尝试的,但是发现也有间接依赖(插件依赖中没有列出),然后就这样了。我会再试一次,按照 Sven 的建议省略 EMF 和 Xtext jar。
    【解决方案2】:

    尝试了同样的事情,我可以确认启用 Xtend Nature 并添加三个 Xtend 库(前面提到过,'org.eclipse.xtext.xtend2.lib'、'org.eclipse.xtext.xbase.lib'和 'com.google.inject') 到项目的库中至少可以编译 Xtend 代码。但是,我也遇到了 R 类问题。

    仔细检查后,看起来 R 类的问题不在于它位于不同的目录中。将文件复制到具有不同名称的主源目录不会改变任何内容。相反,问题似乎在于 R 类是一个 static final 类,包含几个 static final 子类。如果我创建一个简单的纯 Java 包装类,它将对 R.layout.main(例如)的引用包装在一个普通方法中,并从我的 Xtend 代码中调用它,那么它会接受它并愉快地编译。

    之后,我遇到的下一个问题是 Android 编译器抱怨 'org.eclipse.xtext.xtend2.lib'、'org.eclipse.xtext.xbase.lib 中有重复的 about.html 和 plugin.properties 文件' 和 'com.google.inject'。通过从三个 .jar 文件中的两个中删除这些文件,这相对容易解决。我不确定它以后是否会破坏任何东西,但现在至少我有一个在 Android 模拟器上运行的 Xtend 代码的工作 sn-p。

    【讨论】:

      【解决方案3】:

      我刚刚编译它,虽然我现在不能导入“R”类。 执行以下步骤:

      首先,在 Eclipse 更新管理器中安装 Xtend SDK,通过输入“http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/”,展开节点“TMF Xtext-2.1. 0”,然后选择“Xtend2 SDK”。等待,然后重新启动 Eclipse。

      在您的 Eclipse Android 项目文件夹中,编辑文件“.project”(例如,通过在 OSX 上的终端中键入“nano .project”),并将其更改为类似于此(名称除外;您实际上可以复制全部内容,并将名称改回您的项目名称):

      <?xml version="1.0" encoding="UTF-8"?>
      <projectDescription>
      <name>TestAndroidXtend</name>
      <comment></comment>
      <projects>
      </projects>
      <buildSpec>
          <buildCommand>
              <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
              <arguments>
              </arguments>
          </buildCommand>
          <buildCommand>
              <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
              <arguments>
              </arguments>
          </buildCommand>
          <buildCommand>
              <name>org.eclipse.jdt.core.javabuilder</name>
              <arguments>
              </arguments>
          </buildCommand>
          <buildCommand>
              <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
              <arguments>
              </arguments>
          </buildCommand>
          <buildCommand>
              <name>com.android.ide.eclipse.adt.ApkBuilder</name>
              <arguments>
              </arguments>
          </buildCommand>
      </buildSpec>
      <natures>
          <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
          <nature>org.eclipse.jdt.core.javanature</nature>
          <nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
      </natures>
      

      然后将以下内容插入到文件“.classpath”的类路径元素中:

      <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
      

      我把它放在com.android.ide.eclipse.adt.ANDROID_FRAMEWORK的入口之前,也许你也应该这样做。

      回到 Eclipse,用 F5 刷新项目,然后在项目的顶层创建一个文件夹“META-INF”,并创建一个空文件“MANIFEST.MF”。将这些内容粘贴到其中:

      Manifest-Version: 1.0
      Bundle-ManifestVersion: 2
      Bundle-Name: Xtend Tutorial
      Bundle-SymbolicName: xtend.tutorial
      Bundle-Version: 2.1.0.qualifier
      Bundle-Vendor: Eclipse Modeling
      Bundle-RequiredExecutionEnvironment: J2SE-1.5
      Require-Bundle: org.eclipse.xtext.xtend2.lib;bundle-version="2.0.0",
       org.junit4,
       org.aopalliance;bundle-version="1.0.0"
      

      对您的项目执行“项目”->“清理”,您现在可以创建和使用 Xtend 类。

      如前所述,我无法导入 R 类,也许 Xtend 只是在普通的“src”文件夹中查找类文件。

      【讨论】:

      • 你用 xtend 的包替换了包,我认为这就是它停止生成 R 文件的原因。
      • 它并没有停止生成文件,我无法在 .xtend 类中使用它 - 如果您提出问题,至少在猜测之前尝试答案。
      【解决方案4】:

      到目前为止,我还没有做过任何 Android 开发。但是 Xtend 代码是针对瘦运行时库(用 Java 编写的)编译的。它主要只是三个罐子: - org.eclipse.xtext.xtend2.lib - org.eclipse.xtext.xbase.lib - com.google.collect

      它们都安装在eclipse中,所以你应该在你安装的plugins文件夹中找到它们。我们通常使用 OSGI 和 PDE 将它们放在类路径上,但它实际上只是一个类路径依赖。

      Xtend 可以像 Java 一样导入类路径中的所有内容。它重用了 Java 项目配置以及 Java 开发工具。因此,只要您在类路径上有“R”类,它就可以工作。请在 bugs.eclipse.org (在 Modeling/TMF/Xtext 下)提交一个 bugzilla,如果您不能引用它,尽管您可以从 Xtend 文件旁边的 Java 中引用它。并提供一个小例子和一些额外的解释。

      【讨论】:

      • 我想你很清楚我如何能够实现这一点,但是你能否提供一个更简洁的答案(逐步)关于我如何在任何 Java 项目中实现这一点?
      • @sven-efftinge:这并不容易,因为这似乎与动态生成的 R 类有关。一个简单的例子是不可能的,因为你需要安装在 eclipse 中的 ADT 工具才能工作。
      【解决方案5】:

      还有一个问题:确保您的参数名称不与 R.java 中的任何内容冲突。

      我使用向导创建了一个 (Java) Activity,复制了代码,删除了 Activity,并在其位置创建了 MainActivity.xtend,如下所示:

      
      public class MainActivity extends Activity {
      
          override void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R$layout::activity_main);
          }
      
          override boolean onCreateOptionsMenu(Menu menu) {
              getMenuInflater().inflate(R$menu::activity_main, menu);
              return true;
          }
      

      在 .xtend 文件中看起来不错,但由于生成的 Java 代码没有构建

        public boolean onCreateOptionsMenu(final Menu menu) {
          MenuInflater _menuInflater = this.getMenuInflater();
          _menuInflater.inflate(menu.activity_main, menu);
          return true;
        }

      目前不喜欢 activity_main。

      我花了几分钟才发现“menu”参数覆盖了 R.menu.activity_main。 一旦我将 .xtend 的“menu”参数更改为“optionsMenu”,它就可以正常工作了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-16
        • 1970-01-01
        • 1970-01-01
        • 2014-10-31
        相关资源
        最近更新 更多