36 votes

Quel est le problème du débogage dans Eclipse sur Android ?

Duplicata possible :
Environnement de débogage apparemment inutile pour Android

J'ai manifestement été gâté par Visual Studio, car bien que je sois en train d'apprendre Android et l'environnement Eclipse, le débogage des applications dans Eclipse devient un sérieux obstacle à la poursuite du développement.

Par exemple, Eclipse compilera très bien ce diviseur par zéro :

public class Lesson2Main extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate (savedInstanceState);

        int i = 1 / 0;

        TextView tv = new TextView (this);
        tv.setText ("Hello, Android!");
        setContentView (tv);
    }
}

Et ensuite, lorsqu'il l'exécute sous le débogueur, j'obtiens un écran complet d'informations de débogage inutiles, dont aucune ne m'indique réellement la ligne spécifique contenant l'erreur.

La trace de la pile est nulle dans l'arbre d'information de l'exception ('e'), et elle indique simplement un message indiquant 'ArithmeticException'. (c'est bien, et si vous m'indiquiez où vous l'avez trouvé ?)

J'ai regardé partout sur l'écran et je suis déconcerté par le fait que cet IDE n'arrive pas à faire ça correctement. Est-ce que le développement avec Eclipse ramène tout le monde à 1991 avec printf() comme la journalisation à chaque intervalle pour traquer les bugs ? Sérieusement.

Y a-t-il une configuration ou un plug-in qui m'échappe pour m'aider ?

Je n'ai pas testé ce cas avec XCode, mais si l'iPhone dev. IDE gère cela plus comme Visual Studio, alors pas étonnant que le marché Android ait si peu d'applications.

Je suis excité par Android, mais il semble qu'Eclipse se mette en travers du chemin.

25voto

Steve Haley Points 26928

Oui, vous avez manqué l'un des plug-ins très importants pour Eclipse appelé "LogCat". Il récupère tous les journaux de débogage que votre programme Android donne, qu'il fonctionne sur l'émulateur ou sur un vrai téléphone. Dans ce dernier cas, il faut évidemment que le téléphone soit branché à l'ordinateur et, ce qui est moins évident, que le paramètre dans Application -> Développement -> Activer le débogage USB soit activé.

Les messages LogCat vous donnent le détail complet de ce qui a causé l'erreur, y compris le numéro de ligne. Pour ouvrir LogCat dans Eclipse, allez dans Fenêtre -> Afficher la vue -> Autre -> Android (un des dossiers de la liste) -> LogCat. Fixez ensuite la fenêtre LogCat à un endroit où vous pouvez la voir facilement. Eclipse se souviendra de cet emplacement et l'ouvrira à nouveau la prochaine fois que vous le lancerez.

(Il arrive que LogCat et l'émulateur soient déconnectés l'un de l'autre. Le moyen simple de résoudre ce problème est de fermer Eclipse et l'émulateur, puis de les redémarrer tous les deux).

11voto

fadden Points 17450

(Il y a trop de choses à dire dans un commentaire, alors je rédige ceci comme une réponse).

Vous pouvez configurer Eclipse pour qu'il s'arrête sur les exceptions qui sont attrapées, non attrapées, ou les deux. Par défaut, Eclipse s'arrêtera sur toute exception non attrapée, et ignorera toutes les exceptions attrapées (c.-à-d. tout ce qui est accroché par un bloc try/catch).

Les choses deviennent un peu étranges pour Android, car vous vous exécutez dans un cadre d'application, et non dans une application autonome. Comme vous pouvez le voir dans la trace de la pile affichée ci-dessus, l'exception a en fait été attrapée par ActivityThread. Cela signifie que votre exception initiale est considérée comme "attrapée" et qu'elle ne déclenchera pas la gestion des exceptions non attrapées d'Eclipse avant que ActivityThread ne la relance. Pour cette raison, la pile que vous voyez dans le débogueur quand il s'arrête n'est nulle part près de votre code.

