Webviewで発生した問題を自分で処理するための要約

7759 ワード

こんなに長い間androidをしていたのに、webviewを使うと多くの問題が発生し、多くの解決策が蓄積され、忘れないように記録されています.
また、多くの解決策もネットからすり抜けていて、すみません..
以下に要約します.
1.appインタフェースの内部でのみジャンプし、ブラウザにジャンプしない
関連メソッドを書き換え、次のように処理します.
webview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

2.物理的な戻りキーは前のレベルに戻る
説明:webviewにロードされたhtmlインタフェースには独自の内部ジャンプがあり、携帯電話の物理的な戻りキーを処理しないと、前のレベルではなく現在のactivityインタフェースを終了するだけで、前のレベルに戻るには次のようにします.
@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && wvTalking.canGoBack()) {
            webview.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

3.クッキーによる問題
説明:主にapp切替ユーザーによるものです.インタフェースに入ると自動的にクッキーが保存され、アカウントを切り替えた後、前のクッキーが分からなくなって表示上の心配があるので、クリアしてから問題が起こらないことを保証する必要があります.
処理方法①すべてのクッキーをクリアする
//    cookie  
private void removeAllCookie()  
{  
    CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(webview.getContext());  
    CookieManager cookieManager = CookieManager.getInstance();  
    cookieManager.setAcceptCookie(true);  
    cookieManager.removeSessionCookie();  
    cookieManager.removeAllCookie();  
    cookieSyncManager.sync();  
}  

弊害:webivewファイルの下のすべてのクッキーをクリアし、一部のインタフェースで前回の状態を保存する必要があるとエラーが発生します.
処理方法②:特定urlのクッキーをクリアする
Webviewではurlをkeyとしてクッキーに保存しますが、そのkeyに対応する値を空に設定して処理します.
 /**
     *     cookie   
     */
    public static void synCookies(Context context, String url) {
        CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);
        cookieManager.removeSessionCookie();//  
        cookieManager.setCookie(url, "");//      cookies
        CookieSyncManager.getInstance().sync();
    }

4.js関連(js調Android Android呼び出しjs)
具体的には、プロジェクトの例を示します.
まず1.jsをサポートする必要があります.また、インタラクティブな呼び出しルールを2つで決定する必要があります.たとえば、次のようにします.
webview.getSettings()..setJavaScriptEnabled(true);
 webview.addJavascriptInterface(new JavaScript(), "BHWEB");
 class JavaScript {
        @JavascriptInterface
        public void pop() {
            finish();
        }
    }

②ここでは、jsが1つの大図プレビューおよびピクチャキャッシュ(キャッシュフレームワークはImageLoaderを用いる)を実現する例
//           ,          ,          。
    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (!TextUtils.isEmpty(url)) {
                Intent intent = new Intent(TeacherTalkArticleInfoActivity.this,InternetExplorerActivity.class);
                intent.putExtra("url", url);
                startActivity(intent);
                return true;
            }
            return super.shouldOverrideUrlLoading(view, url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            //         Js   startLoadImages()    html      
            wvArticle.loadUrl("javascript:startLoadImages()");
        }
    }
 class JavaScript {
        @JavascriptInterface
        //    
        public void viewImages(String json) {
            if (gson == null) {
                gson = new Gson();
            }
            final ImageModel imageModel = gson.fromJson(json, ImageModel.class);
            String[] imageUrls = imageModel.imageUrls;
            if (imageUrls == null || imageUrls.length == 0) {
                return;
            }
            Intent intent = new Intent(TeacherTalkArticleInfoActivity.this,TeacherTalkZoomImageActivity.class);
            intent.putExtra("urls", imageUrls);
            intent.putExtra("index", Integer.valueOf(imageModel.index));
            startActivity(intent);
        }

        @JavascriptInterface
        public void loadImage(String json) {
            if (gson == null) {
                gson = new Gson();
            }
            final ImageModel imageModel = gson.fromJson(json, ImageModel.class);

            ImageLoader.getInstance().loadImage(imageModel.url, LoaderImage.getInstance().postCacheoptions, new ImageLoadingListener() {
                @Override
                public void onLoadingStarted(String s, View view) {
                }

                @Override
                public void onLoadingFailed(String s, View view, FailReason failReason) {
                }

                @Override
                public void onLoadingComplete(final String s, View view, final Bitmap bitmap) {
                    try {
                        boolean save = cache.save(s, bitmap);//  ImageLoader           
                        if (save) {
                            String toString = "'file://" + cache.get(s).getPath() + "'," + imageModel.index;
                            final String jsonData = "javascript:loadImageSuccess(" + toString + ")";
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    wvArticle.loadUrl(jsonData);//                 ,js      loadImageSuccess
                                }
                            });
                        }
                    } catch (IOException e) {
                    }
                }

                @Override
                public void onLoadingCancelled(String s, View view) {}
            });
        }

    }

(ここのjsファイルはtest.htmlです.assetsディレクトリの下に置きます)
注意点:
  • androidがjsを呼び出す方法はwebviewである.loadUrl(「javascript:jsメソッド名」)、jsメソッドでパラメータを渡す必要がある場合、String toString=「'file://」+path+「',」+imageModel.index;    String jsonData = "javascript:loadImageSuccess("+ toString + ")"; 注意「'」の引用符は
  • を使用します.
  • jsファイルは必ずassetsディレクトリの下に置かなければならない.jsファイルをロードする方法はwebviewである.loadDataWithBaseURL(null,"teacherTalkDetail.html","text/html","UTF-8",null)
  • ローカルの画像に保存して、アップロードする時類似の処理が必要です:“file://”+path
  • urlをロードするときにloadUrlを使用すればよい.ローカルassestsディレクトリの下にロードされたhtmlのロード方式はloadUrl(「file://android_assest/test.html")、具体的にはhttp://blog.csdn.net/edmond999/article/details/45197013


  • 5.webviewローカルhtmlをロードしてドメイン間アクセスを実現
    ローカルassestsディレクトリの下に置かれたhtmlのロード方法はloadUrl("file://android_assest/test.html")
    サーバのWebコードをローカルに保存してトラフィックを節約する必要がある場合がありますが、中のデータはサーバでajaxを使用して取得されます.このページをローカルwenviewで開くと、ajaxに追加されたリンクが応答しない場合があります.処理方法は次のとおりです.
    まずandroidは、android WebView privateオブジェクトWebView Core mWebView Coreにアクセスし、mWebView Coreのprivateメソッドn tiveRegisterURLSchemeAsLocalを呼び出し、httpとhttpsをローカルアクセス、コード
    try {
                if (Build.VERSION.SDK_INT >= 16) {
                    Class> clazz = webView.getSettings().getClass();
                    Method method = clazz.getMethod(
                            "setAllowUniversalAccessFromFileURLs", boolean.class);
                    if (method != null) {
                        method.invoke(webView.getSettings(), true);
                    }
                }
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
    }