Zdalne debugowanie za pomocą emulatora Androida

94

Czy można napisać kod / skompilować aplikację na Androida na jednym komputerze i zdalnie debugować ją na emulatorze uruchomionym na innym? Mam dość tego, że emulator ciągle zjada połowę procesora mojego laptopa.

zakovyrya
źródło

Odpowiedzi:

72

Wcześniej nie próbowałem (ani nawet nie zauważyłem) adb connect polecenia, o którym wspomniał cmb, ale mogę potwierdzić, że samodzielne przekazywanie portów TCP - na przykład przez SSH - działa dobrze.

Emulator nasłuchuje na dwóch portach TCP na instancję: 5554 dla interfejsu telnet i 5555 do sterowania komunikacją z narzędziami takimi jak DDMS. Więc prawdopodobnie mógłbyś uciec tylko z przekierowaniem portu 5555 (chociaż próbowałem go do tej pory tylko z obydwoma). Każdy kolejny emulator przyjmuje następną dostępną krotkę portu parzystego + nieparzystego (do około 5580, jak sądzę).

Dla porównania wykonałem następujące kroki na moim komputerze lokalnym:

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

Uważam, że emulator próbuje powiadomić lokalny serwer ADB podczas uruchamiania; stąd potrzeba ponownego uruchomienia adb, aby mógł sondować lokalne porty 5554+.

Zauważ, że localhostw poleceniu ssh odnosi się do lokalnego interfejsu zdalnej maszyny.

adb devicespokazał nowy emulator - emulator-5554- i mogłem go używać tak, jakby działał na moim lokalnym komputerze.

Christopher Orr
źródło
1
działa jak urok, nawet z mojego komputera z systemem Windows 7 z przekierowaniem portów Putty SSH. Dziękuję Ci.
gsbabil
1
@JimMcKeeth: W oparciu o powyższą konfigurację sieci, otwórz Putty, przejdź do Connection> SSH> Tunnels. Teraz dodaj wpis z Source-port: 5556 i Destination: localhost: 5554. Powtórz to samo z portem źródłowym: 5557 i miejscem docelowym: localhost: 5555. Twoje zdrowie!
gsbabil
5
Pamiętaj tylko, że musisz to zrobić killall adbna serwerze, ponieważ emulator nie zaakceptuje wielu połączeń i będzie offlinedla lokalnej maszyny.
Henrique de Sousa
Czy ktoś może to wyjaśnić po angielsku?
Anil GR
21

Oto, jak rozwiązałem to w systemie Windows. Prawie poszedłem za przykładem Christophera, ale nie mogę edytować, więc nowa odpowiedź będzie musiała wystarczyć.

Problem polegał na tym, że ADB i emulator po prostu nasłuchiwały na 127.0.0.1, a nie na 0.0.0.0. W przeciwnym razie użyłbym TCPMon . Wydaje mi się, że jest to albo inne w systemie Windows, albo zmieniło się wraz z najnowszymi wersjami SDK. (Możesz to sprawdzić netstat -ban.)

  1. Zainstalowałem WinSSHD na maszynie, na której działa emulator. (Uważam, że powinno działać również z freeSSHd, ale nie mogłem tam uzyskać loginu).

  2. Otworzyłem port 22 (TCP) w Zaporze systemu Windows. (WinSSHD może to zrobić za Ciebie).

  3. Utworzyłem konto wirtualne w GUI WinSSHD.

  4. Utworzyłem nowe połączenie PuTTY z maszyny deweloperskiej do maszyny emulatora i upewniłem się, że mogę się połączyć.

  5. Następnie skonfigurowałem tunelowanie w PuTTY: Połączenie -> SSH -> Tunele

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

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

    (Połącz i pozostaw PuTTY otwarte, aby utrzymać tunel).

  6. Teraz odpaliłem emulator na zdalnej maszynie i upewniłem się, że ADB tam nie działa.

  7. Zrestartowałem ADB na komputerze deweloperskim ( adb kill-serverwtedy adb start-server).

  8. adb devicesa zdalny emulator pojawił się jako emulator-5554 device. Mogłem teraz wdrożyć i uruchomić moją aplikację bezpośrednio z Eclipse / ADT, gdzie emulator pojawił się w obszarze Urządzenia wirtualne, jakby był emulatorem lokalnym.

Henrik Heimbuerger
źródło
Działało świetnie! Dzięki za szczegóły.
Jim McKeeth,
1
Fajnie, ale chciałbym wyjaśnić: po kroku 4 musisz zamknąć kit, a następnie w kroku 5 otworzyć go ponownie, skonfigurować tunele i ponownie połączyć. Kroki 6-8: najpierw uruchom emulator, a następnie uruchom adb (na maszynie hosta). Krok 9: możesz chcieć ponownie uruchomić adb na komputerze klienckim i wpisać urządzenia adb, aby upewnić się, że wszystko jest w porządku. Zwykłe DDMS i zaćmienia również powinny działać.
Mister Smith
@MisterSmith Bardzo ważne punkty, dlaczego nie prześlesz zmiany? :)
Henrik Heimbuerger
@MisterSmith Czy możesz zmienić swoją odpowiedź, aby odzwierciedlić ten komentarz, jest to bardzo ważne dla powodzenia problemu. Dziękuję, mogę teraz łączyć się z hostem z komputera gościa.
meanbunny
20

Zdaję sobie sprawę, że to pytanie jest naprawdę stare, ale rozwiązałem problem nieco inaczej i zajęło mi trochę czasu, zanim doszedłem do tego trywialnego rozwiązania.

Zwykle używam komputera PC lub laptopa z systemem Windows 7 (w zależności od tego, gdzie pracuję) jako mojego interfejsu użytkownika, ponieważ lubię GUI, jednak wolę wykonywać całą edycję / kompilację / debugowanie na bezgłowym serwerze Ubuntu ze względu na wszystkie zapewnia moc wiersza poleceń. Moim celem jest uczynienie każdego systemu Windows jak najbardziej uproszczonym klientem bez żadnych dodatkowych usług (takich jak sshd) lub dziur w zaporze.

Więc oto senario:

  • System-A: system Windows7 z uruchomionym emulatorem Androida
  • System-B: serwer Ubuntu z zainstalowanym SDK

Problem, jak opisano wcześniej, polega na tym, że emulator w System-A wiąże się z lokalnym hostem, a nie z zewnętrznym interfejsem Ethernet, więc adb w System-B nie może uzyskać dostępu do emulatora w System-A. Wszystko, co musisz zrobić, to skonfigurować zdalne przekierowanie portów w PuTTY dla połączenia SSH z System-B. Sztuczka polega na zaznaczeniu przycisku radiowego „Remote” podczas tworzenia dwóch tuneli, tak aby kierunek tunelu był odwrócony (tunelowanie z serwera, na którym się logujesz, do klienta, z którego się logujesz).

zrzut ekranu tunelu

Na koniec połącz się z adb do „localhost” w System-B po ustanowieniu połączenia SSH:

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

Teraz możesz normalnie pobierać obrazy / debugować, a przejście na inny system Windows jest banalną sprawą, jeśli chcesz wyjąć laptopa i napić się kawy.

Ponadto, tunelując port 5037 w ten sam sposób, możesz w rzeczywistości przekierować połączenie z serwerem adb, dzięki czemu możesz podłączyć prawdziwe urządzenie z Androidem przez USB do System-A i pobierać do niego obrazy z System-B. Aby to zadziałało, przed rozpoczęciem sesji SSH upewnij się, że serwer adb działa w System-A, a nie w System-B:

Najpierw uruchom serwer adb w System-A (wiersz polecenia)

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

Następnie zabij serwer adb na System-B

System-B$ adb kill-server

Na koniec zrestartuj sesję ssh do System-B i sprawdź

