Merge pull request #14154 from Dimon4eg/fix-crash-in-web-view-on-android

Fix crash in web view on android
This commit is contained in:
pandamicro 2015-10-22 10:35:00 +08:00
commit a7e5946b7d
3 changed files with 45 additions and 11 deletions

View File

@ -11,6 +11,27 @@ import android.widget.FrameLayout;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.concurrent.CountDownLatch;
class ShouldStartLoadingWorker implements Runnable {
private CountDownLatch mLatch;
private boolean[] mResult;
private final int mViewTag;
private final String mUrlString;
ShouldStartLoadingWorker(CountDownLatch latch, boolean[] result, int viewTag, String urlString) {
this.mLatch = latch;
this.mResult = result;
this.mViewTag = viewTag;
this.mUrlString = urlString;
}
@Override
public void run() {
this.mResult[0] = Cocos2dxWebViewHelper._shouldStartLoading(mViewTag, mUrlString);
this.mLatch.countDown(); // notify that result is ready
}
}
public class Cocos2dxWebView extends WebView {
private static final String TAG = Cocos2dxWebViewHelper.class.getSimpleName();
@ -75,7 +96,20 @@ public class Cocos2dxWebView extends WebView {
Log.d(TAG, "Failed to create URI from url");
}
return Cocos2dxWebViewHelper._shouldStartLoading(mViewTag, urlString);
boolean[] result = new boolean[] { true };
CountDownLatch latch = new CountDownLatch(1);
// run worker on cocos thread
activity.runOnGLThread(new ShouldStartLoadingWorker(latch, result, mViewTag, urlString));
// wait for result from cocos thread
try {
latch.await();
} catch (InterruptedException ex) {
Log.d(TAG, "'shouldOverrideUrlLoading' failed");
}
return result[0];
}
@Override
@ -102,7 +136,7 @@ public class Cocos2dxWebView extends WebView {
});
}
}
public void setWebViewRect(int left, int top, int maxWidth, int maxHeight) {
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);

View File

@ -147,10 +147,9 @@ public:
/**
* Call before a web view begins loading.
* Note: Any OpenGL related operations are forbidden in this callback.
*
* @param callback The web view that is about to load new content.
* @return YES if the web view should begin loading content; otherwise, NO .
* @return YES if the web view should begin loading content; otherwise, NO.
*/
void setOnShouldStartLoading(const std::function<bool(WebView *sender, const std::string &url)>& callback);

View File

@ -45,7 +45,7 @@
static const std::string s_defaultBaseUrl = "file:///android_asset/";
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;
if (baseUrl.empty())
@ -402,20 +402,21 @@ namespace cocos2d {
}
bool WebViewImpl::shouldStartLoading(const int viewTag, const std::string &url) {
bool allowLoad = true;
auto it = s_WebViewImpls.find(viewTag);
if (it != s_WebViewImpls.end()) {
auto webView = s_WebViewImpls[viewTag]->_webView;
auto webView = it->second->_webView;
if (webView->_onShouldStartLoading) {
return webView->_onShouldStartLoading(webView, url);
allowLoad = webView->_onShouldStartLoading(webView, url);
}
}
return true;
return allowLoad;
}
void WebViewImpl::didFinishLoading(const int viewTag, const std::string &url){
auto it = s_WebViewImpls.find(viewTag);
if (it != s_WebViewImpls.end()) {
auto webView = s_WebViewImpls[viewTag]->_webView;
auto webView = it->second->_webView;
if (webView->_onDidFinishLoading) {
webView->_onDidFinishLoading(webView, url);
}
@ -425,7 +426,7 @@ namespace cocos2d {
void WebViewImpl::didFailLoading(const int viewTag, const std::string &url){
auto it = s_WebViewImpls.find(viewTag);
if (it != s_WebViewImpls.end()) {
auto webView = s_WebViewImpls[viewTag]->_webView;
auto webView = it->second->_webView;
if (webView->_onDidFailLoading) {
webView->_onDidFailLoading(webView, url);
}
@ -435,7 +436,7 @@ namespace cocos2d {
void WebViewImpl::onJsCallback(const int viewTag, const std::string &message){
auto it = s_WebViewImpls.find(viewTag);
if (it != s_WebViewImpls.end()) {
auto webView = s_WebViewImpls[viewTag]->_webView;
auto webView = it->second->_webView;
if (webView->_onJSCallback) {
webView->_onJSCallback(webView, message);
}