2009-02-21 6 views
20

J'ai deux projets Android, un «projet de bibliothèque» contenant une mise en page personnalisée et un «projet d'application» contenant une application qui utilise la mise en page. Tout semble se construire et s'exécuter correctement, sauf que l'éditeur de disposition visuelle lève une ClassNotFoundException (ce que je suppose être un bug dans le plug-in), mais quand j'essaie de commencer à utiliser les attributs que j'ai définis pour la mise en page personnalisée dans le fichier XML, je ne peux plus construire. C'est; cela fonctionne:Spécification des dépendances de projet Android (dans Eclipse)

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

Alors que cela ne:

<?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 construction échoue avec un message de AAPT:

ERREUR Aucun identifiant de ressource trouvé pour l'attribut 'layout_horizontalSpacing' dans le paquet ' se.fnord.android '

L'identifiant de ressource est ex ist dans le fichier R et attrs.xml contenait le projet de bibliothèque, et si je mets le code de disposition et les ressources directement dans le projet d'application tout fonctionne bien. L'attribut layout_horizontalSpacing (et layout_verticalSpacing) est un attribut personnalisé utilisé dans la classe PredicateLayout.LayoutParam pour spécifier la distance jusqu'au widget suivant. Jusqu'ici j'ai essayé les manières standard d'éclipse en spécifiant des références de projet et des dépendances de projet de chemin de construction. On m'a également dit d'essayer l'étiquette dans le manifeste de l'application, ce qui n'a pas aidé. Alors, que dois-je faire pour que les références dans le fichier xml fonctionnent?

Je ne sais pas si elle est pertinente, mais le manifeste 'bibliothèque' ressemble à ceci:

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

Le manifeste comme cette 'application':

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

(Le 'PredicateLayout' , btw, est une version nettoyée de this).

+0

Voir aussi 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

Répondre

19

Les premières versions d'Android sdk ne prenaient pas en charge le partage au niveau du code source de manière agréable. Vous pouvez compresser vos fichiers .class puis les ajouter dans le dossier lib /, mais cette solution n'a pas permis le partage direct du code source et tout aussi important n'a pas supporté le partage des ressources ou des fichiers aidl.

Puis en mai 2010, Android a introduit le mécanisme de projet de bibliothèque. Un projet de bibliothèque est structuré très semblable à un projet Android normal, mais plutôt que d'être utilisé pour produire un apk, il sert uniquement à fournir du code et des ressources à d'autres projets. Comme un projet ordinaire, un projet de bibliothèque contient généralement des dossiers src et res, ainsi qu'un fichier AndroidManifest.xml; cependant, le manifeste doit être principalement vide, à l'exception de l'élément manifest et de l'attribut package (n'est plus vrai - vous pouvez désormais déclarer des activités et d'autres composants dans le manifeste de votre projet Library). De plus, le fichier project.properties pour un projet de bibliothèque doit contenir la propriété:

"android.library=true" 

Pour faire une référence d'un projet ordinaire (apk-production) à un projet de bibliothèque, vous devez ajouter un « android ".library.reference.N" dans le fichier project.properties du projet ordinaire. Par exemple, si mon projet principal tient à souligner deux projets de bibliothèque, mon project.properties fichier pour le projet principal comprendrait les éléments suivants:

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

où le ../ et le ../../ sont les chemins respectifs du projet principal aux projets de bibliothèque (ceci est juste un exemple). Notez que cette liste de références est basée sur 1 et ne doit pas contenir d'espaces ou de doublons. Google est bien conscient que ce n'est pas un système parfait mais c'est une solution raisonnable compatible avec Ant et Eclipse. D'une manière générale, votre IDE tentera de maintenir ces fichiers pour vous, mais vous devrez parfois les modifier manuellement.

Au début des projets de bibliothèque ne prennent pas en charge les éléments suivants:

  1. Projets Bibliothèque pointant vers d'autres bibliothèques Projets
  2. Projets Bibliothèque contenant des fichiers AIDL
  3. Projets Bibliothèque contenant dossier actifs

Cependant les versions suivantes de sdk ont ​​résolu tous ces problèmes.

Pour plus d'informations sur les projets de bibliothèque, voir the official documentation.

+1

ADT 0.9.7 nous obtient 80% de ce que nous voulons, mais il a encore ces inconvénients: (1) un projet de bibliothèque ne peut pas contenir de fichiers .aidl, (2) un projet de bibliothèque ne peut pas dépendre d'un autre projet de bibliothèque, (3) un projet de bibliothèque ne peut pas contenir d'actifs –

+1

(1) n'est plus valide à partir de ADT 0.9.8 – neu242

+1

Correct. SDK Tools Revision 7 et ADT 0.9.8 (publié en septembre 2010) résolvent les problèmes (1) et (2) au moins et éventuellement (3). –

3

Exportez votre projet de bibliothèque en tant que fichier JAR et référencez-le dans le fichier "Java Build Path" de votre projet d'application en tant que fichier JAR.

3

Le « Exporter votre bibliothèque comme un pot » solution » ne fonctionne que si votre projet de bibliothèque contient le code source uniquement. Dans ce cas, la question de l'OP mentionne que son projet de bibliothèque contient des choses liées ui.

Nous avons la Nous avons fini par refondre notre système de construction Ant afin d'avoir des applications qui engloutissent les projets de la bibliothèque pendant le temps de construction, malheureusement aucune solution de ce genre ne semble Eclipse est compatible avec Eclipse, ce qui est une source de frustration majeure pour les développeurs, mais nous sommes toujours capables d'utiliser Eclipse, mais nous devons passer à travers des cerceaux pour le faire fonctionner et avoir à supporter une productivité diminuée

+0

Voir la mise à jour ci-dessus qui mentionne ADT 0.9.7 - cela résout principalement ce problème. –

8

De plus, j'ai les attributs qui marchent, mais pas de la façon dont ça devrait marcher je pense.

Vous devez utiliser comme espace de nom dans l'élément qui utilise vos attributs personnalisés, l'espace de nom de votre application principale, pas celui du projet de bibliothèque. Donc, dans votre exemple, si vous spécifiez pour la valeur de "xmlns: fnord" l'espace de noms de votre projet d'application, cela fonctionne. En outre, lors de la lecture des attributs personnalisés dans votre constructeur personnalisé PredicateLayout(Context,AttributeSet), vous devez également spécifier l'espace de nom de l'application dans les appels attributes.getAttributeValue().

Ce qui est pénible, car ce code est dans votre application de bibliothèque qui ne doit/ne doit pas savoir sur le projet d'application dans lequel il est utilisé. J'ai travaillé autour de cela en appelant l'application une méthode statique ViewUtil.setAttributeNamespace (appNamespace) dans onCreate() de mon application, et les vues personnalisées de la bibliothèque utilisent cet espace de noms pour récupérer les attributs personnalisés. Le fichier attrs.xml peut ensuite rester dans le projet de bibliothèque. Maintenant, la seule chose laide est que la mise en page XML doit utiliser l'espace de noms de l'application sur les vues personnalisées, donc vous ne pouvez pas mettre ces XML de mise en page dans le projet de la bibliothèque.

+2

Essayez de supprimer he/apk/du chemin du schéma comme indiqué ici -> http://stackoverflow.com/questions/3428784/android-how-do-i-reference-a-stylable-that-resides-in-a- library-that-my-app-refe – scottyab

12

L'exportation du projet en tant que fichier JAR n'est pas la bonne méthode pour lier un projet de bibliothèque à votre projet d'application via Propriétés -> Chemin de construction Java -> Bibliothèque. Il ne s'agit pas non plus de lier le projet en tant que projet requis via Propriétés -> Chemin de construction Java -> Projets.

D'abord, lisez les projets de bibliothèque sujet aux développeurs Android -> Développement -> Gestion des projets: http://developer.android.com/guide/developing/projects/index.html#LibraryProjects Après cela, lisez la mise en place d'un projet de bibliothèque et référençant un des sujets du projet de bibliothèque à nouveau Développeurs Android -> Développement - > Gestion de projets -> de Eclipse ADT

Alors ... les étapes sont les suivantes:

  1. Créez votre projet de bibliothèque normalement comme un projet Android;
  2. Définir "est la bibliothèque" dans les propriétés du projet -> Android Créez votre projet normalement;
  3. Ajoutez une référence à votre bibliothèque dans les propriétés du projet -> Android -> Ajouter.

Après cela, vous pouvez utiliser toutes les classes, les composants (activités, services, fournisseurs, récepteurs), des ressources, etc.

Ex .: pour faire référence à toutes les ressources dans une mise en page XML, par exemple, vous devez utiliser Observations: Si vous utilisez des composants de votre bibliothèque dans un projet d'application, vous devez les répliquer dans le manifeste de votre application.

+1

Y a-t-il une différence dans le fichier APK final selon qu'un projet de bibliothèque est lié de cette façon ou entièrement intégré dans l'application? – Pacerier

+0

Je ne suis pas sûr, @Pacerier, mais je pense que lier la bibliothèque comme un projet intégrera seulement ce que votre application utilise et non la bibliothèque complète. Vous pouvez vérifier cela en testant les deux solutions et en examinant la taille et le contenu de l'apk final. En tout cas, c'est un bon point! – JPMagalhaes

Questions connexes