System-B$ adb devices
List of devices attached
3435F6E6035B00EC        device
Patrick McKinnon
źródło
Czy jest jakiś sposób, aby to zrobić bez instalowania zestawu SDK systemu Android na System-A? (maszyna z systemem Windows?)
Keith Twombley
Nie, ponieważ serwer ADB i sterowniki USB muszą być uruchomione w System-A, aby komunikować się z urządzeniem.
Patrick McKinnon
Zrobiłem to również w konfiguracji takiej jak: Windows 7 (z emulatorem) -> Linux (wymagany skok, ze względu na sieć ...) -> OS X z Eclipse. Jestem w stanie zobaczyć urządzenia z „urządzeniami adb” i użyć emulatora z Eclipse. Problem polega na tym, że nie rozpoznaje on docelowego systemu Android emulatora, więc muszę ręcznie wybierać cel przy każdym uruchomieniu.
Frank,
jeśli potrzebujesz szpachlówki do Mac OS X, możesz ją znaleźć tutaj: mac-tools.org/putty-fur-mac-os-x/02/2012 Dla mnie działało z tym narzędziem.
Bruno Bieri
@PatrickMcKinnon, rzecz działała dobrze, ale w System-B nie mogę wywołać „urządzeń adb”. Na urządzeniach System-B „adb” pokazuje, że działa poprawnie. Jakaś pomoc?
Tejas Sherdiwala
6

Znalazłem łatwy sposób, aby to zrobić, jeśli twoje dwa komputery znajdują się w tej samej sieci prywatnej i dlatego nie muszą używać szyfrowania SSH (co jest częstym przypadkiem). Może to pomóc, ponieważ tunel SSH może być dość długi i trudny do zainstalowania. Na przykład zainstalowanie demona SSH pod Cygwin / Windows po raz pierwszy może doprowadzić do poddania się (cóż, poddałem się).

W systemie Windows poniższe czynności wymagają zainstalowania Cygwin z pakietem httptunnel . To musi działać również pod Linuksem / httptunnel, ale nie próbowałem.

  • Uruchom emulator na jednym z komputerów (powiedzmy, że jego nazwa hosta to HostEmulator )

  • Uruchom Eclipse na innym komputerze (nazwijmy to HostEclipse )

  • Otwórz terminal Cygwin na każdym komputerze, a następnie

  • W HostEmulator wprowadź następujące polecenia cygwin :

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

hts oznacza Http Tunnel Server .

Te dwa polecenia tworzą dwa półmostki, które nasłuchują portów 10001 i 10001 i przekierowują wejścia / wyjścia tych portów do lokalnych portów 5554 i 5555, które są portami używanymi przez emulator (w rzeczywistości pierwszy emulator uruchomiony - jeśli jest ich kilka działających, będą używać wyższych numerów portów, jak widać w innych odpowiedziach na tej stronie).

  • W HostEclipse wprowadź te :

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

htc oznacza klienta tunelu Http .

Te polecenia tworzą brakujące półmostki. Nasłuchują lokalnych portów 5554 i 5555 i przekierowują wejścia / wyjścia tych portów do półmostków, które utworzyliśmy tuż przed HostEmulator .

  • Następnie, nadal na HostEclipse , wprowadź te trzy polecenia :

    adb kill-server
    adb start-server
    adb devices
    

Spowoduje to ponowne uruchomienie adb, ponieważ w przeciwnym razie nie wykrywa zdalnego emulatora. Musi wykonywać skanowanie podczas uruchamiania. A następnie wyświetla listę urządzeń (dostępnych emulatorów) tylko do sprawdzenia.

  • I gotowe.

Możesz pracować ze zdalnym emulatorem tak, jakby był lokalny. Musisz pozostawić otwarte terminale Cygwin na obu maszynach, w przeciwnym razie zabijesz utworzone przez siebie połówki mostów.

Użyłem portu 10000 i 10001 do wymiany maszyna / maszyna tutaj, ale oczywiście możesz użyć innych portów, o ile nie są już używane.

Shlublu
źródło
2

