我有两个Android项目,一个包含自定义布局的"库项目",以及一个包含使用该布局的应用程序的"应用程序项目".
除了可视布局编辑器抛出一个ClassNotFoundException(我认为这是插件中的一个错误)之外,所有东西似乎都构建并执行得很好,但是当我尝试开始使用我为自定义布局定义的属性时xml,我再也无法构建了.那是; 这工作:
然而,这不是:
构建失败,来自aapt的消息:
错误在包'se.fnord.android'中找不到属性'layout_horizontalSpacing'的资源标识符
资源标识符确实存在于R文件中,而attrs.xml包含库项目,如果我将布局代码和资源直接放在应用程序项目中,一切正常.layout_horizontalSpacing属性(和layout_verticalSpacing)是PredicateLayout.LayoutParam类中使用的自定义属性,用于指定到下一个窗口小部件的距离.
到目前为止,我已经通过指定项目引用和构建路径项目依赖项来尝试标准的eclipse方法.我还被告知在应用程序清单中尝试标记,但没有帮助.
那么,我需要做什么才能使xml文件中的引用有效?
我不知道它是否相关,但'library'清单看起来像这样:
"应用程序"显示如下:
(在"PredicateLayout",顺便说一句,是的清理后的版本此).
最早版本的Android sdk不支持以很好的方式在源代码级别进行共享.您可以将您的.class文件包装起来,然后将其添加到lib /文件夹中,但此解决方案不允许直接共享源代码,同样重要的是不支持共享资源或aidl文件.
然后在2010年5月,Android推出了图书馆计划机制.库项目的结构与普通的Android项目非常相似,但它不是用于生成apk,而是仅为其他项目提供代码和资源.像普通项目一样,Library Project通常包含src和res文件夹,以及AndroidManifest.xml文件; 但是清单应该大部分是空的,除了manifest元素和package属性(不再是真的 - 您现在可以在Library Project的清单中声明Activities和其他组件).此外,库项目的project.properties文件需要包含属性:
"android.library=true"
要从普通(apk生成)项目引用到库项目,需要在普通项目的project.properties文件中添加"android.library.reference.N"行.例如,如果我的主项目想要指向两个库项目,我的主项目的project.properties文件将包括以下内容:
android.library.reference.1=../LibraryA android.library.reference.2=../../LibraryB
其中../和../../是从主项目到图书馆项目的相应路径(这只是一个例子).请注意,此引用列表是基于1的,不应包含间隙或重复.Google非常清楚这不是一个完美的系统,但它是一个与Ant和Eclipse兼容的合理解决方案.一般来说,IDE会尝试为您维护这些文件,但有时您可能需要手动编辑它们.
起初,Library Projects不支持以下内容:
指向其他图书馆项目的图书馆项目
包含aidl文件的库项目
库项目包含资产文件夹
然而,随后的sdk版本解决了所有这些问题.
有关库项目的更多信息,请参阅官方文档.
将项目导出为JAR不是通过"属性" - >"Java构建路径" - >"库"将库项目链接到应用项目的正确方法.也不是通过Properties - > Java Build Path - > Projects将项目链接为必需项目.
首先,阅读Android开发人员的库项目主题 - >开发 - >管理项目:http://developer.android.com/guide/developing/projects/index.html#LibraryProjects 之后,阅读设置库在Android开发人员中再次计划和引用库项目主题 - >开发 - >管理项目 - >从Eclipse使用ADT
所以......步骤是:
通常将您的库项目创建为Android项目;
在项目属性中设置"is library" - > Android正常创建您的App项目;
在项目属性中添加对库的引用 - > Android - > Add.
在此之后,您可以使用所有类,组件(活动,服务,提供者,接收者),资源等.
例如:要引用xml布局中的任何资源,例如,您应该使用@mylib:id/my_id或@mylib:layout/my_lib_layout
视频:如果您在应用程序项目中使用库的组件,则必须在应用程序清单中复制它们.
此外,我得到了属性工作,但不是我认为应该工作的方式.
您必须在使用自定义属性的元素中使用命名空间,即主应用程序的命名空间,而不是库项目的命名空间.因此,在您的示例中,如果您为应用项目的命名空间指定"xmlns:fnord"的值,则它可以正常工作.
此外,在自定义PredicateLayout(Context,AttributeSet)
构造函数中读取自定义属性时,必须在调用时指定应用程序的命名空间attributes.getAttributeValue()
.
这是一个痛苦,因为该代码在您的库应用程序中,它不会/不应该知道它所使用的应用程序项目.我通过让应用程序调用静态方法ViewUtil.setAttributeNamespace(appNamespace)来解决这个问题.我的应用程序是onCreate(),并且库的自定义视图使用该命名空间来检索自定义属性.然后,attrs.xml文件也可以保留在库项目中.现在唯一令人遗憾的是,布局XML必须在自定义视图上使用应用程序的命名空间,因此您无法将这些布局XML放在库项目中.