前言
最近在使用Cordova开发应用,我的主要工作是提供一个Android的壳,并提供一些原生方法的插件让前端可以调用,正常情况下,每次发包,我们都需要将前端的文件放入assets文件夹下的www目录下,但是这样会带来一个问题,那就是如果前端有改动的化,Android端需要频繁的进行发包,这样就很麻烦了,上线后如果前端有Bug也不能实时的更新应用,于是我们就考虑直接去访问前端的URL路径不就行了。
直接使用前端部署后的URL后出现的问题解决
1. 直接访问远程URL
于是我们MainActivity的onCreate()中我们直接调用远程URL应该就可以了。
loadUrl("https://www.baidu.com")//此处以百度的URL作为例子
但是事情貌似没有想象中的那么顺利,此时打开界面,前端会报错,就是说找不到cordova.js
2. 解决Cordova找不到的问题
通过一通搜索之后,最终得到解决方案通过拦截请求将js中引用的cordova路径转成本地路径实现,具体修改SystemWebViewClient类:
private static final String INJECTION_TOKEN = "http://injection/"; //新增
@Override
@SuppressWarnings("deprecation")
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
//-----------新增-----------
if(url != null && url.contains(INJECTION_TOKEN)) {
String assetPath = url.substring(url.indexOf(INJECTION_TOKEN) + INJECTION_TOKEN.length(), url.length());
try {
WebResourceResponse response = new WebResourceResponse(
"application/javascript",
"UTF8",
view.getContext().getAssets().open(assetPath)
);
return response;
} catch (IOException e) {
e.printStackTrace(); // Failed to load asset file
return new WebResourceResponse("text/plain", "UTF-8", null);
}
}
//-----------新增-----------
...
}
同时前端对cordova.js的引用改成:
<script src=http://injection/www/cordova.js type=text/javascript charset=UTF-8></script>
打开之后发现能够正常的找到cordova实例了。
3. 解决调用execute没有响应的问题
虽然不报错了,但是前端调用cordova的execute方法时返现虽然没有报错,但是也没有响应,这里也很让人纳闷,也不报错,但是为什么没有执行成功呢?经过一番的排查,我们从Log中看出了问题,
Ignoring exec() from previous page load
这是因为Cordova对外部网站对本机的交互有限制,需要添加进入白名单,于是我们去修改WhitelistPlugin这个类,将默认的是否允许交互设置为true即可。
@Override
public Boolean shouldAllowNavigation(String url) {
if (allowedNavigations.isUrlWhiteListed(url)) {
return true;
}
return true; // Default policy
}
此时重新打开一切就都正常了。
4. 解决请求外部URL超时的问题
实际使用中,在某些终端打开Cordova的APP时可能会报
Application Error - The connection to the server was unsuccessful
遇到这个问题,我们只需要在config.xml中添加以下配置即可:
<preference name="loadUrlTimeoutValue" value="100000" />
总结
这样访问外部URL的一些坑算是基本解决的差不多了,剩下的就让前端小伙伴愉快的去玩耍去吧…
最新发现的解决方案(2021.9.14)
上面提供的解决方案还是会引发其他的一些问题,比如说cordova_plugins.js
没有添加依赖等,后面经过一段时间的查阅,发现已经有前人帮我们解决好了这个问题,并且已经为我们提供了一个插件方面我们使用,建议大家直接采用这个方案,唯一要注意的是,添加插件可能会格式化Manifest文件,这里需要注意下。
cordova plugin add cordova-plugin-remote-injection
附上链接地址:
cordova-plugin-remote-injection