指定 Android 项目依赖项(在 Eclipse 中)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/573581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:18:11  来源:igfitidea点击:

Specifying Android project dependencies (in Eclipse)

androideclipsedependencies

提问by Henrik Gustafsson

I have two Android projects, a 'library project' containing a custom layout, and an 'application project' containing an application which uses the layout.

我有两个 Android 项目,一个包含自定义布局的“库项目”和一个包含使用该布局的应用程序的“应用程序项目”。

Everything seems to build and execute fine, except that the visual layout editor throws a ClassNotFoundException (which I assume is a bug in the plug-in), but when I try to start to make use of the attributes I defined for the custom layout in the xml, I can no longer build. That is; this works:

一切似乎都很好地构建和执行,除了可视化布局编辑器抛出 ClassNotFoundException(我认为这是插件中的错误),但是当我尝试开始使用我为自定义布局定义的属性时xml,我不能再构建了。那是; 这有效:

<?xml version="1.0" encoding="utf-8"?>
<se.fnord.android.layout.PredicateLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
  <TextView
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="asdfasdf"
    />
</se.fnord.android.layout.PredicateLayout>

Whereas this does not:

而这不会:

<?xml version="1.0" encoding="utf-8"?>
<se.fnord.android.layout.PredicateLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fnord="http://schemas.android.com/apk/res/se.fnord.android"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
  <TextView
    fnord:layout_horizontalSpacing="1px"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="asdfasdf"
    />
</se.fnord.android.layout.PredicateLayout>

The build fails with a message from aapt:

构建失败并显示来自 aapt 的消息:

ERROR No resource identifier found for attribute 'layout_horizontalSpacing' in package 'se.fnord.android'

错误在包“se.fnord.android”中找不到属性“layout_horizo​​ntalSpacing”的资源标识符

The resource identifier does exist in the R-file and attrs.xml contained the library project, and if I put the layout code and resources directly in the application project everything works fine. The layout_horizontalSpacing attribute (and layout_verticalSpacing) is a custom attribute used in the PredicateLayout.LayoutParam class to specify the distance to the next widget.

资源标识符确实存在于 R 文件中,并且 attrs.xml 包含库项目,如果我将布局代码和资源直接放在应用程序项目中,一切正常。layout_horizo​​ntalSpacing 属性(和 layout_verticalSpacing)是 PredicateLayout.LayoutParam 类中使用的自定义属性,用于指定到下一个小部件的距离。

So far I've tried the standard eclipse ways by specifying project references and build path project dependencies. I was also told to try the tag in the application manifest, which did not help.

到目前为止,我已经通过指定项目引用和构建路径项目依赖项尝试了标准的 Eclipse 方式。我还被告知尝试应用程序清单中的标签,但没有帮助。

So, what do I need to do for the references in the xml-file to work?

那么,我需要做什么才能使 xml 文件中的引用起作用?

I don't know if it's relevant, but the 'library' manifest looks like this:

我不知道它是否相关,但“库”清单如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="se.fnord.android"
      android:versionCode="1" android:versionName="1.0.0">
</manifest>

The 'application' manifest like this:

“应用程序”清单如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="se.fnord.appname"
      android:versionCode="1" android:versionName="1.0.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AppName"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

(The 'PredicateLayout', btw, is a cleaned-up version of this).

(在“PredicateLayout”,顺便说一句,是的清理后的版本)。

采纳答案by Joseph Johnson

The earliest versions of Android sdk did not support sharing at the source code level in a nice way. You could jar up your .class files and then add that into the lib/ folder, but this solution did not allow direct sharing of source code and just as importantly did not support the sharing of resources or aidl files.

最早版本的 Android sdk 不支持在源代码级别以一种很好的方式共享。您可以 jar up .class 文件,然后将其添加到 lib/ 文件夹中,但该解决方案不允许直接共享源代码,同样重要的是不支持共享资源或 aidl 文件。

Then in May 2010, Android introduced the Library Project mechanism. A Library Project is structured very similar to a normal Android project, but rather than being used to produce an apk, it serves only to provide code and resources to other projects. Like an ordinary project, a Library Project usually contains src and res folders, along with an AndroidManifest.xml file; however the manifest should be mostly empty with the exception of the manifest element and the package attribute (no longer true - you can now declare Activities and other components in the manifest of your Library Project). In addition, the project.properties file for a Library Project needs to contain the property:

然后在 2010 年 5 月,Android 引入了 Library Project 机制。库项目的结构与普通的 Android 项目非常相似,但它不是用于生成 apk,而是仅用于向其他项目提供代码和资源。与普通项目一样,Library Project 通常包含 src 和 res 文件夹,以及一个 AndroidManifest.xml 文件;但是清单应该大部分是空的,清单元素和包属性除外(不再为真 - 您现在可以在库项目的清单中声明活动和其他组件)。此外,库项目的 project.properties 文件需要包含以下属性:

"android.library=true"

To make a reference from an ordinary (apk-producing) project to a Library Project, you need to add a "android.library.reference.N" line into the project.properties file of the ordinary project. For example, if my main project wants to point to two Library Projects, my project.properties file for the main project would include the following:

要将普通(apk-生产)项目引用到库项目,需要在普通项目的project.properties文件中添加“android.library.reference.N”行。例如,如果我的主项目想要指向两个库项目,则主项目的 project.properties 文件将包含以下内容:

android.library.reference.1=../LibraryA
android.library.reference.2=../../LibraryB

where the ../ and the ../../ are the respective paths from the main project to the Library Projects (this is just an example). Note this list of references is 1-based and it should not contain gaps or duplicates. Google is well aware that this is not a perfect system but it was a reasonable solution that was compatible with Ant and Eclipse. Generally speaking, your IDE will attempt to maintain these files for you, but sometimes you may need to edit them by hand.

其中 ../ 和 ../../ 分别是从主项目到库项目的路径(这只是一个例子)。请注意,此参考文献列表以 1 为基础,不应包含空白或重复项。Google 很清楚这不是一个完美的系统,但它是一个与 Ant 和 Eclipse 兼容的合理解决方案。一般来说,您的 IDE 会尝试为您维护这些文件,但有时您可能需要手动编辑它们。

At first Library Projects did not support the following:

起初,Library Projects 不支持以下内容:

  1. Library Projects pointing to other Library Projects
  2. Library Projects containing aidl files
  3. Library Projects containing assets folder
  1. 指向其他库项目的库项目
  2. 包含 aidl 文件的库项目
  3. 包含资产文件夹的库项目

However subsequent sdk releases solved all of these problems.

然而,随后的 sdk 版本解决了所有这些问题。

For more information on Library Projects, see the official documentation.

有关库项目的更多信息,请参阅官方文档

回答by JPMagalhaes

Export the project as a JAR is not the right way to link a library project to your app project through Properties -> Java Build Path -> Library. Neither it is to link the project as a required project through Properties -> Java Build Path -> Projects.

将项目导出为 JAR 并不是通过 Properties -> Java Build Path -> Library 将库项目链接到您的应用程序项目的正确方法。也不是通过 Properties -> Java Build Path -> Projects 将项目链接为必需项目。

First of all, read the Library projects topic at Android developers -> Developing -> Managing projects: http://developer.android.com/guide/developing/projects/index.html#LibraryProjectsAfter this, read the Setting up a Library Project and Referencing a library project topics again at Android Developers -> Developing -> Managing projects -> From Eclipse With ADT

首先,阅读 Android 开发者 -> 开发 -> 管理项目中的库项目主题:http: //developer.android.com/guide/developing/projects/index.html#LibraryProjects之后,阅读设置库在 Android 开发人员 -> 开发 -> 管理项目 -> 从 Eclipse 使用 ADT 再次进行项目和引用库项目主题

So... the steps are:

