¡Construye un puente! Integración perfecta entre Android y WebApps
Construya sin esfuerzo un puente robusto entre su Android y WebApp con la Biblioteca SimpleEnDroidbridge. Esta biblioteca le permite representar una aplicación web en una WebView de Android y crear una JSIinterface para habilitar una comunicación sin problemas entre las dos plataformas. Comparta objetos complejos, promesas y funciones de devolución de llamada, todo mientras su aplicación web sigue siendo receptiva y eficiente.
✓ Compartir objetos - Android ⇄ Web
✓ Compartir promesa - Android ⇄ Web
✓ Funciones de devolución de llamada - Android ← Web
✓ Funciones de llamadas sin bloqueo - Android ⇄ Web
✓ Tipo de seguridad con TypeScript - Android + Web
El puente JavaScript incorporado en el SDK de Android solo admite tipos primitivos. Con SimpleAnDroidBridge, puede compartir objetos complejos entre Android y Web con facilidad. Simplemente defina los tipos como argumentos o valores de retorno en sus funciones nativas de Android, y la biblioteca convertirá automáticamente los objetos JavaScript en objetos Kotlin y viceversa.
// Kotlin
class AndroidNativeInterface ( val contactService : ContactService ): DefaultJSInterface( " Android " ) {
@NativeCall( CallType . FULL_SYNC )
fun searchContact ( contactFilter : ContactFilter ): List < Contact > {
return contactService.search(contactFilter)
}
}
data class ContactFilter ( val surname : String? = null , val firstname : String? = null )
data class Contact ( val surname : String? = null , val fistname : String? = null ,
val mail : String? = null , val phonenumber : String? = null ) // Javascript
console . log ( Bridge . interfaces . Android . searchContact ( { surname : "Pitt" } ) )El puente JavaScript en el SDK de Android ejecuta funciones de manera bloqueadora, lo que hace que la aplicación web se congele hasta que regrese la función nativa. Sin embargo, con esta biblioteca, puede definir un tipo de retorno de promesa, lo que permite la ejecución sin bloqueo. Al utilizar la función 'doinbackground', el código de Android se ejecuta en un hilo de fondo, evitando que la aplicación web se bloquee.
// Kotlin
class AndroidNativeInterface ( val contactService : ContactService ): DefaultJSInterface( " Android " ) {
@NativeCall( CallType . FULL_PROMISE )
fun searchContact ( contactFilter : ContactFilter ) = doInBackground< List < Contact >> { promise ->
try {
promise.resolve(contactService.search(contactFilter))
} catch (e : Exception ) {
promise.reject(e)
}
}
}
data class ContactFilter ( val surname : String? = null , val firstname : String? = null )
data class Contact ( val surname : String? = null , val fistname : String? = null ,
val mail : String? = null , val phonenumber : String? = null ) // Javascript
Bridge . interfaces . Android . searchContact ( { surname : "Pitt" } ) . then ( ( list ) => {
console . log ( list ) ;
} ) ;Si está familiarizado con JavaScript, es probable que no sea ajeno a las funciones de devolución de llamada. SimpleAnDroidBridge lleva este concepto un paso más allá, lo que le permite inyectar estas funciones de devolución de llamada de JavaScript directamente en la capa de Android, creando así una interacción perfecta entre su aplicación web y Android.
// Kotlin
class AndroidNativeInterface ( val button : Button ): DefaultJSInterface( " Android " ) {
@NativeCall( CallType . FULL_SYNC )
fun registerOnClickAction ( jsFunction : JSFunction ) {
button.setOnClickListener { jsFunction() }
}
} // Javascript
Bridge . interfaces . Android . registerOnClickAction ( ( ) => {
console . log ( "Button Clicked!" )
} ) Para pasar un argumento a una función JavaScript, use el tipo JSFunctionWithArg , que está específicamente diseñado para aceptar un argumento.
// Kotlin
class AndroidNativeInterface ( val button : Button ): DefaultJSInterface( " Android " ) {
var i = 0
@NativeCall( CallType . FULL_SYNC )
fun registerOnClickAction ( jsFunction : JSFunctionWithArg < Int >) {
button.setOnClickListener { jsFunction( ++ i) }
}
} // Javascript
Bridge . interfaces . Android . registerOnClickAction ( ( i ) => {
console . log ( "Button Clicked! " + i )
} )Para pasar múltiples argumentos a una función, considere crear una clase de datos.
Para las funciones que necesitan devolver un resultado a la capa de Android, puede usar JSFunctionWithPromise para funciones sin argumentos o JSFunctionWithPromiseAndArg para funciones que acepten un argumento.
// Kotlin
class AndroidNativeInterface ( val button : Button ): DefaultJSInterface( " Android " ) {
@NativeCall( CallType . FULL_SYNC )
fun registerOnClickAction ( jsFunction : JSFunctionWithPromiseAndArg < Add , Int >) {
button.setOnClickListener {
val add = Add (( Math .random() * 10 ).toInt(), ( Math .random() * 10 ).toInt())
jsFunction(add)
.then{ Log .d( " AndroidNativeInterface " , " Web calculated: ${add.a} + ${add.b} = $it " ) }
. catch { Log .e( " AndroidNativeInterface " , " ERROR IN WEB LAYER: $it " ) }
}
}
data class Add ( a : Int , b : Int )
} // Javascript
Bridge . interfaces . Android . registerOnClickAction ( ( add ) => {
return new Promise ( ( resolve ) => { resolve ( add . a + add . b ) } )
} )NOTA
Para liberar una JSFunction y borrar su enlace, simplemente llame a la función close . JSFunction implementa la interfaz AutoCloseable , lo que le permite utilizar los try-with-recursores o AutoCloseable.use {}
function.use { it() } Además, si su aplicación web o WebView admite la recarga, se recomienda agregar un AfterInicialInSeSistener al puente. Este oyente ayudará a lanzar cualquier JSFunctions disponible, asegurando un estado limpio después de la inicialización.
Esta biblioteca admite diferentes tipos de llamadas nativas que le permiten decidir cómo llamar al código nativo.
El tipo de llamada CallType.FULL_SYNC invoca el código nativo de manera bloqueadora, lo que hace que la ejecución de JavaScript se detenga hasta que la función de Android nativa regrese. Como resultado, la vista web no responde hasta que se completa la ejecución nativa. (No recomendado para tareas de larga duración)
// Kotlin
@NativeCall( CallType . FULL_SYNC )
fun searchContact ( contactFilter : ContactFilter ): List < Contact > {
return contactService.search(contactFilter)
} // Javascript
console . log ( Bridge . interfaces . Android . searchContact ( { surname : "Pitt" } ) ) El tipo de llamada CallType.WEB_PROMISE de manera similar a la llamada FULL_SYNC , con la diferencia clave que la llamada de JavaScript devuelve una promesa. Sin embargo, la función de Android nativa todavía se invoca de manera bloqueadora. (Recomendado si no está seguro de la duración de la tarea y puede necesitar migrar a FULL_PROMISE en el futuro)
// Kotlin
@NativeCall( CallType . WEB_PROMISE )
fun searchContact ( contactFilter : ContactFilter ): List < Contact > {
return contactService.search(contactFilter)
} // Javascript
Bridge . interfaces . Android . searchContact ( { surname : "Pitt" } ) . then ( ( list ) => {
console . log ( list ) ;
} ) ; El tipo de llamada CallType.FULL_PROMISE le permite ejecutar el código de Android nativo en un subproceso de fondo, permitiendo que la ejecución de JavaScript continúe ininterrumpida. Como resultado, la vista web sigue siendo receptiva y es libre de realizar sus tareas. (Recomendado para tareas de larga duración)
// Kotlin
@NativeCall( CallType . FULL_PROMISE )
fun searchContact ( contactFilter : ContactFilter ) = doInBackground< List < Contact >> { promise ->
try {
promise.resolve(contactService.search(contactFilter))
} catch (e : Exception ) {
promise.reject(e)
}
} // Javascript
Bridge . interfaces . Android . searchContact ( { surname : "Pitt" } ) . then ( ( list ) => {
console . log ( list ) ;
} ) ; Agregue Maven Central al bloque de repositorios.
repositories {
google()
mavenCentral()
}Agregue la biblioteca al bloque de dependencias.
dependencies {
implementation ' com.github.andycandy-de:simple-android-bridge:1.1.1 '
} class AndroidNativeInterface : DefaultJSInterface ( " Android " ) {
@NativeCall( CallType . FULL_SYNC )
fun helloFullSync ( name : String ): String {
return " hello $name "
}
@NativeCall( CallType . WEB_PROMISE )
fun helloWebPromise ( name : String ): String {
return " hello $name "
}
@NativeCall( CallType . FULL_PROMISE )
fun helloFullPromise ( name : String ) = doInBackground< String > { promise ->
promise.resolve( " hello $name " )
}
} val bridge = Bridge (applicationContext, webView)
bridge.addJSInterface( AndroidNativeInterface ())Código de Android
// Bridge can be initialized by calling the 'init' function inside
// the 'onPageStarted' function of a WebViewClient
webView.webViewClient = object : WebViewClient () {
override fun onPageStarted ( view : WebView ? , url : String? , favicon : Bitmap ? ) {
bridge. init ()
}
}Código JavaScript
// Bridge can be initialized by calling the 'init' function in
// Javascript. Register function to 'Bridge.afterInitialize' to
// start the webapp after the bridge is initialized.
function startApp ( f ) {
if ( Bridge . initialized ) {
f ( )
} else {
Bridge . afterInitialize = f
}
}
Bridge . init ( )
startApp ( ( ) => {
// Start your webapp
} ) ; console . log ( Bridge . interfaces . Android . helloFullSync ( "Web" ) ) Licencia de MIT
Copyright (c) 2020 Andycandy-de
Copyright (c) 2021 Andycandy-de
Copyright (c) 2024 Andycandy-de
El permiso se otorga, de forma gratuita, a cualquier persona que obtenga una copia de este software y archivos de documentación asociados (el "software"), para tratar en el software sin restricción, incluidos los derechos de los derechos de usar, copiar, modificar, fusionar, publicar, distribuir, sublicense y/o vender copias del software, y para permitir que las personas a quienes se les proporciona el software para hacer, sujeto a las siguientes condiciones: las siguientes condiciones: las siguientes condiciones: las siguientes condiciones:
El aviso de derechos de autor anterior y este aviso de permiso se incluirán en todas las copias o porciones sustanciales del software.
El software se proporciona "tal cual", sin garantía de ningún tipo, expresa o implícita, incluidas, entre otros, las garantías de comerciabilidad, idoneidad para un propósito particular y no infracción. En ningún caso los autores o titulares de derechos de autor serán responsables de cualquier reclamo, daños u otra responsabilidad, ya sea en una acción de contrato, agravio o de otra manera, que surge, de o en relación con el software o el uso u otros tratos en el software.