web-dev-qa-db-ja.com

Android:インターセプトAJAX WebViewからの呼び出し

WebViewで実行されているHTML/javascriptアプリケーションに、AJAXコードで処理されるJava呼び出しを実行させたい。
理想的なのは、呼び出しをインターセプトし(簡単、shouldOverrideUrlLoading()を使用するだけ)、データを「返す」ことです。
しかし、loadUrl()を使用してWebView関数を呼び出す以外に、javascriptへの応答を「返す」方法が見つかりません。
HTML/javascriptアプリは私が制御できないドロップインアプリケーションであるため、これは機能しません。 HTML/javascriptアプリに関する限り、AJAX呼び出しを実行し、データを受信します。

これについて何か考えはありますか?

14
Erik

結局、私はとにかく質問で説明されている方法を使用しました。

_foo://bar/get/1?callback=foobar_のような特定のリクエストをインターセプトしてから、URLを解析し、実際のデータを使用してjavascriptコールバック関数を呼び出しました。
コールバック関数はURLのクエリ部分で定義されているため、上記の例では次のようになります。foobar();

その関数の呼び出しは簡単でした。次を使用するだけです:yourWebView.loadUrl("javascript:foobar('somedata')");

0
Erik

皆さんに朗報です。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 も確認してください。

お役に立てれば。

32
Nappy

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();
    }
}

そして、これがAjaxHandlerActivityでどのように使用されるかです。

    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
                            "});");

            });
    }
}

主なアイデアは ここ から取られ、いくつかの調整が加えられています。
回答を提出するのは少し遅いですが、これが他の人にも役立つことを願っています!

11
S1LENT WARRIOR