所以......步骤是:

  1. Create your Library project normally as a Android Project;
  2. Set "is library" in the project properties -> Android Create your App project normally;
  3. Add a reference to your library in the project properties -> Android -> Add.
  1. 通常将您的库项目创建为 Android 项目;
  2. 在项目属性中设置“is library” -> Android 正常创建你的App项目;
  3. 在项目属性 -> Android -> 添加中添加对您的库的引用。

After this you can use all classes, components (activities, services, providers, receivers), resources etc.

在此之后,您可以使用所有类、组件(活动、服务、提供者、接收者)、资源等。

Ex.: to reference any resources in a xml layout, for example, you should use @mylib:id/my_id or @mylib:layout/my_lib_layout

例如:要引用 xml 布局中的任何资源,例如,您应该使用 @mylib:id/my_id 或 @mylib:layout/my_lib_layout

Obs.: If you use components of your library in app project, you must replicate them in your app manifest.

观察:如果您在应用项目中使用库的组件,则必须在应用清单中复制它们。

回答by Edwin

Also, I got the attributes working, but not in the way it should work I think.

另外,我使属性正常工作,但不是我认为应该工作的方式。

You must use as the namespace in the element that uses your custom attributes, the namespace of your main app, not that of the library project. So, in your example, if you specify for the value of "xmlns:fnord" the namespace of your app project, it works.

您必须在使用自定义属性的元素中使用主应用程序的命名空间,而不是库项目的命名空间。因此,在您的示例中,如果您为“xmlns:fnord”的值指定应用程序项目的命名空间,则它可以工作。

Also, when reading the custom attributes in your custom PredicateLayout(Context,AttributeSet)constructor, you must specify the app's namespace as well in calls to attributes.getAttributeValue().

此外,在您的自定义PredicateLayout(Context,AttributeSet)构造函数中读取自定义属性时,您还必须在对attributes.getAttributeValue().

Which is a pain, since that code is in your library app which doesn't/shouldn't know about the app project it is used in. I worked around that by having the app call a static method ViewUtil.setAttributeNamespace(appNamespace) in my app's onCreate(), and the library's custom views use that namespace to retrieve the custom attributes. The attrs.xml file can then remain in the library project as well. Now the only ugly thing is that the layout XML must use the app's namespace on custom views, so you can't put those layout XML's in the library project.

这是一个痛苦,因为该代码在您的库应用程序中,它不/不应该知道它所使用的应用程序项目。我通过让应用程序调用静态方法 ViewUtil.setAttributeNamespace(appNamespace) 来解决这个问题我的应用程序的 onCreate() 和库的自定义视图使用该命名空间来检索自定义属性。然后 attrs.xml 文件也可以保留在库项目中。现在唯一丑陋的是布局 XML 必须在自定义视图上使用应用程序的命名空间,因此您不能将这些布局 XML 放在库项目中。

回答by Hans Malherbe

Export your library project as a JAR and reference it in your application project's "Java Build Path" as a JAR.

将您的库项目导出为 JAR,并在应用程序项目的“Java 构建路径”中将其作为 JAR 引用。

回答by Joseph Johnson

The "Export your library as a jar" solution" only works if your library project contains source code only. In this case the OP's question mentions that his library project contains ui-related stuff.

仅当您的库项目仅包含源代码时,“将您的库导出为 jar”解决方案才有效。在这种情况下,OP 的问题提到他的库项目包含与 ui 相关的东西。

We have the exact same issue on my team of wanting to have library projects that hold ui-related source and resources. We ended up overhauling our Ant build system in order to have applications engulf the library projects during build time. Unfortunately no solution of this sort seems to be compatible with Eclipse and this is a major source of frustration for the developers. We are still able to use Eclipse, but we have to jump through hoops to get it working and have to put up with diminished productivity.

我的团队也有同样的问题,希望拥有包含 ui 相关源代码和资源的库项目。我们最终彻底改造了我们的 Ant 构建系统,以便在构建期间让应用程序吞没库项目。不幸的是,此类解决方案似乎与 Eclipse 不兼容,这是开发人员沮丧的主要来源。我们仍然可以使用 Eclipse,但我们必须跳过障碍才能让它工作,并且不得不忍受生产力下降的问题。