I am trying to inject a javascript function into my webview running a server url "www.myserver.com". However, I am unable to do so. I tried several ways but didn't succeed. I tried setting up js alerts, which do not pop up upon reading the js file. I am not sure what I am doing wrong. Here's my code so far: my js file "page.js":
(function() {
**alert("this is a test alert");**
if (window.page) {
return; // page has been loaded from somewhere, not to redefine it again
}
function Response(xhr) {
this.xhr = xhr;
this.status = xhr.status;
}
Response.prototype.getHeader = function(header) {
return this.xhr.getResponseHeader(header);
};
Response.prototype.getBody = function() {
return this.xhr.responseText;
};
function ajax(url, callback) {
//TODO support PUT method
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onerror = function(e) {
callback.onerror(e);
};
xhr.onreadystatechange = function(event) {
if (this.readyState != this.DONE || this.status == 0) {
return;
}
if (this.status != 200) {
var response = new Response(xhr);
callback.onfail(response);
return;
}
callback.onsuccess(this.responseText);
};
xhr.send();
};
var rpc = {
type: ["SMALL", "LARGE"],
exec: function(call, type) {// "call" conform to JSON-RPC 2.0
//TODO differentiate POST/GET based on rpc.type.SMALL/LARGE
var param = encodeURIComponent(JSON.stringify(call));
ajax("?_$b=" + param, {
onerror: function(e) {
//TODO use logging
alert("Error:"+e.toString());
},
onfail: function(response) {
//TODO use logging
alert("Failed:"+response.getBoby());
},
onsuccess: function(text) {
//TODO use logging
alert("page success:"+text);
},
});
}
};
var _$b = window.page = {
version: "0.1"
};
_$b.has = function(feature) {
// TODO support nested objects, e.g.: "cache.get"
return _$b[feature];
};
_$b.notify = function(id, data) {
// TODO invoke the function from native and send web event
// var event = document.createEvent('Event');
// event.initEvent(id, true, true);
// document.dispatchEvent(event);
alert("id:" + id + ";data:" + data);
};
_$b.navigate = function(url, title) {
rpc.exec(// JSON-RPC 2.0
{method: "navigate", params: {
"url": url,
"title": title
}}, rpc.type.SMALL);
};
_$b.cache = {};
_$b.cache.get = function(id) {
rpc.exec(
{method: "cache.get", params: {
"id": id,
}}, rpc.type.SMALL);
};
_$b.cache.put = function(id, obj, ts, ttl) {
rpc.exec(
{method: "cache.put", params: {
"id": id,
"obj": obj,
"ts": ts,
"ttl": ttl,
}}, rpc.type.LARGE);
};
_$b.cache.has = function(id) {
rpc.exec(
{method: "cache.has", params: {
"id": id,
}}, rpc.type.SMALL);
};
})();
Here's my webview code:
@Override
public void onPageFinished(WebView view, String url) {
String javascript = "";
try{
AssetManager manager = view.getContext().getAssets();
InputStream is = manager.open("page.js");
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while (( line = br.readLine()) != null) {
javascript += line;
}
is.close();
}
catch(Exception e){}
view.loadUrl("javascript:" + javascript);
}
webview.setWebChromeClient(new WebChromeClient() {});
webview.loadUrl(url);
Any ideas how to get the alerts to popup? Note: When I remove all the functions in js and just keep the alerts, the alert works,but after I re-add the necessary js functions the alert doesnt work anymore. Any idea what might be stopping it from injecting into the js as expected?
Consider this code. This is simple html & javascript code that models after your page.js
<html>
<script type="text/javascript">
(function() { alert('inside function'); })
alert('ok');
</script>
</html>
Executing this, you can derive that the alert inside the function is not execute at the start unless you specifically invoke it.
To run your function with a click: (Try this)
<html>
<input type="button" onclick="run()" value="Start" />
<script type="text/javascript">
var run = (function() { alert('inside function'); })
alert('ok');
</script>
</html>
To run your function [Self Run] (Try this)
<html>
<script type="text/javascript">
var run = (function() { alert('inside function'); })
alert('ok');
//you need to execute your function that you have named
run();
</script>
</html>