2009-02-21 14 views
20

Tengo dos proyectos de Android, un 'proyecto de biblioteca' que contiene un diseño personalizado y un 'proyecto de aplicación' que contiene una aplicación que usa el diseño.Especificación de dependencias de proyectos de Android (en Eclipse)

Todo parece construir y ejecutar bien, excepto que el editor de diseño visual arroja una ClassNotFoundException (que supongo que es un error en el complemento), pero cuando trato de comenzar a hacer uso de los atributos que definí para el diseño personalizado en el xml, ya no puedo construir. Es decir; esto funciona:

<?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> 

Considerando que el presente no:

<?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> 

La generación falla con un mensaje de aapt:

ERROR Sin identificador de recursos encontrado para el atributo 'layout_horizontalSpacing' en el paquete ' se.fnord.android '

El identificador de recursos hace ex está en el archivo R y attrs.xml contenía el proyecto de la biblioteca, y si pongo el código de diseño y los recursos directamente en el proyecto de la aplicación todo funciona bien. El atributo layout_horizontalSpacing (y layout_verticalSpacing) es un atributo personalizado utilizado en la clase PredicateLayout.LayoutParam para especificar la distancia al siguiente widget.

Hasta ahora he intentado las formas de eclipse estándar especificando las referencias del proyecto y las dependencias del proyecto de ruta de compilación. También me dijeron que probara la etiqueta en el manifiesto de la aplicación, lo que no ayudó.

Entonces, ¿qué debo hacer para que las referencias en el archivo xml funcionen?

No sé si es relevante, pero manifiesta la 'biblioteca' se ve así:

<?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> 

La 'aplicación' manifestarse como esto:

<?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> 

(La 'PredicateLayout' , por cierto, es una versión limpiada de this).

+0

Véase también http://stackoverflow.com/questions/8581627/android-activity-under-eclipse-adt-with-project-dependencies-failed-resolving-x http://stackoverflow.com/questions/9838069/ jar-file-issue-with-adt-r17 – jfritz42

Respuesta

19

Las primeras versiones de SDK de Android no admitían el uso compartido del código fuente de una manera agradable. Podrías sacudir tus archivos .class y luego agregarlos a la carpeta lib /, pero esta solución no permitía compartir directamente el código fuente y, lo que es más importante, no permitía el uso compartido de recursos o archivos aidl.

Luego, en mayo de 2010, Android introdujo el mecanismo de Proyecto de biblioteca. Un Library Project está estructurado de forma muy similar a un proyecto normal de Android, pero en lugar de ser utilizado para producir un apk, solo sirve para proporcionar código y recursos a otros proyectos. Al igual que un proyecto ordinario, un proyecto de biblioteca generalmente contiene carpetas src y res, junto con un archivo AndroidManifest.xml; sin embargo, el manifiesto debe estar en su mayoría vacío, con la excepción del elemento manifiesto y el atributo del paquete (ya no es verdadero; ahora puede declarar Actividades y otros componentes en el manifiesto de su Proyecto de biblioteca). Además, el archivo project.properties para un proyecto de biblioteca debe contener la propiedad:

"android.library=true" 

hacer una referencia a un proyecto ordinario (apk productoras) para un proyecto de biblioteca, es necesario agregar un "androide .library.reference.N "línea en el archivo project.properties del proyecto ordinario. Por ejemplo, si mi principal proyecto quiere señalar a dos proyectos de biblioteca, mi archivo project.properties para el proyecto principal incluiría lo siguiente:

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

donde el ../ y la ../../ son las rutas respectivas desde el proyecto principal hasta los Proyectos de la Biblioteca (esto es solo un ejemplo). Tenga en cuenta que esta lista de referencias está basada en 1 y no debe contener vacíos o duplicados. Google sabe muy bien que este no es un sistema perfecto, pero era una solución razonable que era compatible con Ant y Eclipse. En general, su IDE intentará mantener estos archivos por usted, pero a veces puede necesitar editarlos a mano.

Al principio, los proyectos de bibliotecas no apoyaron la siguiente:

  1. proyectos de biblioteca apuntando a otros proyectos de bibliotecas
  2. proyectos de bibliotecas que contienen archivos AIDL
  3. que contiene la carpeta activos
  4. proyectos de bibliotecas

Sin embargo las versiones subsiguientes de SDK resolvieron todos estos problemas.

Para obtener más información sobre proyectos de biblioteca, consulte the official documentation.

+1

ADT 0.9.7 nos consigue el 80% de lo que deseamos, pero todavía tiene estos inconvenientes: (1) un proyecto de biblioteca no puede contener archivos .aidl, (2) un proyecto de biblioteca no puede depender de otro proyecto de biblioteca, (3) un proyecto de biblioteca no puede contener activos –

+1

(1) ya no es válido a partir de ADT 0.9.8 – neu242

+1

