title: Android webview doesn't execute javascript from script src
body: <h1>The Problem</h1>
  
  <p>The webview doesn't actually execute the scripts loaded through src from a remote location</p>
  
  <h1>Checked and double checked</h1>
  
  <ul>
  <li><p>The permission: <code>&lt;uses-permission android:name="android.permission.INTERNET" /&gt;</code></p></li>
  <li><p>That the file <code>http://localhost/android/test.js</code> exists</p></li>
  <li><p>That it called <code>view.getSettings().setJavaScriptEnabled(true);</code> before loading an URL</p></li>
  </ul>
  
  <h1>The code</h1>
  
  <p>Given a <code>WebView view</code> and a <code>Context context</code></p>
  
  <h2>Building a document</h2>
  
  <p>It will need cookies so need to dynamically build it. file:// urls don't allow for cookies. Either way, this 'should' work just fine.</p>
  
  <pre><code>String html =
          "&lt;html&gt;\n" +
          "&lt;head&gt;\n" +
          "&lt;/head&gt;\n" +
          "&lt;body&gt;\n" +
          "&lt;script src=\"http://localhost/android/test.js\"  type=\"text/javascript\"&gt;&lt;/script&gt;\n" +
          "&lt;/body&gt;\n" +
          "&lt;/html&gt;";
  String mime = "text/html";
  String encoding = "utf-8";
  </code></pre>
  
  <h2>Cookies enabled</h2>
  
  <p>Simple functions to make sure the device retains cookies. </p>
  
  <pre><code>CookieSyncManager.createInstance(context);
  CookieSyncManager.getInstance().sync();
  </code></pre>
  
  <h2>Creating a chrome client for logging</h2>
  
  <p>Logging all messages [twice] and when the page is done loading execute a function. This actually works well. Adding more [remote] script tags delays the execution.</p>
  
  <pre><code>WebChromeClient client = new WebChromeClient ( ) {
          @Override
          public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
              Log.e( "JSINTERFACE", consoleMessage.message() );
              return super.onConsoleMessage(consoleMessage);
          }
  
          @Override
          public void onProgressChanged(WebView view, int newProgress) {
              super.onProgressChanged(view, newProgress);
              loadingFinished = ( newProgress == 100 );
              Log.d( "JSINTERFACE", "Progress is:" + newProgress );
              if ( loadingFinished ) {
                  Log.i( "JSINTERFACE", "Finished loading webclient" );
                  execute();
              }
          }
  
      };
  </code></pre>
  
  <h2>Loading the view</h2>
  
  <p>Attach the chrome client, enable javascript, add the interface and start loading!</p>
  
  <pre><code>view.setWebChromeClient( client );
  view.getSettings().setJavaScriptEnabled(true);
  view.addJavascriptInterface( new JSInterface(), "bridge" );
  view.loadDataWithBaseURL( "http://localhost/android/", html, mime, encoding, null );
  </code></pre>
  
  <h1>The Interface</h1>
  
  <p>The interface looks as follows</p>
  
  <pre><code>public class JSInterface{
  
      @JavascriptInterface
      public void result( int success, String message ) {
          Log.i( "JSINTERFACE", message );
          // TODO handler
      }
  }
  </code></pre>
  
  <p>I can actually test javascript AND the interface by calling     </p>
  
  <pre><code>view.loadUrl("javascript:bridge.result( 0, 'TESTING INTERFACE' );");
  </code></pre>
  
  <p>As long as this is postponed until after loading has completed (for example in the <code>execute function</code> this works fine. And the message is logged.</p>
  
  <h1>Inside the <code>test.js</code> script</h1>
  
  <p>A very simple script</p>
  
  <pre><code>console.log( 'test loaded' );
  var test = function() { console.log( 'test' ); bridge.result( 1, 'res' ); }
  </code></pre>
  
  <h1>Why doesn't it work?</h1>
  
  <ul>
  <li><p>I don't see the <code>test loaded</code> log, should be captured by the client</p></li>
  <li><p>When I call <code>view.loadUrl("javascript:console.log(test)</code> I get <code>test is not defined</code></p></li>
  </ul>