From 473859a6f9cc7faa2d026272cfa8e3aedd268372 Mon Sep 17 00:00:00 2001 From: Allen Yeung Date: Wed, 26 Oct 2011 16:15:12 -0700 Subject: [PATCH 1/3] TIMOB-4357: Webview fatal exception / crash on re-open --- .../ti/modules/titanium/ui/WebViewProxy.java | 10 --- .../ui/widget/webview/TiWebViewClient.java | 67 +++++++++++-------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/android/modules/ui/src/ti/modules/titanium/ui/WebViewProxy.java b/android/modules/ui/src/ti/modules/titanium/ui/WebViewProxy.java index 6ce5b41c6a5..51cddb1c7f2 100644 --- a/android/modules/ui/src/ti/modules/titanium/ui/WebViewProxy.java +++ b/android/modules/ui/src/ti/modules/titanium/ui/WebViewProxy.java @@ -200,16 +200,6 @@ public boolean getEnableZoomControls() return enabled; } - @Override - public void releaseViews() - { - // See Lighthouse #1936 - we can't allow the releasing - // of the view because Android's WebViewCoreThread seems - // to refer back to it in GC and freak out (crash the app) - // if it's not there. - // So we're just overriding and not calling super. - } - public void clearBasicAuthentication() { fusername = null; diff --git a/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebViewClient.java b/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebViewClient.java index 84c6d2eb8f7..bff69e08615 100644 --- a/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebViewClient.java +++ b/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebViewClient.java @@ -27,31 +27,40 @@ public class TiWebViewClient extends WebViewClient private static final boolean DBG = TiConfig.LOGD; private TiUIWebView webView; private TiWebViewBinding binding; - + private static final String DEFAULT_PAGE_FINISH_URL = "file:///android_asset/Resources/"; private String username, password; - public TiWebViewClient(TiUIWebView tiWebView, WebView webView) { + public TiWebViewClient(TiUIWebView tiWebView, WebView webView) + { super(); this.webView = tiWebView; binding = new TiWebViewBinding(tiWebView.getProxy().getTiContext(), webView); } @Override - public void onPageFinished(WebView view, String url) { + public void onPageFinished(WebView view, String url) + { super.onPageFinished(view, url); - webView.changeProxyUrl(url); + if (DEFAULT_PAGE_FINISH_URL.equals(url)) { + url = ""; + webView.getProxy().getProperties().remove("url"); + } else { + webView.changeProxyUrl(url); + } KrollDict data = new KrollDict(); data.put("url", url); webView.getProxy().fireEvent("load", data); } - public TiWebViewBinding getBinding() { + public TiWebViewBinding getBinding() + { return binding; } @Override - public void onPageStarted(WebView view, String url, Bitmap favicon) { + public void onPageStarted(WebView view, String url, Bitmap favicon) + { super.onPageStarted(view, url, favicon); KrollDict data = new KrollDict(); data.put("url", url); @@ -63,13 +72,14 @@ public void onReceivedError(WebView view, int errorCode, String description, Str { super.onReceivedError(view, errorCode, description, failingUrl); - //TODO report this to the user - String text = "Javascript Error("+errorCode+"): " + description; + // TODO report this to the user + String text = "Javascript Error(" + errorCode + "): " + description; Log.e(LCAT, "Received on error" + text); } @Override - public boolean shouldOverrideUrlLoading(final WebView view, String url) { + public boolean shouldOverrideUrlLoading(final WebView view, String url) + { if (DBG) { Log.d(LCAT, "url=" + url); } @@ -78,23 +88,24 @@ public boolean shouldOverrideUrlLoading(final WebView view, String url) { // go through the proxy to ensure we're on the UI thread webView.getProxy().setProperty("url", url, true); return true; - } else if(url.startsWith(WebView.SCHEME_TEL)) { + } else if (url.startsWith(WebView.SCHEME_TEL)) { Log.i(LCAT, "Launching dialer for " + url); Intent dialer = Intent.createChooser(new Intent(Intent.ACTION_DIAL, Uri.parse(url)), "Choose Dialer"); webView.getProxy().getTiContext().getActivity().startActivity(dialer); - return true; + return true; } else if (url.startsWith(WebView.SCHEME_MAILTO)) { Log.i(LCAT, "Launching mailer for " + url); Intent mailer = Intent.createChooser(new Intent(Intent.ACTION_SENDTO, Uri.parse(url)), "Send Message"); webView.getProxy().getTiContext().getActivity().startActivity(mailer); - return true; + return true; } else if (url.startsWith(WebView.SCHEME_GEO)) { Log.i(LCAT, "Launching app for " + url); - /*geo:latitude,longitude - geo:latitude,longitude?z=zoom - geo:0,0?q=my+street+address - geo:0,0?q=business+near+city - */ + /* + * geo:latitude,longitude + * geo:latitude,longitude?z=zoom + * geo:0,0?q=my+street+address + * geo:0,0?q=business+near+city + */ Intent geoviewer = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse(url)), "Choose Viewer"); webView.getProxy().getTiContext().getActivity().startActivity(geoviewer); return true; @@ -104,37 +115,39 @@ public boolean shouldOverrideUrlLoading(final WebView view, String url) { if (mimeType != null) { return shouldHandleMimeType(mimeType, url); } - + if (DBG) { Log.e(LCAT, "NEED to Handle " + url); } return super.shouldOverrideUrlLoading(view, url); } } - - private boolean shouldHandleMimeType(String mimeType, String url) { + + private boolean shouldHandleMimeType(String mimeType, String url) + { if (mimeType.startsWith("video/")) { Intent intent = new Intent(); intent.setClass(webView.getProxy().getContext(), TiVideoActivity.class); intent.putExtra("contentURL", url); intent.putExtra("play", true); webView.getProxy().getTiContext().getActivity().startActivity(intent); - + return true; } return false; } - + @Override - public void onReceivedHttpAuthRequest(WebView view, - HttpAuthHandler handler, String host, String realm) { - + public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) + { + if (this.username != null && this.password != null) { handler.proceed(this.username, this.password); } } - - public void setBasicAuthentication(String username, String password) { + + public void setBasicAuthentication(String username, String password) + { this.username = username; this.password = password; } From cb3479f13ccfc694ac7e9bb039e6d7f5b75c1699 Mon Sep 17 00:00:00 2001 From: Allen Yeung Date: Mon, 31 Oct 2011 14:23:44 -0700 Subject: [PATCH 2/3] TIMOB-4357:Moved check for default path to TiUIWebView --- .../titanium/ui/widget/webview/TiUIWebView.java | 11 +++++++---- .../titanium/ui/widget/webview/TiWebViewClient.java | 8 +------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiUIWebView.java b/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiUIWebView.java index d528d33a889..65166decc9a 100644 --- a/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiUIWebView.java +++ b/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiUIWebView.java @@ -57,6 +57,8 @@ public class TiUIWebView extends TiUIView { public static final int PLUGIN_STATE_ON = 1; public static final int PLUGIN_STATE_ON_DEMAND = 2; + private static final String DEFAULT_PAGE_FINISH_URL = "file:///android_asset/Resources/"; + private class TiWebView extends WebView { public TiWebViewClient client; public TiWebView(Context context) { @@ -170,14 +172,14 @@ public void processProperties(KrollDict d) { settings.setLoadWithOverviewMode(TiConvert.toBoolean(d, TiC.PROPERTY_SCALES_PAGE_TO_FIT)); } - if (d.containsKey(TiC.PROPERTY_URL)) { + if (d.containsKey(TiC.PROPERTY_URL) && !DEFAULT_PAGE_FINISH_URL.equals(TiConvert.toString(d, TiC.PROPERTY_URL))) { setUrl(TiConvert.toString(d, TiC.PROPERTY_URL)); } else if (d.containsKey(TiC.PROPERTY_HTML)) { setHtml(TiConvert.toString(d, TiC.PROPERTY_HTML)); } else if (d.containsKey(TiC.PROPERTY_DATA)) { Object value = d.get(TiC.PROPERTY_DATA); if (value instanceof TiBlob) { - setData((TiBlob)value); + setData((TiBlob) value); } } @@ -199,13 +201,14 @@ public void processProperties(KrollDict d) { @Override public void propertyChanged(String key, Object oldValue, Object newValue, KrollProxy proxy) { - if (TiC.PROPERTY_URL.equals(key) && !changingUrl) { + if (TiC.PROPERTY_URL.equals(key) && !changingUrl + && !DEFAULT_PAGE_FINISH_URL.equals(TiConvert.toString(newValue))) { setUrl(TiConvert.toString(newValue)); } else if (TiC.PROPERTY_HTML.equals(key)) { setHtml(TiConvert.toString(newValue)); } else if (TiC.PROPERTY_DATA.equals(key)) { if (newValue instanceof TiBlob) { - setData((TiBlob)newValue); + setData((TiBlob) newValue); } } else if (TiC.PROPERTY_SCALES_PAGE_TO_FIT.equals(key)) { WebSettings settings = getWebView().getSettings(); diff --git a/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebViewClient.java b/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebViewClient.java index bff69e08615..3d3a45d0dcb 100644 --- a/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebViewClient.java +++ b/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebViewClient.java @@ -27,7 +27,6 @@ public class TiWebViewClient extends WebViewClient private static final boolean DBG = TiConfig.LOGD; private TiUIWebView webView; private TiWebViewBinding binding; - private static final String DEFAULT_PAGE_FINISH_URL = "file:///android_asset/Resources/"; private String username, password; @@ -42,12 +41,7 @@ public TiWebViewClient(TiUIWebView tiWebView, WebView webView) public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); - if (DEFAULT_PAGE_FINISH_URL.equals(url)) { - url = ""; - webView.getProxy().getProperties().remove("url"); - } else { - webView.changeProxyUrl(url); - } + webView.changeProxyUrl(url); KrollDict data = new KrollDict(); data.put("url", url); webView.getProxy().fireEvent("load", data); From d5c00a35778a13367ab1800244e12cb07681ada3 Mon Sep 17 00:00:00 2001 From: Allen Yeung Date: Wed, 9 Nov 2011 17:13:39 -0800 Subject: [PATCH 3/3] Remove unused file --- .../ti/modules/titanium/ui/WebViewProxy.java | 219 ------------------ 1 file changed, 219 deletions(-) delete mode 100644 android/modules/ui/src/ti/modules/titanium/ui/WebViewProxy.java diff --git a/android/modules/ui/src/ti/modules/titanium/ui/WebViewProxy.java b/android/modules/ui/src/ti/modules/titanium/ui/WebViewProxy.java deleted file mode 100644 index 51cddb1c7f2..00000000000 --- a/android/modules/ui/src/ti/modules/titanium/ui/WebViewProxy.java +++ /dev/null @@ -1,219 +0,0 @@ -/** - * Appcelerator Titanium Mobile - * Copyright (c) 2009-2011 by Appcelerator, Inc. All Rights Reserved. - * Licensed under the terms of the Apache Public License - * Please see the LICENSE included with this distribution for details. - */ -package ti.modules.titanium.ui; - -import org.appcelerator.kroll.annotations.Kroll; -import org.appcelerator.titanium.TiC; -import org.appcelerator.titanium.TiContext; -import org.appcelerator.titanium.util.TiConvert; -import org.appcelerator.titanium.view.TiUIView; - -import ti.modules.titanium.ui.widget.webview.TiUIWebView; -import android.app.Activity; -import android.os.Handler; -import android.os.Message; - -@Kroll.proxy(creatableInModule=UIModule.class) -@Kroll.dynamicApis(properties = { - TiC.PROPERTY_DATA, - TiC.PROPERTY_HTML, - TiC.PROPERTY_SCALES_PAGE_TO_FIT, - TiC.PROPERTY_URL -}) -public class WebViewProxy extends ViewProxy - implements Handler.Callback -{ - - private static final int MSG_FIRST_ID = ViewProxy.MSG_LAST_ID + 1; - - private static final int MSG_GO_BACK = MSG_FIRST_ID + 101; - private static final int MSG_GO_FORWARD = MSG_FIRST_ID + 102; - private static final int MSG_RELOAD = MSG_FIRST_ID + 103; - private static final int MSG_STOP_LOADING = MSG_FIRST_ID + 104; - - protected static final int MSG_LAST_ID = MSG_FIRST_ID + 999; - - private static String fusername; - private static String fpassword; - - public WebViewProxy(TiContext context) - { - super(context); - } - - @Override - public TiUIView createView(Activity activity) - { - TiUIWebView webView = new TiUIWebView(this); - webView.focus(); - return webView; - } - - public TiUIWebView getWebView() - { - return (TiUIWebView)getView(getTiContext().getActivity()); - } - - @Kroll.method - public Object evalJS(String code) - { - return getWebView().getJSValue(code); - } - - @Override - public boolean handleMessage(Message msg) - { - if (peekView() != null) { - switch (msg.what) { - case MSG_GO_BACK: - getWebView().goBack(); - return true; - case MSG_GO_FORWARD: - getWebView().goForward(); - return true; - case MSG_RELOAD: - getWebView().reload(); - return true; - case MSG_STOP_LOADING: - getWebView().stopLoading(); - return true; - } - } - return super.handleMessage(msg); - } - - @Kroll.method - public void setBasicAuthentication(String username, String password) - { - if (peekView() == null) { - // if the view is null, we cache the username/password - fusername = username; - fpassword = password; - return; - } - clearBasicAuthentication(); - getWebView().setBasicAuthentication(username, password); - } - - @Kroll.method - public boolean canGoBack() - { - if (peekView() != null) { - return getWebView().canGoBack(); - } - return false; - } - - @Kroll.method - public boolean canGoForward() - { - if (peekView() != null) { - return getWebView().canGoForward(); - } - return false; - } - - @Kroll.method - public void goBack() - { - getUIHandler().sendEmptyMessage(MSG_GO_BACK); - } - - @Kroll.method - public void goForward() - { - getUIHandler().sendEmptyMessage(MSG_GO_FORWARD); - } - - @Kroll.method - public void reload() - { - getUIHandler().sendEmptyMessage(MSG_RELOAD); - } - - @Kroll.method - public void stopLoading() - { - getUIHandler().sendEmptyMessage(MSG_STOP_LOADING); - } - - @Kroll.method @Kroll.getProperty - public int getPluginState() - { - int pluginState = TiUIWebView.PLUGIN_STATE_OFF; - - if (hasProperty(TiC.PROPERTY_PLUGIN_STATE)) { - pluginState = TiConvert.toInt(getProperty(TiC.PROPERTY_PLUGIN_STATE)); - } - - return pluginState; - } - - @Kroll.method @Kroll.setProperty - public void setPluginState(int pluginState) - { - switch(pluginState) { - case TiUIWebView.PLUGIN_STATE_OFF : - case TiUIWebView.PLUGIN_STATE_ON : - case TiUIWebView.PLUGIN_STATE_ON_DEMAND : - setProperty(TiC.PROPERTY_PLUGIN_STATE, pluginState, true); - break; - default: - setProperty(TiC.PROPERTY_PLUGIN_STATE, TiUIWebView.PLUGIN_STATE_OFF, true); - } - } - - @Kroll.method - public void pause() - { - if (peekView() != null) { - getWebView().pauseWebView(); - } - } - - @Kroll.method - public void resume() - { - if (peekView() != null) { - getWebView().resumeWebView(); - } - } - - @Kroll.method(runOnUiThread=true) @Kroll.setProperty(runOnUiThread=true) - public void setEnableZoomControls(boolean enabled) - { - setProperty(TiC.PROPERTY_ENABLE_ZOOM_CONTROLS, enabled, true); - } - - @Kroll.method @Kroll.getProperty - public boolean getEnableZoomControls() - { - boolean enabled = true; - - if(hasProperty(TiC.PROPERTY_ENABLE_ZOOM_CONTROLS)) { - enabled = TiConvert.toBoolean(getProperty(TiC.PROPERTY_ENABLE_ZOOM_CONTROLS)); - } - return enabled; - } - - public void clearBasicAuthentication() - { - fusername = null; - fpassword = null; - } - - public String getBasicAuthenticationUserName() - { - return fusername; - } - - public String getBasicAuthenticationPassword() - { - return fpassword; - } - -}