Correcto. La Revisión 7 de SDK Tools junto con ADT 0.9.8 (lanzada en septiembre de 2010) resuelven los problemas (1) y (2) al menos y posiblemente (3). –

3

Exporte su proyecto de biblioteca como un JAR y hágalo referencia en la "Ruta de compilación de Java" del proyecto de su aplicación como un JAR.

3

El "Exportar su biblioteca como un frasco de" solución" sólo funciona si su proyecto de biblioteca contiene el código fuente única. En este caso la pregunta del OP menciona que su proyecto de biblioteca contiene material relacionado con la interfaz de usuario.

Tenemos la exactamente el mismo problema en mi equipo de querer tener proyectos de biblioteca que contengan fuentes y recursos relacionados con la UI. Terminamos revisando nuestro sistema de compilación Ant para que las aplicaciones engullen los proyectos de la biblioteca durante el tiempo de compilación. Desafortunadamente, ninguna solución de este tipo parece ser compatible con Eclipse y esta es una gran fuente de frustración para los desarrolladores. Todavía podemos usar Eclipse, pero tenemos que pasar por aros para que funcione y tenga que soportar una productividad reducida.

+0

Ver la actualización anterior que menciona ADT 0.9.7 - en su mayoría resuelve este problema. –

8

Además, tengo los atributos funcionando, pero no de la forma en que debería funcionar, creo.

Debe usar como espacio de nombres en el elemento que usa sus atributos personalizados, el espacio de nombres de su aplicación principal, no el del proyecto de la biblioteca. Entonces, en su ejemplo, si especifica el valor de "xmlns: fnord" en el espacio de nombres de su proyecto de aplicación, funciona.

Además, al leer los atributos personalizados en su constructor personalizado PredicateLayout(Context,AttributeSet), también debe especificar el espacio de nombres de la aplicación en las llamadas al attributes.getAttributeValue().

Lo cual es un problema, ya que ese código está en la aplicación de su biblioteca que no/no debería saber sobre el proyecto de aplicación en el que se usa. Lo solucioné al hacer que la aplicación llamara a un método estático ViewUtil.setAttributeNamespace (appNamespace) en onCreate() de mi aplicación, y las vistas personalizadas de la biblioteca usan ese espacio de nombres para recuperar los atributos personalizados. El archivo attrs.xml también puede permanecer en el proyecto de la biblioteca. Ahora, lo único feo es que el diseño XML debe usar el espacio de nombres de la aplicación en vistas personalizadas, por lo que no puede poner esos XML de diseño en el proyecto de la biblioteca.

+2

Intenta eliminar he/apk/de la ruta del esquema como se indica aquí -> http://stackoverflow.com/questions/3428784/android-how-do-i-reference-a-stylable-that-resides-in-a- library-that-my-app-refe – scottyab

12

Exportar el proyecto como un JAR no es la forma correcta de vincular un proyecto de biblioteca a su proyecto de aplicación a través de Propiedades -> Ruta de compilación de Java -> Biblioteca. Ni vincular el proyecto como un proyecto requerido a través de Propiedades -> Ruta de compilación de Java -> Proyectos.

En primer lugar, lea el tema proyectos de bibliotecas en los desarrolladores de Android -> Desarrollo -> Administración de proyectos: http://developer.android.com/guide/developing/projects/index.html#LibraryProjects Después de esto, lee la creación de un proyecto de Biblioteca y hacer referencia a una serie de temas de proyectos biblioteca de nuevo a los desarrolladores de Android -> Desarrollo - > Gestión de proyectos -> Desde Eclipse con ADT

Así que ... los pasos son:

  1. Cree su proyecto de biblioteca normalmente como un proyecto Android;
  2. Establecer "es biblioteca" en las propiedades del proyecto -> Android Crea tu aplicación proyecto normalmente;
  3. Agregue una referencia a su biblioteca en las propiedades del proyecto -> Android -> Agregar.

Después de ello se puede utilizar todas las clases, los componentes (actividades, servicios, proveedores, receptores), recursos etc.

Ej .: para hacer referencia a cualquier recurso en un diseño xml, por ejemplo, se debe utilizar @mylib: id/my_id o @mylib: layout/my_lib_layout

Obs .: Si usa componentes de su biblioteca en un proyecto de aplicación, debe replicarlos en el manifiesto de su aplicación.

+1

¿Hay alguna diferencia en el archivo APK final dependiendo de si un proyecto de biblioteca está vinculado de esta manera o completamente integrado en la aplicación? – Pacerier

+0

No estoy seguro, @Pacerier, pero creo que al vincular la biblioteca como un proyecto incrustará solo lo que usa su aplicación y no la lib completa. Puede verificar esto probando ambas soluciones y examinando el tamaño y el contenido de la apk final. De todos modos, ese es un buen punto! – JPMagalhaes

Cuestiones relacionadas