| 导语
В настоящее время при разработке мобильных приложений H5 взаимодействие с Native незаменимо. В Native контейнером размещения H5 является WebView, и его ядром является использование элемента управления WebView для реализации URL-адреса загрузки.
Концепция WebView
WebView
используется для отображения веб-страницview
Компонент, который является основой для запуска вашего собственного браузера или отображения онлайн-контента в вашей теме. использоватьWebkit
Механизм рендеринга для отображения и поддерживает перемотку вперед и назад на основе истории просмотров, увеличение и уменьшение масштаба и многое другое.
Проще говоря
WebView
Это высокопроизводительный встроенный мобильный телефон.Webkit
Браузер ядра, компонент, упакованный в SDK. Однако здесь нет адресной строки и панели навигации, только простое отображение веб-интерфейса.
Выше описан разработчиком клиента, а с точки зрения фронтенд разработчика ощущения после использования такие:
WebView
Это может быть просто понято как страница вiframe
. Роднойapp
а такжеWebView
Взаимодействие можно просто рассматривать как страницу и страницу.iframe
взаимодействие со страницей. как страницы и внутри страницiframe
поделиться однимWindow
такой же, родной иWebView
Также поделился набором нативных методов.
Поскольку мы использовалиWebView
нестиH5
, то необходимоNative
взаимодействие междуWebView
Страницы размещеныJS
а такжеNative
Чтобы общаться, мы делаем «мост» этого общения какJSBridge
. Если вы участвовали во встроенном браузере WeChatH5
развития, вы найдете частое явление, называемоеWeixinJSBridge
.
JSBridge
JSBridge
Проще говоря, основнойJavaScript 提供调用 Native 功能的接口
, чтобы "внешняя часть" в гибридной разработке могла легко использовать адресное расположение, камеру и даже оплату и т.д.Native
Функция.
Поскольку это «просто», цель JSBridge определенно не только в том, чтобы «вызвать нативную функцию» как простую и широкую. На самом деле, JSBridge, как и значение слова «мост» в его названии, является мостом между нативным и не-нативным.构建 Native 和非 Native 间消息通信的通道
,И является双向通信的通道
.так называемый双向通信的通道
:
-
JS отправляет сообщения в Native: вызывает связанные функции, уведомляет Native о текущем состоянии JS и т. д.
-
Native отправляет сообщения в JS: отслеживание результатов вызова, push-сообщения, уведомление JS о текущем статусе Native и т. д.
JavaScript работает в отдельном JS-контексте (например, движке WebView Webkit, JCore). Из-за естественной изоляции этих контекстов от собственной операционной среды мы можем сравнить эту ситуацию с обменом данными RPC (удаленный вызов процедур, удаленный вызов процедур) и рассматривать каждый взаимный вызов между Native и JavaScript как вызов RPC. Таким образом, мы можем проектировать и реализовывать обычным способом RPC.
В дизайне JSBridge внешний интерфейс можно рассматривать как клиент RPC, а собственный конец можно рассматривать как серверный конец RPC, поэтому основная логика, которую должен реализовать JSBridge, выглядит следующим образом:通信调用(Native 与 JS 通信
а также句柄解析调用
. (Если вы работаете с интерфейсом и не знакомы с RPC, вы также можете сравнить этот процесс с процессом JSONP.)
Из вышеприведенного анализа видно, чтоJSBridge
Основные функции и обязанности, затем анализAndroid WebView
а такжеiOS WebView
Принцип реализации связи между Native и JS в .
Android WebView
До Android 4.4:
Android WebView
В низкой версии и старшей версии ядро различных версий webkit (поскольку многие новые функции H5 не поддерживаются на машинах Android с версией Android ниже 4.4) Android 4.4 после: Первоначально основан наWebkit
изWebView
начать на основеChromium
ядро, это изменение значительно улучшаетWebView
производительность компонентов иHTML5
,CSS3
,JavaScript
служба поддержки. Тем не менее, его API не сильно изменился: в нем представлено лишь небольшое количество новых API, но он совместим с более ранними версиями и не требует внесения серьезных изменений.
В Android WebView для реализации JS, вызывающего Java, есть 3 метода:
JavascriptInterface
WebViewClient.shouldOverrideUrlLoading()
WebChromeClient.onXXX()
1. JavascriptИнтерфейс
Это официальное решение для JS и Native-коммуникаций, предоставляемое Android.
Во-первых, нативная сторона должна реализовать такой класс и вызвать его для JavaScript.
public class WebAppInterface {
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
тогда поставь этоWebAppInterface
Класс со следующим кодом добавляется в JavaScriptInterface WebView.
WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
// 这里的Android会被当做一个变量,注入到页面的window中。
Затем вы можете вызвать Native в JS.
function showAndroidToast(toast) {
Android.showToast(toast);
}
2. WebViewClient.shouldOverrideUrlLoading()
Цель этого метода — перехватить все URL-схемы WebView.
URL Scheme
аналогичныйURL
Ссылка для удобстваapp
Напрямую называть друг друга разработанными, формальными и обычнымиURL
приблизительно, главное отличиеprotocol
а такжеhost
Обычно на заказ.
перехватыватьURL Scheme
Основной процесс:Web
каким-либо образом заканчиваться (например,iframe.src/location.href
)ОтправитьURL Scheme
просьба, послеNative
перехватил запрос иURL Scheme
(включая параметры, которые он принимает) для выполнения связанных операций.
Страница может создать специальную схему URL-адреса для запуска,shouldOverrideUrlLoading
перехватыватьURL
После оценки его формата, затемNative
Он может выполнять свою собственную логику.
public class CustomWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(
WebView view,
String url
) {
if (isJsBridgeUrl(url)) {
// JSbridge的处理逻辑
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
}
3. WebChromeClient.onXXX()
Модифицируя некоторые методы исходного окна браузера, затем перехватывая параметры фиксированных правил, а затем раздавая их соответствующим методам в Java для обработки
- оповещение, может быть WebView
WebChromeClient.onJsAlert()
монитор
- подтвердить, который может использоваться WebView
WebChromeClient.onJsConfirm()
монитор
- console.log, к которому можно получить доступ с помощью WebView
WebChromeClient.onConsoleMessage()
монитор
- подсказка, к которой может получить доступ WebView
WebChromeClient.onJsPrompt()
монитор
prompt — это простой пример, веб-страница вызываетprompt()
метод, клиент Android прослушиваетWebChromeClient.onJsPrompt()
События, перехватывать входящие параметры, если параметры соответствуют определенной спецификации протокола, то парсить параметры и кидать их на последующую Яву для обработки.
window.prompt(message, value);
WebChromeClient.onJsPrompt() будет вызван обратно. Значение параметра сообщения метода onJsPrompt() точно соответствует значению сообщения метода JS window.prompt().
public class CustomWebChromeClient extends WebChromeClient {
@Override
public boolean onJsPrompt(
WebView view,
String url,
String message,
String defaultValue,
JsPromptResult result
) {
// 处理JS 的调用逻辑
result.confirm();
return true;
}
}
Java вызывает JavaScript
Android в Kitkat (4.4) может использовать loadUrl только как фрагмент кода JavaScript.
webView.loadUrl("javascript:" + javaScriptString);
Версия после Kitkat также может быть реализована с помощью метода AssessmentJavascript:
webView.evaluateJavascript(javaScriptString, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
// native代码
}
});
IOS WebView
In apps that run in iOS 8 and later, use the WKWebView class instead of using UIWebView. Additionally, consider setting the WKPreferences property javaScriptEnabled to NO if you render files that are not supposed to run JavaScript.
До IOS8 WebView Apple использовал UIWEBVIEW, UiWebview имеет несколько вопросов в течение длительного времени:
- медленная загрузка
- Есть утечка памяти
- Использование памяти велико, оптимизация памяти затруднена
- Если использование памяти слишком много, она может быть уничтожена системой из-за слишком большого использования.
На WWDC 2014 iOS8 представила WKWebView, основную часть современного Webkit API в приложениях iOS 8 и OS X Yosemite. Он заменяет UIWebView в UIKit и WebView в AppKit, предоставляя унифицированный межплатформенный API. Имеет частоту обновления прокрутки 60 кадров в секунду, встроенные жесты, эффективные каналы обмена информацией между приложениями и веб-сайтами и тот же движок JavaScript, что и Safari.
JavaScript ↔︎ Быстрый механизм диалога
Использование пользовательских скриптов для внедрения JavaScript
WKUserScript допускает внедрение на страницу до или после загрузки тела. Эта мощная функция позволяет управлять веб-контентом безопасным и уникальным способом на странице.
Простой пример: пользовательский скрипт, в котором пользователь меняет фон, вставляется на веб-страницу:
let source = "document.body.style.background = #777";
// 注入脚本 在文档加载完成后执行
let userScript = WKUserScript()
let userScript = WKUserScript(source: source, injectionTime: .AtDocumentEnd, forMainFrameOnly: true)
let userContentController = WKUserContentController()
userContentController.addUserScript(userScript)
let configuration = WKWebViewConfiguration()
configuration.userContentController = userContentController
self.webView =WKWebView(frame: self.view.bounds, configuration: configuration)
Объекты могут быть инициализированы в исходной форме JavaScript, а также могут быть инициализированы с указанием того, вводить ли их перед загрузкой или в конце, а также влияет ли сценарий на этот макет или только на основной макет. Таким образом, пользовательский скрипт добавляется вWKUserContentController
в и сWKWebViewConfiguration
атрибут переданWKWebView
во время инициализации.
Этот пример можно легко распространить на более продвинутые методы модификации страницы, такие как удаление рекламы, скрытие комментариев и т. д.
Message Handlers
Используйте следующий код для связи с Native
window.webkit.messageHandlers.{NAME}.postMessage()
Handler
Имя можно передатьWKScriptMessageHandler
в соглашенииaddScriptMessageHandler()
Настройки функций интерфейса:
class NotificationScriptMessageHandler: NSObject, WKScriptMessageHandler {
func userContentController(
userContentController: WKUserContentController,
didReceiveScriptMessage message: WKScriptMessage!
) {
println(message.body)
}
}
let userContentController = WKUserContentController()
let handler = NotificationScriptMessageHandler()
userContentController.addScriptMessageHandler(handler, name: "notification")
Поэтому, когда в приложение приходит уведомление, скажем, о создании нового объекта на странице, соответствующая информация может быть передана следующим образом:
window.webkit.messageHandlers.notification.postMessage({body: '发送给Native'});
Добавьте пользовательские сценарии для прослушивания веб-событий и используйте обработчики сообщений для передачи информации обратно в приложение.
Суммировать
Принцип общения такойJSBridge
Суть реализации может быть реализована по-разному, но она остается неизменной. Здесь рекомендуемая реализация выглядит следующим образом:
-
JavaScript
передачаNative
Рекомендуемое использование注入 API
Путь. (Игнорируется iOS6, используется ниже Android 4.2WebViewClient
изonJsPrompt
Способ. ) -
Native
передачаJavaScript
Затем непосредственно выполните сваркуJavaScript
код подойдет.
Для других методов, таких как React Native, апплет WeChat, методы связи аналогичны описанным выше и оптимизированы в соответствии с реальной ситуацией.
В качестве примера возьмем сторону React Native для iOS: JavaScript работает в JCore, Фактически, так же, как и выше, JavaScript можно использовать для вызова собственных функций путем внедрения API. Однако React Native не предназначен для прямого вызова Object-C из JavaScript.为了与 Native 开发里事件响应机制一致
, разработаны, чтобы需要在 Object-C 去调 JavaScript 时才通过返回值触发调用
. Принцип в основном одинаково, но реализация отличается.