Amplíe ADB para facilitar la depuración de aplicaciones de Tuan Chau | Octubre de 2020

ADB es una herramienta útil y poderosa para interactuar con una aplicación de Android o con un dispositivo Android completo a través de la línea de comandos. Sin embargo, ADB todavía está lejos del depurador, por lo que generalmente en una aplicación grande tenemos que desarrollar una herramienta de interfaz de usuario que ofrezca llamar a dev o algo similar para que podamos comunicarnos, cambiar la configuración, etc. como Facebook Relleno o Stetho o Hyperionetc.

En este escrito, me gustaría extender ADB para facilitar la vida del desarrollo.

Por que elegí ADB ?

Bueno, mi, AndrOid devs, ya están familiarizados con ADB, al menos para algunos comandos de uso regular. Además, debido a que usamos una consola (o terminal) para interactuar con ADB, podemos configurar un alias para comandos largos (si eres como yo, odio escribir líneas de comando largas con el nombre de la rama git) para que sea más fácil y rápido de manejar.

En el lado de la computadora, ciertamente usamos una consola, terminal u otra herramienta de línea de comandos que admita ADB.

¿Cómo puede una aplicación recibir información de la consola? Hay muchas opciones para elegir

Lista de servicios

adb shell dumpsys ...

Para usar la lista de servicios, solo necesitamos reescribir dump() Método de clase de servicio

override fun dump(
fd: FileDescriptor?,
writer: PrintWriter?,
args: Array<out String>?
)

La primera ventaja de este método es que podemos obtener el resultado directamente en la consola. Por razones de seguridad, podemos verificar la información de la persona que llama Binder.getCallingPid() si si Process.SHELL_UID (indica una llamada ADB).

Desventajas Debemos mantener vivo el servicio. Por lo tanto, este enfoque es un poco inestable porque el servicio puede destruirse.

Receptor de radiodifusión

adb shell am broadcast ...

La ventaja más intuitiva de usar un receptor de transmisión es que el receptor siempre está listo para manejar nuestros comandos, incluso cuando la aplicación no se está ejecutando. La implementación también es simple, podemos pasar tipos primarios como booleano, entero, etc. O matriz al controlador de comandos, porque el receptor recibe todos los argumentos a través deIntent y Android ya lo están analizando.

Desventajas El mayor problema es la seguridad, la segunda aplicación puede ejecutar nuestra aplicación libremente a través del canal de transmisión. Por lo tanto, deberíamos habilitarlo para el modo de depuración.

Otra desventaja de un receptor de transmisión en comparación con una lista de servicios es que no podemos obtener resultados fácilmente en la consola donde se ejecuta el comando. Necesitamos comprobar Logcat para ver la prensa.

Una pequeña nota sobre el uso del comando de recepción:

Las aplicaciones destinadas a Android 8.0 o superior ya no pueden registrar receptores de transmisión para transmisiones implícitas en su manifiesto. Un difusión implícita es una transmisión que no está dirigida específicamente a esta aplicación. (Restricciones de transmisión)

Esto significa que tenemos que poner la aplicación de destino en el comando ADB

# Command 1
adb shell am broadcast -p <app.package.name> -a <broadcast.action>

Más enfoques y decisiones finales

Hay muchas otras formas posibles de comunicarse con la aplicación a través de ADB. En la aplicación podemos crear un servidor HTTP, abrir un socket, podemos usar telnet o activar una actualización de archivo (ver ¿Cómo monitorear la carpeta en busca de cambios de archivo en segundo plano?).

Para fines de depuración, elegí Broadcast Receiver debido a su preparación y fácil implementación, estamos seguros de que nuestros comandos siempre se procesan, no es necesario verificar si el servicio está activo.

Ahora que podemos aceptar argumentos de ADB, necesitamos crear un controlador para cada comando. Definitivamente tendremos algunos comandos para cumplir con nuestro propósito de depuración. Para manejar todos estos comandos, podemos crear un receptor para cada comando. Sin embargo, esto hará un mal uso del sistema de recepción de nuestra aplicación, y cada vez que creamos un receptor, debemos copiarlo y pegarlo (o usar BaseBroadcastReceiver clase) control de supuestos como seguridad.

Piense en el receptor como un servidor, recibe todas las solicitudes del cliente (terminal) y cada solicitud se identifica mediante una ruta. Podemos agregar una identificación a cada comando que indique la ruta, y luego el destinatario delega la solicitud para atender al corresponsal. A esto agregamos el primer elemento obligatorio, digamos cmd

override fun onReceive(context: Context, intent: Intent) {
val command = intent.getStringExtra("cmd") ?: return
// snippet
}

Entonces, al final command 1 agregaremos arriba -e cmd <commandKey>

Después de obtener la clave de comando, podemos delegar libremente otras clases de manejadores. en esta muestra, Crearé una utilidad de comando simple que actualice el color de fondo.

adb shell am broadcast -p com.example.adbplugindemo 
-a debug.adb.COMMAND
-e cmd changeBg
-e bgcolor red

Para obtener más información sobre la transferencia de datos al proyecto a través de ADB, consulte la página este enlace.

Obtenga el resultado en el mismo lugar

Como mencioné, una de las razones para usar el receptor de transmisión es que no podemos enviar la impresión a la consola. Aquí creé un script simple que redujo esta desventaja.

# command.sh
runTimeFlag=$(adb shell date +"%m-%d %T")

adb shell am broadcast -p app.package.name
-a receiver.action.COMMAND -e cmd [email protected]
adb logcat -t "$runTimeFlag.000" -v tag -s TAG | while read LOGLINE
do
echo $LOGLINE
done

Entonces podemos usar como

./command.sh commandKey ...

y el resultado impreso en logcat se muestra directamente en la consola. Sin embargo, debo decir que no funciona al 100%. Si el registro no se imprime antes de que se cierre el canal, el script no imprimirá nada. Podemos solucionar esto de otra manera para que podamos leer los registros de Logcat.

Usar ADB para depurar es realmente divertido y ahorra mucho tiempo navegando por el menú de desarrollo. Además, también podemos usar el receptor de transmisión para crear una aplicación independiente que sirva como desarrollador.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *