Débogage à distance avec l'émulateur Android

93

Est-il possible d'écrire le code / compiler l'application Android sur une machine et de la déboguer à distance sur l'émulateur lancé sur une autre? J'en ai marre que l'émulateur consomme constamment la moitié du processeur de mon ordinateur portable.

zakovyrya
la source

Réponses:

71

Je n'ai jamais essayé (ni même remarqué) la adb connectcommande mentionnée par cmb, mais je peux confirmer que la transmission des ports TCP vous-même - par exemple via SSH - fonctionne bien.

L'émulateur écoute sur deux ports TCP par instance: 5554 pour l'interface telnet et 5555 pour contrôler la communication avec des outils comme DDMS. Vous pourriez donc probablement vous en tirer avec uniquement le port de transfert 5555 (bien que je ne l'ai essayé que pour l'instant avec les deux). Chaque émulateur suivant prend le prochain numéro de port pair + impair disponible (jusqu'à environ 5580, je pense).

Pour référence, j'ai effectué les étapes suivantes sur ma machine locale:

  • ssh -NL 5554:localhost:5554 -L 5555:localhost:5555 myuser@remote-server
  • killall adb; adb devices

Je crois que l'émulateur essaie de notifier un serveur adb local au démarrage; d'où la nécessité de redémarrer adb pour qu'il puisse sonder les 5554 ports locaux.

Notez que localhostdans la commande ssh fait référence à l'interface locale de la machine distante .

adb devicesa montré un nouvel émulateur - emulator-5554- et je pourrais l'utiliser comme s'il fonctionnait sur ma machine locale.

Christophe Orr
la source
1
fonctionne comme un charme, même à partir de ma machine Windows 7 avec la redirection de port Putty SSH. Je vous remercie.
gsbabil
1
@JimMcKeeth: En fonction de la configuration réseau ci-dessus, ouvrez Putty, accédez à Connexion> SSH> Tunnels. Ajoutez maintenant une entrée avec Source-port: 5556 et Destination: localhost: 5554. Répétez la même chose avec Source-port: 5557 et Destination: localhost: 5555. À votre santé!
gsbabil
5
N'oubliez pas que vous devez killall adbégalement le faire sur le serveur, car l'émulateur n'acceptera pas plusieurs connexions et sera offlinedestiné à la machine locale.
Henrique de Sousa
Quelqu'un peut-il l'expliquer en anglais?
Anil GR
21

Voici comment je l'ai résolu sous Windows. J'ai à peu près suivi l'exemple de Christopher, mais je ne peux pas modifier, donc une nouvelle réponse devra faire.

Le problème que j'ai eu était que ADB ainsi que l'émulateur écoutaient juste sur 127.0.0.1, pas 0.0.0.0, pour moi. Sinon, j'aurais utilisé TCPMon . Je suppose que c'est soit différent sur Windows, soit a changé avec les dernières versions du SDK. (Vous pouvez vérifier avec netstat -ban.)

  1. J'ai installé WinSSHD sur la machine qui exécute l'émulateur. (Je pense que cela devrait également fonctionner avec freeSSHd, mais je n'ai pas pu obtenir de connexion.)

  2. J'ai ouvert le port 22 (TCP) dans le pare-feu Windows. (WinSSHD pourra peut-être le faire pour vous.)

  3. J'ai créé un compte virtuel dans l'interface graphique WinSSHD.

  4. J'ai créé une nouvelle connexion PuTTY entre la machine de développement et la machine d'émulation et je me suis assuré que je pouvais me connecter.

  5. Ensuite, j'ai mis en place le tunneling dans PuTTY: Connection -> SSH -> Tunnels

    Source port: 5554
    Destination: localhost:5554
    Type: Local/Auto

    Source port: 5555
    Destination: localhost:5555
    Type: Local/Auto

    (Connectez et gardez PuTTY ouvert, pour maintenir le tunnel.)

  6. Maintenant, j'ai lancé l'émulateur sur la machine distante et je me suis assuré que ADB ne fonctionnait pas là-bas.

  7. J'ai redémarré ADB sur la machine de développement ( adb kill-server, alors adb start-server).

  8. adb deviceset l'émulateur distant est apparu comme emulator-5554 device. Je pouvais maintenant déployer et exécuter mon application directement à partir d'Eclipse / ADT, où l'émulateur apparaissait sous Virtual Devices comme s'il s'agissait d'un émulateur local.

Henrik Heimbuerger
la source
A très bien fonctionné! Merci pour les détails.
Jim McKeeth
1
Bien, mais je voudrais clarifier: après l'étape 4, vous devez fermer le mastic, puis à l'étape 5, ouvrez-le à nouveau, configurez les tunnels et reconnectez-vous. Étapes 6 à 8: démarrez d'abord l'émulateur, puis démarrez adb (dans la machine hôte). Étape 9: vous voudrez peut-être redémarrer adb sur la machine cliente et tapez adb devices pour vous assurer que tout va bien. Les éléments DDMS et éclipse normaux devraient également fonctionner.
Mister Smith le
@MisterSmith Des points très valables, pourquoi ne soumettez-vous pas une modification? :)
Henrik Heimbuerger
@MisterSmith Pouvez-vous s'il vous plaît modifier votre réponse pour refléter ce commentaire, c'est très important pour le succès du problème. Aussi, merci, je peux maintenant me connecter à mon hôte depuis ma machine invitée.
meanbunny
20

Je me rends compte que cette question est vraiment ancienne, mais j'ai résolu le problème légèrement différemment, et il m'a fallu un certain temps pour trouver cette solution triviale.

J'utilise généralement un PC ou un ordinateur portable Windows7 (selon l'endroit où je travaille) comme frontal parce que j'aime l'interface graphique, mais je préfère faire tout mon éditer / compiler / déboguer sur un serveur Ubuntu sans tête à cause de tous les puissance de ligne de commande qu'il fournit. Mon objectif est de faire de chaque système Windows un client léger autant que possible sans services supplémentaires (tels que sshd) ou trous de pare-feu.

