WebView
で実行されているHTML/javascript
アプリケーションに、AJAX
コードで処理されるJava
呼び出しを実行させたい。
理想的なのは、呼び出しをインターセプトし(簡単、shouldOverrideUrlLoading()
を使用するだけ)、データを「返す」ことです。
しかし、loadUrl()
を使用してWebView
関数を呼び出す以外に、javascript
への応答を「返す」方法が見つかりません。HTML/javascript
アプリは私が制御できないドロップインアプリケーションであるため、これは機能しません。 HTML/javascriptアプリに関する限り、AJAX
呼び出しを実行し、データを受信します。
これについて何か考えはありますか?
結局、私はとにかく質問で説明されている方法を使用しました。
_foo://bar/get/1?callback=foobar
_のような特定のリクエストをインターセプトしてから、URL
を解析し、実際のデータを使用してjavascriptコールバック関数を呼び出しました。
コールバック関数はURL
のクエリ部分で定義されているため、上記の例では次のようになります。foobar();
その関数の呼び出しは簡単でした。次を使用するだけです:yourWebView.loadUrl("javascript:foobar('somedata')");
皆さんに朗報です。APIレベル11では、shouldInterceptRequest
メソッドをWebViewClient
クラスに入れています。また、WebView
トリガー内のアプリケーションの要求に対しても起動します。次のようにオーバーライドできます。
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url)
{
if (magicallyMatch(url))
return new WebResourceResponse("application/json", "utf-8", magicallyGetSomeInputStream());
return null;
}
Androidリファレンス から:
public WebResourceResponseshouldInterceptRequest(WebViewビュー、文字列URL)
以来:APIレベル11
ホストアプリケーションにリソース要求を通知し、アプリケーションがデータを返すことを許可します。戻り値がnullの場合、
WebView
は通常どおりリソースをロードし続けます。それ以外の場合は、戻り応答とデータが使用されます。注:このメソッドはネットワークスレッドによって呼び出されるため、クライアントはプライベートデータにアクセスするときに注意を払う必要があります。パラメータ
view
リソースを要求しているWebView
。
url
リソースの生のURL。返品
応答情報を含む
WebResourceResponse
、またはWebView
がリソース自体をロードする必要がある場合はnull。
WebResourceResponse も確認してください。
お役に立てれば。
JavascriptInterface を使用して、次の方法でAJAX呼び出しとJQueryメソッドajaxStart
およびajaxComplete
をインターセプトできます。
// our JavascriptInterface
public class AjaxHandler {
private static final String TAG = "AjaxHandler";
private final Context context;
public AjaxHandler(Context context) {
this.context = context;
}
public void ajaxBegin() {
Log.w(TAG, "AJAX Begin");
Toast.makeText(context, "AJAX Begin", Toast.LENGTH_SHORT).show();
}
public void ajaxDone() {
Log.w(TAG, "AJAX Done");
Toast.makeText(context, "AJAX Done", Toast.LENGTH_SHORT).show();
}
}
そして、これがAjaxHandler
がActivity
でどのように使用されるかです。
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private WebView webView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// get web view
webView = (WebView) findViewById(R.id.web);
// configure web view
final WebSettings webSettings = webView.getSettings();
webSettings.setBuiltInZoomControls(true);
webSettings.setJavaScriptEnabled(true);
webView.loadUrl("http://foo.com");
// add javascript interface
webView.addJavascriptInterface(new AjaxHandler(this), "ajaxHandler");
// override onPageFinished method of WebViewClient to handle AJAX calls
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.loadUrl("javascript:$(document).ajaxStart(function (event, request, settings) { " +
"ajaxHandler.ajaxBegin(); " + // Event called when an AJAX call begins
"});");
view.loadUrl("javascript:$(document).ajaxComplete(function (event, request, settings) { " +
"ajaxHandler.ajaxDone(); " + // Event called when an AJAX call ends
"});");
});
}
}
主なアイデアは ここ から取られ、いくつかの調整が加えられています。
回答を提出するのは少し遅いですが、これが他の人にも役立つことを願っています!