Puisque vous savez que vous obtenez une ArithmeticException, vous pouvez faire en sorte qu'elle s'arrête sur les instances "attrapées" de cette exception, et elle s'arrêtera au point de lancement. (Ne le faites pas se casser sur toutes les exceptions attrapées - vous frapperez "resume" sans fin).

Pour ce qui est de la journalisation "tardive", si le débogueur laissait le programme continuer à s'exécuter jusqu'à ce que la journalisation se produise, il ne serait pas possible de déboguer à l'endroit de l'éjection.

10voto

Janusz Points 52607

J'obtiens la trace de pile suivante dans logcat :

03-31 17:01:11.272: ERROR/AndroidRuntime(205): java.lang.RuntimeException: Unable to start activity ComponentInfo{MyClass}: java.lang.ArithmeticException: divide by zero
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.access$2100(ActivityThread.java:116)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.os.Looper.loop(Looper.java:123)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.main(ActivityThread.java:4203)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at java.lang.reflect.Method.invokeNative(Native Method)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at java.lang.reflect.Method.invoke(Method.java:521)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at dalvik.system.NativeStart.main(Native Method)
03-31 17:01:11.272: ERROR/AndroidRuntime(205): Caused by: java.lang.ArithmeticException: divide by zero
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at MyClass.onCreate(MyClass.java:40)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     ... 11 more

C'est clair comme de l'eau de roche. Regardez la cause de l'exception à la ligne 14 de la trace de la pile et il est dit : Diviser par zéro. C'est ce que vous avez fait de mal. La ligne suivante dit : at MyClass.onCreate(MyClass.java:40) C'est à cette ligne que l'exception se produit. Je ne vois pas ce qui serait difficile ou inutile dans tout cela. Comment VS présenterait-il cela ?

3voto

Frank LaRosa Points 689

Pendant des semaines après avoir commencé le développement d'Android, j'étais frustré par le manque d'informations que je trouvais dans la fenêtre LogCat. Je plaçais des messages de journal dans mon application sans jamais les voir, et je savais que mon application lançait des exceptions mais je ne les voyais pas non plus.

Un jour, j'ai enfin compris : ma fenêtre LogCat affichait le mauvais appareil. J'ai généralement deux ou trois appareils Android connectés à mon ordinateur à un moment donné, et LogCat affichait l'un de ces autres appareils. Pour changer cela, vous devez afficher la fenêtre Devices et sélectionner le périphérique que vous voulez dans cette fenêtre.

Je trouve que c'est un exemple d'interface utilisateur ridiculement mauvaise. Ici, je regarde une fenêtre LogCat et nulle part dans cette fenêtre il n'y a d'indication sur les journaux du périphérique que je regarde. Je dois en savoir assez pour ouvrir une fenêtre totalement différente et y sélectionner le périphérique. J'ai littéralement perdu des semaines de temps avant de comprendre ce problème. On pourrait penser que LogCat afficherait par défaut tous les périphériques, ou du moins qu'il basculerait automatiquement sur le périphérique sur lequel vous avez lancé une application le plus récemment, mais ce n'est pas le cas. Si vous vous tapez la tête contre votre bureau en vous demandant pourquoi LogCat est si inutile, c'est peut-être pour cela.

1voto

steve Points 5838

Vous rencontrez un problème typique du développement avec un dispositif physique, par opposition à un logiciel sur une machine.

Il vous indiquera l'erreur spécifique (postez l'information et nous pourrons vous la montrer). Cherchez simplement les noms de vos paquets dans l'erreur et vous verrez où l'exception a été levée.

Vous devriez également utiliser des points d'arrêt pour avancer dans le processus et voir ce qui se passe. Le débogueur DDMS devrait répondre à toutes vos exigences.

Et oui, vous devriez utiliser la journalisation Log.i(TAG, "Info : " + x) ;

Vous ne pouvez pas prévoir tout ce qui se passe et, au fur et à mesure que votre base de code se développe, vous serez heureux d'avoir commencé à le faire tôt.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X