Android WebviewのpostUrlとloadUrlのロードページ


Android WebviewのpostUrlとloadUrlのロードページ 
         Androidのwebviewについて、使ったことがあるのはきっとよく知らないことはありません.ここで私はwebviewの基本的な使い方を言わないで、知りたいのはネット上で百余り行って、webviewの基本的な使い方を紹介することがたくさんあります.本稿では,主にプロジェクト中にwebviewを用いたpostUrlで遭遇したピットについて述べる.
        1、使用シーンは以下の通りです.
        Webviewは、H 5リンクをロードする場合、デフォルトではloadUrlを使用してロードされますが、キャッシュ属性(キャッシュ)を設定している場合は、表示されるH 5ページ内でクリックして別のページにジャンプした後、戻るキーを押すと、通常は前のページに戻ることができます.キャッシュ設定が行われているためです.ただし、postUrlを使用してロードする場合、設定したキャッシュプロパティが設定されている場合でも、別のページに移動した後、戻るキーを押すと、前のページはキャッシュされず、postUrlを再呼び出してロードします.このとき問題が来て、同じようにロードを行い、初めてのpostUrlは正常にロードでき、再ロードはロードに失敗し、コンテンツ表示がありません.面白いのではないでしょうか.なぜこのような状況になったのでしょうか.バッグをつかむことによって(私の別のブログを参照してください. Fiddlerが携帯電話端末のAPPインタフェースのデータをキャプチャ)すると、同じリンクがロードされているが、再ロードの要求属性が空で、ロードに失敗したことが分かった.
        2、解決方法:
       理由が見つかった以上、リクエスト属性が空で、解決策があるに違いないので、手動でリクエスト属性を設定し、再ロードします.どのように手動で設定するかは、まず要求されたすべての内容とパラメータを手に入れることができるに違いありません.Webviewを使ったことがある人は、setWebViewClientの方法をよく知っているに違いありません.このメソッドの内部にはshouldInterceptRequestメソッドがリクエストのすべての内容を取得できる.あまり言わないで、先にコードをつけてください. 
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        if(Build.VERSION.SDK_INT >= 21){
            if(!request.getMethod().equalsIgnoreCase("post")){
                return super.shouldInterceptRequest(view, request);
            }
        }
        DataOutputStream os = null;
        try {
            URL mUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod("POST");
            if(Build.VERSION.SDK_INT >= 21){
                Iterator headerKeys=request.getRequestHeaders().keySet().iterator();
                while(headerKeys.hasNext()){
                    String key=headerKeys.next();
                    connection.setRequestProperty(key,request.getRequestHeaders().get(key));
                }
            }
            connection.setRequestProperty("content-type","application/x-www-form-urlencoded");
            os = new DataOutputStream(connection.getOutputStream());

            os.write(EncodingUtils.getBytes(postData, "BASE64"));
            os.flush();
            return new WebResourceResponse("text/html", connection.getContentEncoding(), connection.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return super.shouldInterceptRequest(view, request);
    }
});
        webView.postUrl(url, EncodingUtils.getBytes(postData, "BASE64"));

       この方法には欠陥があり、Android 5.0.0以上のApiでしかありません.
5.0.0以下のApiにはこの方法はありません.これもピットで、すべての機種と互換性がありません.このメソッドのsetRequestPropertyメソッドで要求プロパティを再設定し、postUrlを使用して再ロードすることで、ロールバックキーを押した後のページの再リカバリを解決できます.注意postロードはキャッシュできないので、キャッシュプロパティを設定するときは必ず再ロードプロパティに設定してください.
       3、解決後の問題:
      問題は解決したように見えますが、この方法には穴があります.この方法をよく検討すると、shouldInterceptRequestメソッドはロード全体で呼び出されていることがわかります.パッケージをキャプチャすると、リンクH 5ページにロードされた各リクエストをロードし始めると、そのメソッドが呼び出され、簡単に言えば、何個のリクエストがあるか、そのメソッドが何回呼び出されるかがわかります.ページにpostリクエストが1回ある場合は、問題が発生します.2回目のpostリクエストのリクエスト内容を1回目と比較して、1回目のページをロードするか、2回目のページをロードするかを選択する必要があります.そうしないと、1回目のpostページがデフォルトでロードされます.
      4、結論
      WebviewのH 5ページのロードはloadUrl方式を使うのが一番いいです.
postUrl方式でロードするには、setWebViewClientメソッド全体を書き換える必要があります.中には穴がたくさんあります.これはお勧めしません.