是否可以防止在 Cordova 中重新初始化应用程序?

Posted

技术标签:

【中文标题】是否可以防止在 Cordova 中重新初始化应用程序?【英文标题】:Is it possible to prevent app re-initialization in Cordova? 【发布时间】:2021-01-20 00:35:46 【问题描述】:

我正在构建一个调用 Webview 的 Cordova 项目,并且基本上使用它来将我的网页显示为应用程序。我已经在 android 上测试了我的代码,应用程序加载正常,页面加载正常。我可以浏览我的网站并使用硬件“返回”按钮导航回初始页面。但是,当我到达初始页面时,如果我再次单击“返回”按钮,我会看到设备就绪屏幕,并且应用程序通常不会重新初始化。我已经在 Android 模拟器 (Galaxy Nexus API 30) 和我的个人 Android 设备 (Samsung Galaxy S7) 上对此进行了测试。

我想知道是否可以阻止应用返回设备就绪屏幕,或强制应用重新初始化,以使用户不会在设备就绪屏幕上“卡住”?我在 Duck Duck Go、Google 和 Stack Overflow 上进行了广泛的搜索,但找不到任何人以前解决过这个特定问题。请注意,我对 Cordova 和 javascript 还很陌生,但我是 html 专家。

这是我的 index.html 文件中的应用代码:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="format-detection" content="telephone=no" />
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
        <link rel="stylesheet" type="text/css" href="css/index.css" />
        <title>Cordova App c15-iab</title>
    </head>
    <body>
        <div class="app">
            <h1>My Sample App</h1>
            <div id="deviceready" class="blink">
                <p class="event listening">Connecting to Device</p>
                <p class="event received">Device is Ready</p>
            </div>
        </div>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript">
            var app = 
                // Application Constructor
                initialize: function() 
                    this.bindEvents();
                ,
                // Bind Event Listeners
                //
                // Bind any events that are required on startup. Common events are:
                // 'load', 'deviceready', 'offline', and 'online'.
                bindEvents: function() 
                    document.addEventListener('deviceready', this.onDeviceReady, false);
                ,
                // deviceready Event Handler
                //
                // The scope of 'this' is the event. In order to call the 'receivedEvent'
                // function, we must explicity call 'app.receivedEvent(...);'
                onDeviceReady: function() 
                    app.receivedEvent('deviceready');

                    // Add event listeners.
                    document.addEventListener("offline", goOffline, false);
                    document.addEventListener("online", goOnline, false);

                ,
                // Update DOM on a Received Event
                receivedEvent: function(id) 
                    var parentElement = document.getElementById(id),
                        listeningElement = parentElement.querySelector('.listening'),
                        receivedElement = parentElement.querySelector('.received');
            
                    listeningElement.setAttribute('style', 'display:none;');
                    receivedElement.setAttribute('style', 'display:block;');
            
                    console.log('Received Event: ' + id);
                
            ;
            app.initialize();

            // BT next several lines of code. 20200907_1810
            function goOffline() 
                // Redirect to your local/offline page here
                document.location = 'offline.html';
            
            function goOnline() 
                // Load the actual online content in InAppBrowser/WebView
            
                //use some really slow page for testing.  The http page has been whitelisted.
                var path="http://www.someexamplesite.com";
            
                // Using '_self' to force WebView open.
                var ref = cordova.InAppBrowser.open(path, '_self', 'location=no');
            
                //spinner html
                var spinner ="<!DOCTYPE html><html><head><meta name='viewport' content='width=device-width,height=device-height,initial-scale=1'><style>.loader position: absolute;    margin-left: -2em;    left: 50%;    top: 50%;    margin-top: -2em;    border: 5px solid #f3f3f3;    border-radius: 50%;    border-top: 5px solid #3498db;    width: 50px;    height: 50px;    -webkit-animation: spin 1.5s linear infinite;    animation: spin 1.5s linear infinite;@-webkit-keyframes spin   0%  -webkit-transform: rotate(0deg);  100%  -webkit-transform: rotate(360deg); @keyframes spin   0%  transform: rotate(0deg);   100%  transform:rotate(360deg); </style></head><body><div class='loader'></div></body></html>";
            
                //intended webpage is loaded here
                ref.executeScript(code: "(function() document.write(\""+spinner+"\");window.location.href='"+path+"';)()");
            
                //loadstart event
                ref.addEventListener('loadstart', function(event) 
                    //nothing specific needed for spinner                        
                );
            
                //loadstop event
                ref.addEventListener('loadstop', function(event) 
                    //nothing specific needed for spinner
                );
                
            
        </script>
    </body>
</html>

谁能帮忙?

【问题讨论】:

只是不提供网页,而是将其设为本地 SPA(单页应用程序).​​.....然后设备的后退按钮显然无法导航到任何地方,因为有没有历史。也可以远程加载 SPA,但唯一的问题是这在离线时不起作用。这就是为什么它应该被打包而不是获取。 亲爱的 Martin,我对 javascript 还很陌生,我不确定我是否足够精通构建一个 SPA。另外,我不确定它是否合适,因为我的目标是在我的 InAppBrowser 中提供远程网页,就好像它是实际的应用程序一样。你还有其他建议吗?布赖恩 【参考方案1】:

我会尝试拦截后退按钮事件并在 window.history.length 降至 1 时取消它。

【讨论】:

亲爱的 weHe,我尝试添加 'document.addEventListener("backbutton", onBackKeyDown, false);'到app的onDeviceReady事件,然后添加如下函数: [code] function onBackKeyDown() alert('window.location.history = ' + window.location.history); if (window.location.history == 1) return false; [/代码]。该功能不起作用,警报甚至没有显示在我的 Android 模拟器上。在我的三星 Galaxy S7 手机上,警报仅在用户返回应用程序初始化屏幕时显示,因此不起作用。还有其他想法吗? 你确定你捕捉到了 deviceready(不是 onDeviceReady)吗?记录它并远程观察控制台,直到你有证据。我刚刚在 android 模拟器上测试了我的应用程序,我看到“后退按钮”事件可靠地触发,在我的平板电脑上也是如此。它是 window.history 而不是 window.location.history;这也是一个数组,所以检查它的 .length==1!请参阅developer.mozilla.org/en-US/docs/Web/API/Window/history 希望对您有所帮助 - 一切顺利! weHe 我最终将我的应用程序转换为渐进式 Web 应用程序。这解决了我所有的问题。不过,感谢您的帮助。

以上是关于是否可以防止在 Cordova 中重新初始化应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 Cordova 应用程序中的 web 视图顶部放置静态图像

如何在不更新应用程序的情况下重新加载 Cordova 应用程序的 UI

当我在 Safari 中将应用程序切换到 Facebook 时,防止 IOS 重新启动应用程序

如何动态更改Cordova白名单?

是否可以在不重新编译的情况下使科尔多瓦应用程序可调试?

使用cordova防止android编辑栏