Voici donc le senario:

  • System-A: système Windows7 avec émulateur Android en cours d'exécution
  • System-B: serveur Ubuntu avec SDK installé

Le problème, comme décrit précédemment, est que l'émulateur sur System-A se lie à localhost, pas à l'interface Ethernet externe, donc adb sur System-B ne peut pas accéder à l'émulateur sur System-A. Tout ce que vous avez à faire est de configurer la redirection de port distant dans PuTTY pour votre connexion SSH à System-B. L'astuce consiste à cocher le bouton radio "Remote" lorsque vous créez les deux tunnels afin que la direction du tunnel soit inversée (tunnel du serveur auquel vous vous connectez au client à partir duquel vous vous connectez).

capture d'écran du tunnel

Enfin, connectez-vous avec adb à "localhost" sur System-B après avoir établi la connexion SSH:

System-B$ adb connect localhost
connected to localhost:5555
System-B$ adb devices
List of devices attached
localhost:5555  device

Maintenant, vous pouvez télécharger des images / déboguer comme d'habitude, et il est trivial de passer à un autre système Windows si vous voulez sortir votre ordinateur portable et prendre un café.

En outre, en tunnelant également le port 5037 de la même manière, vous pouvez réellement transférer votre connexion au serveur adb afin de pouvoir connecter un véritable appareil Android via USB sur System-A et y télécharger des images à partir de System-B. Pour que cela fonctionne, vous devez vous assurer que le serveur adb fonctionne sur System-A et non sur System-B avant de démarrer votre session SSH:

Tout d'abord, démarrez le serveur adb sur System-A (invite de commande)

C:\> adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
C:\> adb devices
List of devices attached
3435F6E6035B00EC        device

Ensuite, tuez le serveur adb sur System-B

System-B$ adb kill-server

Enfin, redémarrez votre session ssh sur System-B et vérifiez

