Если я правильно понимаю, вы хотите получить некоторую информацию из компонента HTML на нативную сторону.
Согласно этому ответу невозможно передать произвольные объекты в Java, но, по крайней мере, вы можете передать HTML-код узла, по которому щелкнули мышью, и затем выполнить его собственный анализ.
Этот код, основанный на вашем коде, делает именно это.
MainActivity.java: Я думаю, это довольно очевидно.Единственное, что я отличал от вас - это получение кода Javascript из отдельного файла, чтобы его было проще поддерживать.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WebView myWebView = findViewById(R.id.webView);
final WebSettings settings = myWebView.getSettings();
settings.setJavaScriptEnabled(true);
myWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
final String injectedJs = "javascript:(function(){" + injectedJs() + "})()";
myWebView.loadUrl(injectedJs);
}
});
myWebView.addJavascriptInterface(
new Object() {
@JavascriptInterface
public void onClick(String param) {
Toast.makeText(MainActivity.this, param, Toast.LENGTH_LONG).show();
}
},
"appHost"
);
myWebView.loadUrl("https://google.com");
}
// Javascript code to inject on the Web page
private String injectedJs() {
BufferedReader stream = null;
StringBuilder jsBuilder = new StringBuilder();
try {
stream = new BufferedReader(new InputStreamReader(getAssets().open("js.js")));
String line;
while ((line = stream.readLine()) != null) {
jsBuilder.append(line.trim());
}
return jsBuilder.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "";
}
}
js.js: Основой этой части является ваш код.Имейте в виду, что, поскольку injectedJs()
удаляет все маркеры строк, каждый оператор должен завершаться, включая комментарии, следовательно, /*...*/
вместо //
/* Keep track of the last clicked element so we can un-highlight it */
var lastSelectedItem = null;
var showHighlighted = function(/* HTML element */view, /*boolean */highlighted) {
if (view) {
view.style.cssText = highlighted? 'border-color: black;border-style: dashed;' : '';
}
};
/* This new method, _addEventListener and _eventClick are the same as yours */
Object.prototype.each = function (fn, bind) {
for (var i = 0; i < this.length; i++) {
if (i in this) {
fn.call(bind, this[i], i, this);
}
}
};
var _addListener = document.addEventListener || document.attachEvent,
_eventClick = window.addEventListener ? 'click' : 'onclick';
/* I changed the element selection criteria, but you can change it back easily.
I am adding event listeners all the leaf elements in the DOM. */
var elements = document.body.getElementsByTagName('*');
elements.each(function (el) {
if (el.children.length == 0) {
_addListener.call(el, _eventClick, function () {
/* First, deal with the previously selected item*/
showHighlighted(lastSelectedItem, false);
if (lastSelectedItem !== null) {
appHost.onClick(lastSelectedItem.outerHTML);
}
/* Update the selected item reference */
lastSelectedItem = el;
/* Finally, deal with the previously selected item*/
showHighlighted(lastSelectedItem, true);
appHost.onClick(el.outerHTML);
}, false);
}
});