Cordova 다중 페이지 등록backbutton 이벤트, 한 페이지가 이벤트에 응답한 후 다른 페이지가 응답하지 않는 문제 해결
Android Studio,Cordova5.3.3
문제 설명:
페이지 1:
document.addEventListener('deviceready', function(){
document.addEventListener("backbutton", onBackKeyDown, false);
},false);
function onBackKeyDown(){
//
}
페이지 2:
document.addEventListener('deviceready', function(){
document.addEventListener("backbutton", onBackKeyDown, false);
},false);
function onBackKeyDown(){
//
}
내가 첫 번째 인터페이스에서 리턴 키를 누르면 프로그램이 정상적으로 응답하고 두 번째 페이지로 이동할 때 리턴 키를 다시 누르면 효과가 없고 심지어 음량 가감 키도 사용할 수 없다.그러나 첫 번째 인터페이스는 되돌아오는 이벤트를 터치하지 않고 두 번째 인터페이스로 이동하여 정상적으로 응답한다.인터넷에서도 비슷한 문제에 부딪힌 친구가 있지만 해결되지 않았다.문제 분석:
아니면 그 말을 믿느냐. 원본 앞에 비밀이 없기 때문에 나는 원본 코드에서 문제의 원인과 해결 방법을 찾기 시작했다.
우선 저는 코도바에서js를 분석합니다. 왜냐하면 우리는 이 파일을 통해 백button 이벤트를 등록했기 때문입니다.cordova.js 1532 줄:
var APP_PLUGIN_NAME = Number(cordova.platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
// Inject a listener for the backbutton on the document.
var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
backButtonChannel.onHasSubscribersChange = function() {
// If we just attached the first handler or detached the last handler,
// let native know we need to override the back button.
exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [this.numHandlers == 1]);
};
에서 4.x버전 이상,cordova.js는Core 안드로이드를 사용하여 리턴 키를 등록하고 호출하는 방법은override Backbutton 방법입니다.다음은 Core Android.java, 231 줄:
public void overrideBackbutton(boolean override) {
LOG.i("App", "WARNING: Back Button Default Behavior will be overridden. The backbutton event will be fired!");
webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_BACK, override);
}
에서 알 수 있듯이 백button 이벤트를 등록했고 구체적인 등록 원본은 스스로 볼 수 있다.다음은 이벤트가 어떻게 네이티브에서 웹뷰로 전송되는지 보여 줍니다.
public Boolean onDispatchKeyEvent(KeyEvent event) - CordovaWebViewImpl.java
private void sendJavascriptEvent(String event) - CordovaWebViewImpl.java
public void fireJavascriptEvent(String action) - CoreAndroid.java
private void sendEventMessage(String action) - CoreAndroid.java
public void sendPluginResult(PluginResult pluginResult) - CallbackContext.java
webView.sendPluginResult(pluginResult, callbackId);//최종적으로 이 코드를 호출해서 웹뷰에 백button 이벤트를 보냅니다.
내가 디버그 코드를 추적했을 때, 두 번째 응답이 없었을 때, 위의 코드가 확실히 실행되었지만, 콜백 Id는 여전히 이전의 값이었다.콜백 Id는 매번 코도바입니다.js가 초기화될 때 생성되었고 인터페이스를 전환할 때마다 코어 안드로이드 등 모든 플러그인은 다시 초기화되었고 이따가 증거를 꺼냅니다.코드는 다음과 같습니다.
private void sendJavascriptEvent(String event) {
if (appPlugin == null) {
appPlugin = (CoreAndroid)pluginManager.getPlugin(CoreAndroid.PLUGIN_NAME);
} if (appPlugin == null) {
LOG.w(TAG, "Unable to fire event without existing plugin");
return;
}
appPlugin.fireJavascriptEvent(event);
}
여기서 알 수 있듯이 sendJavascript Event () 방법을 한 번 호출한 후에 appPlugin 대상은 이미 CordovaWebViewImpl 대상에 존재한다면 위에서 문제가 발생한 원인도 명확하게 설명할 수 있다.
해결 방법:
CordovaWebViewImpl.java의 public void loadUrl IntoView(final String URL,boolean recreatePlugins)에서
public void loadUrlIntoView(final String url, boolean recreatePlugins) {
LOG.d(TAG, ">>> loadUrl(" + url + ")");
if (url.equals("about:blank") || url.startsWith("javascript:")) {
engine.loadUrl(url, false);
return;
}
recreatePlugins = recreatePlugins || (loadedUrl == null);
if (recreatePlugins) {
// Don't re-initialize on first load.
if (loadedUrl != null) {
resetCoreAndroidPlugin();
pluginManager.init();
}
loadedUrl = url;
}
페이지를 로드할 때마다pluginManager를 사용하는 것을 알 수 있습니다.init();플러그인을 초기화하는 방법입니다.여기에서 나는 내가 추가한reset Core 안드로이드 Plugin () 방법으로 Cordova Web View Impl에 있는 appPlugin 변수를 리셋하고,reset Core 안드로이드 Plugin () 방법은 다음과 같다
public void resetCoreAndroidPlugin(){
appPlugin = null;
}
나는github에서 cordova-android 원본 코드를 포착했습니다. 이미pull request입니다. 클릭하여 보십시오.
문필이 좋지 않으니, 만약 이해하지 못하는 점이 있으면 공동으로 연구 토론할 수 있다.재능이 부족하고 학문이 얕으니, 잘못된 점이 있으면 바로잡아 주십시오!
나의 시나닷컴 웨이보width="100%"height="120"class="share self"frameborder="0"scrolling="no"src="http://widget.weibo.com/weiboshow/index.php?language=&width=0&height=120&fansRow=2&ptype=1&speed=0&skin=1&isTitle=1&noborder=1&isWeibo=0&isFans=0&uid=2237047381&verifier=f873c807&dpc=1">
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Android Webkit 요약(개요에서 최신 AndroidX까지)WebView는 Android 응용 프로그램에서 HTML과 웹 페이지 등 HTML 파일을 렌더링(표시)하는 기능을 제공하는 View입니다. Android Webkit은 실제 WebView의 핵심 기술인 렌더링 엔진(...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.