tags:

views:

75

answers:

1

Hi,

I have two webviews and to cut out the common functionality from both the webviews I created a super class with all methods in the super class and use it in the two webviews.

Once when I create the object and set the variables from the 1st webview, the WebView displays properly and when I press the 'BACK' button and go to the 2nd WebView I get the folling exception.

Any help?

First WebView Code

public class firstWebView extends Activity {

    private static final String LOG_TAG = "FirstWebView";
    public static final int VIDEO_PLAY = 0;
    private WebView mWebView;
    private NicuWebView _nicuWebView;
    private static final String URL = mainMenuActivity.urlSelected+"todo.html";    

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.webview);
        getWindow().setFeatureInt(Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON);
        mWebView = (WebView) findViewById(R.id.webview);
        _nicuWebView = NicuWebView.getNicuWebView(mWebView);
//      mWebView.setWebChromeClient(new MyWebChromeClient());
        final Activity activity = this;
        NicuWebView.setContext(activity);
        setProgressBarVisibility(true);
        int count = (int) _nicuWebView.loadUrl(URL);
        Toast.makeText(this, "Count = "+count, Toast.LENGTH_SHORT).show();
    }

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
//          startActivity(new Intent(getApplication(), mainMenuActivity.class));
            mWebView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    } 

Code for Second is similar to the first one but the URL points to a different html page.

E/AndroidRuntime( 7913): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@447d2a98 is not valid; is your activity running?
E/AndroidRuntime( 7913):        at android.view.ViewRoot.setView(ViewRoot.java:468)
E/AndroidRuntime( 7913):        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
E/AndroidRuntime( 7913):        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime( 7913):        at android.view.Window$LocalWindowManager.addView(Window.java:424)
E/AndroidRuntime( 7913):        at android.app.Dialog.show(Dialog.java:239)
E/AndroidRuntime( 7913):        at android.app.AlertDialog$Builder.show(AlertDialog.java:802)
E/AndroidRuntime( 7913):        at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:483)
E/AndroidRuntime( 7913):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 7913):        at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 7913):        at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime( 7913):        at java.lang.reflect.Method.invokeNative(NativeMethod)
E/AndroidRuntime( 7913):        at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 7913):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime( 7913):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime( 7913):        at dalvik.system.NativeStart.main(Native Method)

Code for NicuWebView is

public class NicuWebView {
private static NicuWebView _nicuWebView;
private static WebView _webView;
private static HashMap<String,Long> _urls;
private static Context contextName;
private static final int VIDEO_PLAY = 0;

private NicuWebView(WebView myWebView) {

    _urls = new HashMap<String,Long>(10);
    _webView = myWebView;
    _webView.setWebViewClient(new NicuWebViewClient());
    _webView.getSettings().setJavaScriptEnabled(true);
    _webView.clearCache(true);

    WebSettings webSettings = _webView.getSettings();
    webSettings.setSavePassword(true);
    webSettings.setSaveFormData(true);
    webSettings.setJavaScriptEnabled(true);
    webSettings.setSupportZoom(true);

    _webView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
    _webView.clearCache(true);
    _webView.setWebViewClient(new WebViewClient() {
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        Toast.makeText(contextName, "Super Class TOAST message", Toast.LENGTH_LONG).show();
    }

    @Override  
     public void onPageFinished(WebView view, String url)  
     {  
         _webView.loadUrl("javascript:(function () { " +
                   "setVariable("+mainMenuActivity.numberSelected+");" +
                 "})()");
     }  
    });

    _webView.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView view, int progress) {
          // Activities and WebViews measure progress with different scales.
          // The progress meter will automatically disappear when we reach 100%
            ((Activity) contextName).setProgress(progress * 1000);
        }
    });

    _webView.setWebViewClient(new WebViewClient() {
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
          Toast.makeText(contextName, "Oh no! " + description, Toast.LENGTH_SHORT).show();
        }

     @Override  
     public void onPageFinished(WebView view, String url)  {  
         _webView.loadUrl("javascript:(function () { " +
                   "setVariable("+mainMenuActivity.numberSelected+");" +
                 "})()");
     }  
  });
}

    // allow clicking on link to remain in app instead of launching android browser
    private class NicuWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }   

public static NicuWebView getNicuWebView(WebView myWebView){
    if (_nicuWebView == null) _nicuWebView = new NicuWebView(myWebView);
    return _nicuWebView;

}

 // loads the requested URL and maintains a 'history' of pages visited.
// returns number of times page was loaded.
 public long loadUrl(String url) {
     long count = incrementCounter(url);
     _webView.loadUrl(url); 
     return count;
 }

 //helper to 
 private static long incrementCounter(String url){
     if (url != null) {
     if (_urls.get(url)==null) _urls.put(url,new Long(0));
     long count = _urls.put(url,_urls.get(url) +1L);
     return count;
     }
     else {
         Toast.makeText(contextName, "Null URL", Toast.LENGTH_SHORT).show();
         return 0;
     }
 }

 /// return the number of times the given URL has been visited
 public long getUrlVisitCount(String url) {
     if (_urls.get(url)==null) return 0L;
     return _urls.get(url);
 }

 //returns to the previous URL, returns that URL
 public String goBack(){
     if (_webView.canGoBack()) _webView.goBack();
     String url = _webView.getUrl();
     incrementCounter(url);
     return url;
 }

 //returns to next forward URL, returns that URL
 public String goForward(){
    if (_webView.canGoForward()) _webView.goForward();
    String url = _webView.getUrl();
    incrementCounter(url);
    return url;     
 }

 public static boolean setContext(Context context) {
     contextName = context;
     return true;
 }

 public Context getContext(){
     if (contextName == null) return null;
     return contextName;
 }


    final class DemoJavaScriptInterface {


        public void setPlayVideo(String option) {
            Toast.makeText(contextName, "Playing Video = "+option, Toast.LENGTH_SHORT).show();
            Intent intent = new Intent ( contextName,  playVideo.class );
            ((Activity) contextName).startActivityForResult(intent, VIDEO_PLAY);

        }
    }   

    public boolean canGoBack() {
        return _webView.canGoBack();
    }

}

A: 

The problem is that the dialog need to have the "base" context of your activity, not necessarily the one you're launching it from.

Here's one solution which often works

Activity a = this;
while(a.getParent() != null) {
    a = a.getParent();
}
_nicuWebView.setContext(a);

One way to see what's going on with this is to modify that example as follows

Activity a = this;
while(a.getParent() != null) {
    Log.i("ActivityTree",a.getClass().getSimpleName());
    a = a.getParent();
}
_nicuWebView.setContext(a);

adb will then show you the hierarchy of activities which you're inside.

jwriteclub