mirror of https://github.com/axmolengine/axmol.git
Fix crash in web view on android
This commit is contained in:
parent
e789ab97be
commit
ee3c000b43
|
@ -35,8 +35,11 @@
|
||||||
#include "UIWebView.h"
|
#include "UIWebView.h"
|
||||||
#include "platform/CCGLView.h"
|
#include "platform/CCGLView.h"
|
||||||
#include "base/CCDirector.h"
|
#include "base/CCDirector.h"
|
||||||
|
#include "base/CCScheduler.h"
|
||||||
#include "platform/CCFileUtils.h"
|
#include "platform/CCFileUtils.h"
|
||||||
#include "ui/UIHelper.h"
|
#include "ui/UIHelper.h"
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
#define CLASS_NAME "org/cocos2dx/lib/Cocos2dxWebViewHelper"
|
#define CLASS_NAME "org/cocos2dx/lib/Cocos2dxWebViewHelper"
|
||||||
|
|
||||||
|
@ -45,7 +48,7 @@
|
||||||
static const std::string s_defaultBaseUrl = "file:///android_asset/";
|
static const std::string s_defaultBaseUrl = "file:///android_asset/";
|
||||||
static const std::string s_sdRootBaseUrl = "file://";
|
static const std::string s_sdRootBaseUrl = "file://";
|
||||||
|
|
||||||
static std::string getFixedBaseUrl(const std::string& baseUrl)
|
static std::string getFixedBaseUrl(const std::string& baseUrl)
|
||||||
{
|
{
|
||||||
std::string fixedBaseUrl;
|
std::string fixedBaseUrl;
|
||||||
if (baseUrl.empty())
|
if (baseUrl.empty())
|
||||||
|
@ -401,45 +404,73 @@ namespace cocos2d {
|
||||||
setScalesPageToFitJNI(_viewTag, scalesPageToFit);
|
setScalesPageToFitJNI(_viewTag, scalesPageToFit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// executed from Java's thread (we should invoke callback on cocos thread)
|
||||||
bool WebViewImpl::shouldStartLoading(const int viewTag, const std::string &url) {
|
bool WebViewImpl::shouldStartLoading(const int viewTag, const std::string &url) {
|
||||||
auto it = s_WebViewImpls.find(viewTag);
|
|
||||||
if (it != s_WebViewImpls.end()) {
|
std::mutex m;
|
||||||
auto webView = s_WebViewImpls[viewTag]->_webView;
|
std::condition_variable cv;
|
||||||
if (webView->_onShouldStartLoading) {
|
bool finished = false;
|
||||||
return webView->_onShouldStartLoading(webView, url);
|
bool allowLoad = true;
|
||||||
|
|
||||||
|
Director::getInstance()->getScheduler()->performFunctionInCocosThread([&]{
|
||||||
|
auto it = s_WebViewImpls.find(viewTag);
|
||||||
|
if (it != s_WebViewImpls.end()) {
|
||||||
|
auto webView = s_WebViewImpls[viewTag]->_webView;
|
||||||
|
if (webView->_onShouldStartLoading) {
|
||||||
|
allowLoad = webView->_onShouldStartLoading(webView, url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
m.lock();
|
||||||
|
finished = true;
|
||||||
|
m.unlock();
|
||||||
|
cv.notify_one();
|
||||||
|
});
|
||||||
|
|
||||||
|
// wait for result from cocos thread
|
||||||
|
std::unique_lock<std::mutex> lk(m);
|
||||||
|
cv.wait(lk, [&finished]{ return finished; });
|
||||||
|
|
||||||
|
return allowLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// executed from Java's thread (we should invoke callback on cocos thread)
|
||||||
void WebViewImpl::didFinishLoading(const int viewTag, const std::string &url){
|
void WebViewImpl::didFinishLoading(const int viewTag, const std::string &url){
|
||||||
auto it = s_WebViewImpls.find(viewTag);
|
Director::getInstance()->getScheduler()->performFunctionInCocosThread([viewTag, url]{
|
||||||
if (it != s_WebViewImpls.end()) {
|
auto it = s_WebViewImpls.find(viewTag);
|
||||||
auto webView = s_WebViewImpls[viewTag]->_webView;
|
if (it != s_WebViewImpls.end()) {
|
||||||
if (webView->_onDidFinishLoading) {
|
auto webView = s_WebViewImpls[viewTag]->_webView;
|
||||||
webView->_onDidFinishLoading(webView, url);
|
if (webView->_onDidFinishLoading) {
|
||||||
|
webView->_onDidFinishLoading(webView, url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// executed from Java's thread (we should invoke callback on cocos thread)
|
||||||
void WebViewImpl::didFailLoading(const int viewTag, const std::string &url){
|
void WebViewImpl::didFailLoading(const int viewTag, const std::string &url){
|
||||||
auto it = s_WebViewImpls.find(viewTag);
|
Director::getInstance()->getScheduler()->performFunctionInCocosThread([viewTag, url]{
|
||||||
if (it != s_WebViewImpls.end()) {
|
auto it = s_WebViewImpls.find(viewTag);
|
||||||
auto webView = s_WebViewImpls[viewTag]->_webView;
|
if (it != s_WebViewImpls.end()) {
|
||||||
if (webView->_onDidFailLoading) {
|
auto webView = s_WebViewImpls[viewTag]->_webView;
|
||||||
webView->_onDidFailLoading(webView, url);
|
if (webView->_onDidFailLoading) {
|
||||||
|
webView->_onDidFailLoading(webView, url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// executed from Java's thread (we should invoke callback on cocos thread)
|
||||||
void WebViewImpl::onJsCallback(const int viewTag, const std::string &message){
|
void WebViewImpl::onJsCallback(const int viewTag, const std::string &message){
|
||||||
auto it = s_WebViewImpls.find(viewTag);
|
Director::getInstance()->getScheduler()->performFunctionInCocosThread([viewTag, message]{
|
||||||
if (it != s_WebViewImpls.end()) {
|
auto it = s_WebViewImpls.find(viewTag);
|
||||||
auto webView = s_WebViewImpls[viewTag]->_webView;
|
if (it != s_WebViewImpls.end()) {
|
||||||
if (webView->_onJSCallback) {
|
auto webView = s_WebViewImpls[viewTag]->_webView;
|
||||||
webView->_onJSCallback(webView, message);
|
if (webView->_onJSCallback) {
|
||||||
|
webView->_onJSCallback(webView, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebViewImpl::draw(cocos2d::Renderer *renderer, cocos2d::Mat4 const &transform, uint32_t flags) {
|
void WebViewImpl::draw(cocos2d::Renderer *renderer, cocos2d::Mat4 const &transform, uint32_t flags) {
|
||||||
|
|
Loading…
Reference in New Issue