在Android中从jar库声明名称空间

在Android中从jar库声明名称空间,android,jar,android-view,android-xml,Android,Jar,Android View,Android Xml,我正在创建一个Android SDK作为jar。它包含一些带有自定义参数的自定义视图。我想创建一个drop-in解决方案,在这个解决方案中,开发人员不需要做任何事情,只需要将jar放到他们的libs文件夹中。我不能去一个真正的图书馆项目,这是一个业务需求 实际上一切都很好,这不是我的第一个android项目,它以jar的形式发布。但是在这个例子中,我需要自定义视图的自定义属性。这意味着Android需要通过xml模式了解视图支持的属性集 简单的解决方案是让用户将预定义的attr.xml放在他们的

我正在创建一个Android SDK作为jar。它包含一些带有自定义参数的自定义视图。我想创建一个drop-in解决方案,在这个解决方案中,开发人员不需要做任何事情,只需要将jar放到他们的libs文件夹中。我不能去一个真正的图书馆项目,这是一个业务需求

实际上一切都很好,这不是我的第一个android项目,它以jar的形式发布。但是在这个例子中,我需要自定义视图的自定义属性。这意味着Android需要通过xml模式了解视图支持的属性集

简单的解决方案是让用户将预定义的attr.xml放在他们的资源文件夹中。但是,我看到像admob这样的库在没有自定义attr.xml的情况下工作。例如,您可以通过admob声明:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:text="@string/hello"/>
<com.google.ads.AdView android:id="@+id/ad"
                       android:layout_width="wrap_content"
                       android:layout_height="wrap_content"
                       ads:adSize="BANNER"
                       ads:adUnitId="AD_UNIT_ID_GOES_HERE"
                       ads:testDevices="TEST_EMULATOR,TEST_DEVICE_ID_GOES_HERE"
                       ads:loadAdOnCreate="true"/>
</LinearLayout>

但您不需要在应用程序中添加attr.xml。 如果我尝试像他们那样使用它(我在一个jar中有视图),并且具有与上面相同的布局和我自己的自定义属性,那么aapt会抱怨:

  • 错误:在包中找不到属性“XXX”的资源标识符 “com.XXX.XXX”
我已经查看了admobs jar文件,在com.google.ads包中找不到任何特殊的东西,它看起来像一个xml定义。知道他们是如何做到这一点的吗?aapt如何知道admob视图支持哪些属性


谢谢

不必为了使用自定义属性而创建
attr.xml
。您可以使用以下方法通过其
名称
获取属性值:

  • 等等
下面是一个如何使用它们的简单示例:

布局文件:

<com.example.HelloAndroid.StubView
    xmlns:stub="http://schemas.android.com/apk/lib/com.example.HelloAndroid"
    android:id="@+id/stub"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    stub:title="title value"
    stub:subtitle="subtitle value" />
public class StubView extends View {
    public StubView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StubView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        final String packname = "http://schemas.android.com/apk/lib/com.example.HelloAndroid";

        if (attrs != null) {
            final String title = attrs.getAttributeValue(packname, "title");
            final String subtitle = attrs.getAttributeValue(packname, "subtitle");

            Log.d("Test", "Title " + title);
            Log.d("Test", "Subtitle " + subtitle);
        }
    }
}
您可以反编译
AdMob
jar,并查看它们是否使用相同的方法

编辑:

<com.example.HelloAndroid.StubView
    xmlns:stub="http://schemas.android.com/apk/lib/com.example.HelloAndroid"
    android:id="@+id/stub"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    stub:title="title value"
    stub:subtitle="subtitle value" />
public class StubView extends View {
    public StubView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StubView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        final String packname = "http://schemas.android.com/apk/lib/com.example.HelloAndroid";

        if (attrs != null) {
            final String title = attrs.getAttributeValue(packname, "title");
            final String subtitle = attrs.getAttributeValue(packname, "subtitle");

            Log.d("Test", "Title " + title);
            Log.d("Test", "Subtitle " + subtitle);
        }
    }
}

如果您在包“com.XXX.XXX”中未找到属性“XXX”的资源标识符,请确保您的命名空间看起来不像
http://schemas.android.com/apk/res/your.package.name
apk/res
是最重要的,因为在这种情况下,
appt
将检查所提到的属性是否确实在
attrs.xml
中声明。您只需使用
http://schemas.android.com/apk/lib/your.package.name
namespcae以避免此问题

嗨。谢谢你的评论。我已经像你说的那样做了。这不是我的问题。我的问题是,如果没有attrs.xml,aapt无法解析名称空间(自定义属性类型),并且失败了。谢谢