問題の説明
アプリの Web 部分を chrome://inspect/#devices で、または Android Studio で直接デバッグすると、「Notifying Native Hook」というメッセージが表示されます。chrome://inspect/#devices を使用してアプリで使用されている Web ページを調べると、メッセージのソースが VM298:5 であることがわかります (VM の後に別の番号でも見たことがあることは確かです)。ソースをクリックすると、次の関数が見つかります。
(function () {
if (document.readyState === "complete") {
var foundMessageBridge = false
function notifyMessageBridge() {
console.log("Notifying Native Hook")
if (window.__KlarnaNativeHook != null) {
console.log("Klarna Native Hook was notified")
window.__KlarnaNativeHook.setNativeReady()
foundMessageBridge = true
} else {
window.setTimeout(notifyMessageBridge, 500)
}
}
notifyMessageBridge()
}
window.addEventListener('load', () => {
let interval = null
let notifyMessageBridge = () => {
if (window.__KlarnaNativeHook != null) {
window.__KlarnaNativeHook.setNativeReady()
clearInterval(interval)
}
}
interval = setInterval(notifyMessageBridge, 500)
})
}())
それが最終的に、それがKlarnaと関係があることに私を導きました. 私はこれに圧倒されているので、私のアプリは if (window.__KlarnaNativeHook != null) に入っていないと思います。
いくつかのデバッグの後、次のことに気付きました。
- Klarna とのやり取りを開始すると、アプリが if (window.__KlarnaNativeHook != null) に入ります。しかし、一度だけで、その後スパム行為が再開されます。
- 行を削除すると
(activity as MainActivity).klarnaHybridSDK.addWebView(myWebView)
、メッセージのスワンピングが停止します。それほど驚くべきことではないと思います。 - 私のアプリのWebページとは別に、空の無題のWebページが生成され、コンソールに「ネイティブフックの通知」のみが出力され、他には何もコードも何も表示されません。
- 沼地とは別に、アプリは Klarna で正常に動作しています。
これが SDK のバグなのか、それとも私のエラーなのかはわかりません。
「Notifying Native Hook」のスパムを止める方法について何か提案はありますか? (私はそれをフィルタリングする方法を知っていますが、120 メッセージ/分 * (私のアプリの Web ページ + 生成された無題) であり、毎回それを行うのは面倒です)
コード
主な活動
class MainActivity : AppCompatActivity(), KlarnaHybridSDKCallback {
...
lateinit var klarnaHybridSDK : KlarnaHybridSDK
override fun onCreate(savedInstanceState: Bundle?) {
klarnaHybridSDK = KlarnaHybridSDK("myapp://", this)
...
}
override fun didHideFullscreenContent(webView: WebView, completion: OnCompletion) {
Timber.i("Klarna didHideFullscreenContent called")
completion.run()
}
override fun didShowFullscreenContent(webView: WebView, completion: OnCompletion) {
Timber.i("Klarna didShowFullscreenContent called")
completion.run()
}
override fun onErrorOccurred(webView: WebView, error: KlarnaMobileSDKError) {
Timber.i("Klarna onErrorOccurred called")
Timber.i("Klarna Error: $error")
}
override fun willHideFullscreenContent(webView: WebView, completion: OnCompletion) {
Timber.i("Klarna willHideFullscreenContent called")
completion.run()
}
override fun willShowFullscreenContent(webView: WebView, completion: OnCompletion) {
Timber.i("Klarna willShowFullscreenContent called")
completion.run()
}
}
フラグメント クラス
class myFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
...
/*WEBVIEW*/
myWebView.settings.javaScriptEnabled = true
WebView.setWebContentsDebuggingEnabled(true)
val context = this.activity?.applicationContext
myWebView.addJavascriptInterface(
WebAppInterface(
myWebView, context
), "Android")
myWebView.settings.loadWithOverviewMode = true
myWebView.settings.useWideViewPort = true
myWebView.settings.domStorageEnabled = true
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
myWebView.settings.mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE
}
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){
myWebView.settings.cacheMode = WebSettings.LOAD_NO_CACHE
if(this.activity?.applicationInfo?.flags != 0 && ApplicationInfo.FLAG_DEBUGGABLE != 0) {
WebView.setWebContentsDebuggingEnabled(true)
Timber.i("setWebContentsDebuggingEnabled")
}
}
ticketWebView.webViewClient = object: WebViewClient(){
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
...
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
...
if (view != null) {
(activity as MainActivity).klarnaHybridSDK.newPageLoad(view)
}
...
}
override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
...
}
override fun onReceivedHttpError(view: WebView?, request: WebResourceRequest?, errorResponse: WebResourceResponse?) {
super.onReceivedHttpError(view, request, errorResponse)
...
//Added to prevent Klarna's address search failing to cause the app to show the error screen.
if (request?.url.toString().contains("klarna.com/eu/address")) {
Timber.i("${receivedError}")
Timber.i("Ignoring error since it's simply Klarna's address search failing")
}
...
}
@TargetApi(21)
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
val url = request?.url
...
return (activity as MainActivity).klarnaHybridSDK.shouldFollowNavigation(url.toString())
}
/*To handle cases where the target API < 21*/
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
return (activity as MainActivity).klarnaHybridSDK.shouldFollowNavigation(url.toString())
}
}
val url = "myAppUrl.php"
val postData = "data=" + URLEncoder.encode(data, "UTF-8").toString()
myWebView.postUrl(url, postData.toByteArray())
return root
}
...
}
再現する手順
アプリを起動しました
Chrome で chrome://inspect/#devices を開きました。
関連する Web ページを見つけた
「調べる」を押した
予想される行動
コンソールのメッセージに圧倒されません。
デバイスとバージョン:
デバイス: サムスン A10
OSバージョン:アンドロイド9
Klarna アプリ内 SDK バージョン: com.klarna.mobile:sdk:2.0.16