System-B$ adb devices
List of devices attached
3435F6E6035B00EC        device
Patrick McKinnon
la source
Existe-t-il un moyen de le faire sans installer le SDK Android sur System-A? (la machine Windows?)
Keith Twombley
Non, car le serveur adb et les pilotes USB doivent être exécutés sur System-A pour communiquer avec le périphérique.
Patrick McKinnon
J'ai fait cela aussi avec une configuration comme: Windows 7 (émulateur en cours d'exécution) -> Linux (saut requis, en raison du réseau ...) -> OS X exécutant Eclipse. Je peux voir les appareils avec des «appareils adb» et utiliser l'émulateur d'Eclipse. Le problème est qu'il ne reconnaît pas la cible Android de l'émulateur, je dois donc sélectionner la cible à chaque exécution manuellement.
Frank
si vous avez besoin d'un mastic pour Mac OS X, vous pouvez le trouver ici: mac-tools.org/putty-fur-mac-os-x/02/2012 Pour moi, cela a fonctionné avec cet outil.
Bruno Bieri
@PatrickMcKinnon la chose a bien fonctionné mais sur System-B, je suis devenu non autorisé en appelant des "périphériques adb". Sur le System-B, les "périphériques adb" le montrent comme fonctionnant correctement. De l'aide?
Tejas Sherdiwala
5

J'ai trouvé un moyen simple de le faire si vos deux machines sont dans le même réseau privé et n'ont donc pas besoin d'utiliser le cryptage SSH (ce qui est le cas courant). Cela peut être utile car un tunnel SSH peut être assez long et difficile à installer. Par exemple, installer un démon SSH sous Cygwin / Windows pour la première fois peut conduire à abandonner (enfin, j'ai abandonné).

Sous Windows, ce qui suit nécessite l'installation de Cygwin avec le package httptunnel . Cela doit également fonctionner sous Linux / httptunnel mais je n'ai pas essayé.

  • Exécutez l'émulateur sur l'une des machines (disons que son nom d'hôte est HostEmulator )

  • Démarrez Eclipse sur l'autre machine (appelons-le HostEclipse )

  • Ouvrez un terminal Cygwin sur chaque machine, puis,

  • Sur HostEmulator , entrez les commandes cygwin suivantes :

    hts -F localhost:5554 10000
    hts -F localhost:5555 10001

hts signifie Http Tunnel Server .

Ces deux commandes créent deux demi-ponts qui écoutent les ports 10001 et 10001 et qui redirigent les E / S de ces ports vers les ports locaux 5554 et 5555, qui sont les ports utilisés par l'émulateur (en fait, le premier émulateur lancé - si plusieurs d'entre eux sont en cours d'exécution, ils utiliseront des numéros de port plus élevés, comme indiqué dans d'autres réponses de cette page).

  • Sur HostEclipse , entrez ceux-ci :

    htc -F 5554 HostEmulator:10000
    htc -F 5555 HostEmulator:10001

htc signifie Http Tunnel Client .

Ces commandes créent les demi-ponts manquants. Ils écoutent les ports locaux 5554 et 5555 et redirigent les E / S de ces ports vers les demi-ponts que nous avons créés sur HostEmulator juste avant.

  • Ensuite, toujours sur HostEclipse , entrez ces trois commandes :

    adb kill-server
    adb start-server
    adb devices

Cela redémarre adb car il ne détecte pas l'émulateur distant autrement. Il doit effectuer une analyse au démarrage. Et puis il répertorie les périphériques (les émulateurs disponibles) juste pour vérification.

  • Et voilà.

Vous pouvez travailler avec votre émulateur distant comme s'il était local. Vous devez garder les terminaux Cygwin ouverts sur les deux machines sinon vous tueriez les demi-ponts que vous avez créés.

J'ai utilisé les ports 10000 et 10001 pour les échanges machine / machine ici, mais bien sûr, vous pouvez utiliser d'autres ports tant qu'ils ne sont pas déjà utilisés.

Shlublu
la source
2

Ma solution pour Windows + AndroVM (qui nécessite un adaptateur hôte uniquement) lorsque mon service ssh n'a pas pu démarrer. il ne nécessite donc aucun logiciel supplémentaire.

adb connect <Andro VM IP>
adp tcpip 555

À l'invite cmd, exécutez en tant qu'administrateur:

netsh interface portproxy add v4tov4 listenport=5555 listenaddress=<host ip> connectport=5555 connectaddress=<Andro VM IP>

ouvrez le port TCP 5555 dans le pare-feu Windows.

Ensuite, à partir du deuxième PC, exécutez:

adb connect <host ip>
Emirikol
la source
1

Aucune des solutions proposées n'a fonctionné pour moi. J'ai commencé à partir de la solution d'Emirikol et je l'ai affinée, car avec la nouvelle API Android> 21, l'émulateur apparaissait hors ligne et j'ai dû accéder aux paramètres de Genymotion et laisser le chemin du SDK Android vide. Et depuis la ligne de commande:

netsh interface portproxy add v4tov4 listenport=5555 connectport=5555 connectaddress=<emulatorIP>

netsh interface portproxy add v4tov4 listenport=5554 connectport=5554 connectaddress=<emulatorIP>

source: http://www.sarpex.co.uk/index.php/2016/10/02/connect-genymotion-emulator-remotely/ Avis de non-responsabilité, je suis l'auteur.

Sarpe
la source
Réponse et article parfaits! Si vous utilisez Genymotion, utilisez cette solution. L'article est écrit sur Windows et Mac, mais j'ai Ubuntu local et Ubuntu distant et tout fonctionne bien. J'ai sauvé ma semaine!
konstantin_doncov
1

Lorsque vous exécutez adb, il démarre une copie serveur de lui-même si l'un n'est pas déjà en cours d'exécution. Vous pouvez démarrer cette copie vous-même sur la machine avec le périphérique et depuis SDK 4.3, vous pouvez lui donner l'option -a pour indiquer à ce serveur d'écouter les machines distantes. Faites cela avec la commande suivante qui ne se ferme pas:

serveur adb -a -P 5037 nodaemon

Sur la machine à partir de laquelle vous souhaitez utiliser le périphérique, définissez ADB_SERVER_SOCKET sur tcp: xxxx: 5037 dans une variable d'environnement (ou donnez la même valeur à chaque appel adb avec l'option -L), où xxxx est l'adresse IP ou le nom d'hôte du machine avec les périphériques, et 5037 correspond au port que vous avez indiqué dans la commande ci-dessus.

Nous l'utilisons pour donner accès à environ 100 émulateurs répartis sur 3 machines à une machine exécutant des tests de bout en bout en parallèle, et aux développeurs souhaitant partager de vrais appareils à distance.

Vous pouvez transférer des ports vers et depuis l'émulateur avec adb forward et adb reverse, et ils apparaîtront sur la machine avec les périphériques (pas sur la machine à partir de laquelle vous exécutez 'adb forward').

android.weasel
la source
Pouvez-vous fournir plus de détails sur cette solution? J'ai fait tout ce que vous avez dit, mais je n'ai aucun appareil dans "Sélectionner la cible de déploiement" dans Android Studio. J'utilise Genymotion sur le deuxième ordinateur.
konstantin_doncov
@ don-prog Vous ne dites pas si cela fonctionne pour vous à partir de la ligne de commande: adb -L tcp:remotehost:1234 devicessi c'est le cas, vous devez savoir si Android Studio prend en charge les ADB distantes ou non - cela ne me surprendrait pas s'il insiste pour utiliser appareils locaux.
android.weasel
0

Je n'ai pas de seconde machine avec le SDK sous la main, mais je note que les ports d'écoute de l'émulateur (par défaut 5554, 5555) écoutent 0.0.0.0, c'est-à-dire accessibles depuis des machines distantes, et cela adb --helpmontre une connect <host>:<port>commande. Je suppose que cela le ferait apparaître adb devicespour que les adbcommandes fonctionnent dessus. Pour Eclipse, essayez "Exécuter / Exécuter les configurations ..." et définissez la cible sur Manuel. Cela vous donne un "sélecteur de périphérique" qui, je suppose, inclurait un émulateur distant si adb y est connecté. Ça vaut le coup d'essayer.

Chris Boyle
la source