بناء جسر! تكامل سلس بين Android و WebApps
قم ببناء جسر قوي بين Android و WebApp مع مكتبة SimpleAndroidbridge. تتيح لك هذه المكتبة تقديم تطبيق ويب في عرض WebView Android وإنشاء JSInterface لتمكين الاتصال السلس بين النظامين. مشاركة الكائنات المعقدة والوعود ووظائف رد الاتصال ، كل ذلك بينما يظل تطبيق الويب الخاص بك مستجيبًا وفعالًا.
✓ مشاركة الكائنات - Android ⇄ الويب
✓ شارك الوعد - Android ⇄ الويب
✓ وظائف رد الاتصال - Android ← Web
✓ وظائف الاتصال غير الحظر - Android ⇄ الويب
✓ اكتب السلامة مع TypeScript - Android + Web
يدعم جسر JavaScript المدمج في Android SDK الأنواع البدائية فقط. مع SimpleAndroidbridge ، يمكنك مشاركة الكائنات المعقدة بين Android و Web بسهولة. ما عليك سوى تحديد الأنواع كوسائط أو قيم الإرجاع في وظائف Android الأصلية ، وستقوم المكتبة تلقائيًا بتحويل كائنات JavaScript إلى كائنات Kotlin والعكس بالعكس.
// 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" } ) )يقوم جافا سكريبت جسر في نظام Android SDK بتنفيذ وظائف بطريقة منع ، مما يتسبب في تجميد تطبيق الويب حتى تعود الوظيفة الأصلية. ومع ذلك ، مع هذه المكتبة ، يمكنك تحديد نوع إرجاع الوعد ، مما يسمح بتنفيذ عدم الحظر. من خلال استخدام وظيفة "doinbackground" ، يتم تنفيذ رمز Android في مؤشر ترابط الخلفية ، مما يمنع حظر تطبيق الويب.
// 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 ) ;
} ) ;إذا كنت على دراية بـ JavaScript ، فمن المحتمل ألا تكون غريبًا على وظائف رد الاتصال. يأخذ SimpleAndroidbridge هذا المفهوم خطوة إلى الأمام ، مما يتيح لك حقن وظائف رد الاتصال JavaScript مباشرة في طبقة Android ، وبالتالي إنشاء تفاعل سلس بين تطبيق الويب الخاص بك و 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!" )
} ) لتمرير وسيطة إلى وظيفة JavaScript ، استخدم نوع JSFunctionWithArg ، وهو مصمم خصيصًا لقبول وسيطة.
// 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 )
} )لتمرير وسيطات متعددة إلى وظيفة ، فكر في إنشاء فئة بيانات.
بالنسبة للوظائف التي تحتاج إلى إرجاع نتيجة إلى طبقة Android ، يمكنك استخدام إما JSFunctionWithPromise للوظائف بدون وسيط أو JSFunctionWithPromiseAndArg للوظائف التي تقبل الوسيطة.
// 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 ) } )
} )ملحوظة
لإصدار JSFunction ومسح الربط ، ما عليك سوى استدعاء الوظيفة close . تقوم JSFunction بتنفيذ الواجهة AutoCloseable ، مما يمكّنك من الاستفادة من المحاولة مع الموارد أو AutoCloseable.use {} الكتل لإدارة دورة حياة الوظيفة تلقائيًا وضمان التنظيف المناسب.
function.use { it() } بالإضافة إلى ذلك ، إذا كان تطبيق الويب أو WebView يدعم إعادة التحميل ، فمن المستحسن إضافة Afterinitializelistener إلى الجسر. سيساعد هذا المستمع في إطلاق أي JSFunctions المتاحة ، مما يضمن وجود حالة نظيفة بعد التهيئة.
تدعم هذه المكتبة أنواع المكالمات الأصلية المختلفة التي تتيح لك تحديد كيفية الاتصال بالرمز الأصلي.
يستدعي نوع المكالمة CallType.FULL_SYNC الكود الأصلي بطريقة حظر ، مما تسبب في توقف تنفيذ JavaScript إلى أن تعود وظيفة Android الأصلية. نتيجة لذلك ، تظل طريقة عرض الويب غير مستجيبة حتى يكتمل التنفيذ الأصلي. (غير موصى به للمهام طويلة الأمد)
// Kotlin
@NativeCall( CallType . FULL_SYNC )
fun searchContact ( contactFilter : ContactFilter ): List < Contact > {
return contactService.search(contactFilter)
} // Javascript
console . log ( Bridge . interfaces . Android . searchContact ( { surname : "Pitt" } ) ) تعمل CallType.WEB_PROMISE نوع المكالمة بشكل مشابه لمكالمة FULL_SYNC ، مع وجود اختلاف رئيسي في أن مكالمة JavaScript تُرجع وعدًا. ومع ذلك ، لا تزال وظيفة Android الأصلية يتم استدعاؤها بطريقة حظر. (موصى به إذا كنت غير متأكد من مدة المهمة وقد تحتاج إلى الترحيل إلى FULL_PROMISE في المستقبل)
// 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 ) ;
} ) ; يمكّنك نوع الاتصال CallType.FULL_PROMISE من تنفيذ رمز Android الأصلي في مؤشر ترابط الخلفية ، مما يسمح بتنفيذ JavaScript للاستمرار دون انقطاع. نتيجة لذلك ، تظل طريقة عرض الويب مستجيبة ومجانية في أداء مهامها. (موصى به للمهام طويلة الأمد)
// 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 ) ;
} ) ; أضف Maven Central إلى كتلة المستودعات.
repositories {
google()
mavenCentral()
}أضف المكتبة إلى كتلة التبعيات.
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 ())رمز 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 ()
}
}رمز 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" ) ) رخصة معهد ماساتشوستس للتكنولوجيا
حقوق الطبع والنشر (C) 2020 Andycandy-De
حقوق الطبع والنشر (C) 2021 Andycandy-De
حقوق الطبع والنشر (C) 2024 Andycandy-de
يتم منح الإذن بموجب هذا ، مجانًا ، لأي شخص يحصل على نسخة من هذا البرنامج وملفات الوثائق المرتبطة به ("البرنامج") ، للتعامل في البرنامج دون تقييد ، بما في ذلك على سبيل المثال لا الحصر حقوق استخدام الأشخاص ونسخها ودمجها ودمجها وتوزيعها وتوزيعها على ما يلي:
يجب إدراج إشعار حقوق الطبع والنشر أعلاه وإشعار الإذن هذا في جميع النسخ أو الأجزاء الكبيرة من البرنامج.
يتم توفير البرنامج "كما هو" ، دون أي ضمان من أي نوع ، صريح أو ضمني ، بما في ذلك على سبيل المثال لا الحصر ضمانات القابلية للتسويق واللياقة لغرض معين وعدم الانفجار. لا يجوز بأي حال من الأحوال أن يكون المؤلفون أو حاملي حقوق الطبع والنشر مسؤولاً عن أي مطالبة أو أضرار أو مسؤولية أخرى ، سواء في إجراء عقد أو ضرر أو غير ذلك ، ناشئة عن أو خارج البرنامج أو الاستخدام أو غيرها من المعاملات في البرنامج.