Moje rozwiązanie dla systemu Windows + AndroVM (które wymaga adaptera tylko dla hosta), gdy moja usługa ssh nie uruchomiła się. więc nie wymaga żadnego dodatkowego oprogramowania.

adb connect <Andro VM IP>
adp tcpip 555

W zachęcie cmd uruchom jako administrator:

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

otwórz port TCP 5555 w zaporze systemu Windows.

Następnie z drugiego komputera uruchom:

adb connect <host ip>
Emirikol
źródło
1

Żadne z proponowanych rozwiązań nie zadziałało. Zacząłem od rozwiązania Emirikol i dopracowałem je, ponieważ z nowym Android API> 21 emulator pojawiał się offline i musiałem przejść do ustawień Genymotion i pozostawić pustą ścieżkę Android SDK. I z linii poleceń:

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

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

źródło: http://www.sarpex.co.uk/index.php/2016/10/02/connect-genymotion-emulator-remotely/ Zastrzeżenie, jestem autorem.

Sarpe
źródło
Doskonała odpowiedź i artykuł! Jeśli korzystasz z Genymotion, skorzystaj z tego rozwiązania. Artykuł jest napisany o Windows i Mac, ale mam lokalne Ubuntu i zdalne Ubuntu i wszystko działa dobrze. Uratowałem mój tydzień!
konstantin_doncov
1

Po uruchomieniu adb uruchamia kopię samego serwera, jeśli jeszcze nie jest uruchomiona. Możesz rozpocząć kopiowanie siebie na maszynie z urządzeniem, a od sdk 4.3 możesz dać mu opcję -a, aby nakazać serwerowi nasłuchiwanie zdalnych maszyn. Zrób to za pomocą następującego polecenia, które się nie kończy:

adb -a -P 5037 serwer nodaemon

Na komputerze, z którego chcesz korzystać z urządzenia, ustaw ADB_SERVER_SOCKET na tcp: xxxx: 5037 w zmiennej środowiskowej (lub nadaj tę samą wartość każdemu wywołaniu adb z opcją -L), gdzie xxxx to adres IP lub nazwa hosta maszyna z urządzeniami, a 5037 odpowiada portowi, który podałeś w powyższym poleceniu.

Używamy tego, aby zapewnić dostęp do około 100 emulatorów rozmieszczonych na 3 maszynach do maszyny wykonującej równolegle testy od końca do końca, a także do programistów, którzy chcą zdalnie udostępniać prawdziwe urządzenia.

Możesz przekazywać porty do iz emulatora za pomocą adb forward i adb reverse, a pojawią się one na maszynie z urządzeniami (nie na maszynie, z której uruchamiasz `` adb forward '').

android.weasel
źródło
Czy możesz podać więcej szczegółów na temat tego rozwiązania? Zrobiłem wszystko, co powiedziałeś, ale nie mam żadnego urządzenia w opcji „Select Deployment Target” w Android Studio. Używam Genymotion na drugim komputerze.
konstantin_doncov
@ don-prog Nie mówisz, czy to działa u Ciebie z wiersza poleceń: adb -L tcp:remotehost:1234 devicesjeśli tak, to musisz dowiedzieć się, czy Android Studio obsługuje zdalne ADB, czy nie - nie zdziwiłbym się, gdyby nalegał na użycie urządzenia lokalne.
android.weasel
0

Nie mam pod ręką drugiej maszyny z SDK, ale zauważam, że porty nasłuchu emulatora (domyślnie 5554, 5555) nasłuchują 0.0.0.0, tj. Są osiągalne z maszyn zdalnych, i to adb --helppokazuje connect <host>:<port>polecenie. Zakładam, że to sprawi, że pojawi się w, adb deviceswięc adbdziałają na nim polecenia. W przypadku Eclipse spróbuj „Run / Run Configurations ...” i ustaw Target na Manual. To daje ci "wybór urządzeń", który, jak przypuszczam, zawierałby zdalny emulator, jeśli jest do niego podłączony adb. Warte spróbowania.

Chris Boyle
źródło