JsBridge學(xué)習

  1. 我們先來了解一下WebView
    • 1 添加權(quán)限:AndroidManifest.xml中設(shè)置權(quán)限"android.permission.INTERNET",否則會出Web page not available錯誤第晰。
    • 2 在要Activity中生成一個WebView組件:WebView webView = new WebView(this);或者可以在activity的layout文件里添加webview控件
    • 3 設(shè)置WebView基本信息:
mWebView = (WebView) findViewById(R.id.wb);
mWebView.getSettings().setJavaScriptEnabled(true);//支持javascript
mWebView.requestFocus();//觸摸焦點起作用mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);//取消滾動條
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//設(shè)置允許js彈出alert對話框
//load本地
mWebView.loadUrl("file:///android_asset/hellotest.html");
//load在線
//mWebView.loadUrl("http://www.google.com");
//js訪問android羡亩,定義接口
mWebView.addJavascriptInterface(new JsInteration(), "control");
//設(shè)置了Alert才會彈出供填,重新onJsAlert()方法return true可以自定義處理信息
mWebView.setWebChromeClient(new WebChromeClient() {    
@Override    
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {        
//return super.onJsAlert(view, url, message, result);        
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();        
return true;  
  }});
  • 4 設(shè)置WevView要顯示的網(wǎng)頁:互聯(lián)網(wǎng)用:webView.loadUrl("http://www.google.com"); 本地文件用:webView.loadUrl("file:///android_asset/XX.html"); 本地文件存放在:assets文件中**
  • 5 如果希望點擊鏈接由自己處理南吮,而不是新開Android的系統(tǒng)browser中響應(yīng)該鏈接。給WebView添加一個事件監(jiān)聽對象(WebViewClient)并重寫其中的一些方法: shouldOverrideUrlLoading:對網(wǎng)頁中超鏈接按鈕的響應(yīng)仍翰。當按下某個連接時WebViewClient會調(diào)用這個方法蒂窒,并傳遞參數(shù)
   @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                view.loadUrl("");
                return true;
            }
  • 6 處理https請求
    webView默認是不處理https請求的棠众,頁面顯示空白,需要進行如下設(shè)置:
 @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                super.onReceivedSslError(view, handler, error);
                handler.proceed();   // 表示等待證書響應(yīng)
//                handler.cancel();  //表示掛起連接粪般,為默認方式
//                handler.handleMessage(null); //可做其他處理

1拼余,接收到Http請求的事件onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)
2,載入頁面完成的事件public void onPageFinished(WebView view, String url){ }
同樣道理亩歹,我們知道一個頁面載入完成姿搜,于是我們可以關(guān)閉loading條,切換程序動作捆憎。
3舅柜,載入頁面開始的事件public void onPageStarted(WebView view, String url, Bitmap favicon) { }
這個事件就是開始載入頁面調(diào)用的,通常我們可以在這設(shè)定一個loading的頁面躲惰,告訴用戶程序在等待網(wǎng)絡(luò)響應(yīng)致份。 通過這幾個事件,我們可以很輕松的控制程序操作础拨,一邊用著瀏覽器顯示內(nèi)容氮块,一邊監(jiān)控著用戶操作實現(xiàn)我們需要的各種顯示方式,同時可以防止用戶產(chǎn)生誤操作诡宗。

  1. 如果用webview點鏈接看了很多頁以后滔蝉,如果不做任何處理,點擊系統(tǒng)“Back”鍵塔沃,整個瀏覽器會調(diào)用finish()而結(jié)束自身蝠引,如果希望瀏覽的網(wǎng)頁回退而不是退出瀏覽器,需要在當前Activity中處理并消費掉該Back事件。 覆蓋Activity類的onKeyDown(int keyCoder,KeyEvent event)方法螃概。
 @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK &&IdWebView.canGoBack()){
        IdWebView.goBack(); //返回前一個頁面
        return  true;
    }
    return super.onKeyDown(keyCode, event);
}

二. webview與js的交互(相互調(diào)用參數(shù)矫夯、傳值)

<!DOCTYPE html><html><head>    <meta charset="utf-8">    
<title>jaydenxiao遇上了webview</title>    
<script>
function sayHello() {
alert("我是無參無返回toast") 
}
function alertMessage(message) { 
alert(message)  
}
function toastMessage(message) {
window.control.toastMessage(message)
}
function sumToJava(number1, number2){
window.control.onSumResult(number1 + number2)
}
function sumToJava2(number1, number2) {
return number1 + number2;
}    
</script>
</head><body>
<button type="button" id="button" onclick="toastMessage('js調(diào)用了android方法')">js訪問android中方法</button>
</body>
</html>

調(diào)用示例

js調(diào)用java
調(diào)用格式為window.jsInterfaceName.methodName(parameterValues)
此例中我們使用的是control作為注入接口名稱

function toastMessage(message){
window.control.toastMessage(message)
}
function sumToJava(number1 ,number2){
window.control.onSumResult(number1 +number2)
}

Java調(diào)用JS
webview調(diào)用js的基本格式為
webview.loadUrl("javascript:methodName(paraameterValues)")

  • 1 android調(diào)用js無參無返回值函數(shù)
final String call = "javacript:sayHello()";
mWebView.post(new Runnable(){
public void run(){
mWebView.loadurl(call);
}
});
  • 2.android調(diào)用js有參無返回值函數(shù)
final String call = "javascript:alertMessage(\""+"我是android傳過來的內(nèi)容,hey,man"+"\")"
mWebView.post(new Runnable(){
public void run(){
mWebView.loadUrl(call);
}
})

-3.android調(diào)用js有參有返回值函數(shù)((4.4以上)
Android 4.4以上使用evaluateJavascript即可吊洼。這里展示一個簡單的交互示例 具有返回值的js方法
js代碼如下:

function sumToJava2(number1, number2) {
return number1 + number2;
}

android代碼如下:

@TargetApi(Build.VERSION_CODES.KITKAT)
public void Android2JsHaveParmHaveResult2(View view) { 
 mWebView.evaluateJavascript("sumToJava2(3,4)", new ValueCallback<String>() {
@Override 
public void onReceiveValue(String Str) {   
Toast.makeText(getApplicationContext(), "我是android調(diào)用js方法(4.4后)训貌,入?yún)⑹?和4,js返回結(jié)果是" + Str, Toast.LENGTH_LONG).show(); 
  }    
});}

最后冒窍,我們講一下我們的webview的內(nèi)存泄露問題

public void releaseAllWebViewCallback() { 
 if (android.os.Build.VERSION.SDK_INT < 16) { 
 try { 
 Field field = WebView.class.getDeclaredField("mWebViewCore"); 
field = field.getType().getDeclaredField("mBrowserFrame"); 
 field = field.getType().getDeclaredField("sConfigCallback");
field.setAccessible(true); 
 field.set(null, null);
 } catch (NoSuchFieldException e) {
 if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
 } catch (IllegalAccessException e) {
 if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
  }
 } else {
 try {
 Field sConfigCallback = Class.forName("android.webkit.BrowserFrame").getDeclaredField("sConfigCallback");
 if (sConfigCallback != null) {
 sConfigCallback.setAccessible(true);
 sConfigCallback.set(null, null);
  }
 } catch (NoSuchFieldException e) {
if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
 } catch (ClassNotFoundException e) {
 if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
 } catch (IllegalAccessException e) {
 if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
  }
  }
 }

在webview的 destroy方法里 調(diào)用這個方法就行了递沪。

public class WithPhotoWebActivity extends AppCompatActivity{
    private ProgressBar pg;
    private WebView mWebView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_with_photo_webview);
        initView();
    }

    private void initView() {
        pg = (ProgressBar) findViewById(R.id.pg);
        pg.setVisibility(View.VISIBLE);
        mWebView = (WebView) findViewById(R.id.wb);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.loadUrl("http://m.3gbizhi.com/");
        mWebView.addJavascriptInterface(this,"imagelistner");
        mWebView.setWebViewClient(new MyWebViewClient());
        mWebView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                WebView.HitTestResult result = mWebView.getHitTestResult();
                if(result!=null){
                    int type = result.getType();
                    if(type == WebView.HitTestResult.IMAGE_TYPE ||type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE){
                        String  imgurl = result.getExtra();
                        Toast.makeText(WithPhotoWebActivity.this, imgurl, Toast.LENGTH_SHORT).show();
                    }
                }
                return true;
            }
        });
    }

    @JavascriptInterface
    public void openImage(String img) {
        System.out.println(img);
        //ShowWebImageActivity.startAction(this,img);
        System.out.println(img);
    }

    private void addImageClickListner(){
        // 這段js函數(shù)的功能就是,遍歷所有的img幾點综液,并添加onclick函數(shù)区拳,在還是執(zhí)行的時候調(diào)用本地接口傳遞url過去
        mWebView.loadUrl(
                "javascript:(function(){"+
           " var objs = document.getElementsByTagName(\"img\");"+
           " for(var i=0;i<objs.length;i++)"+
           " {"+
             "   objs[i].onclick=function()"+
              "  {"+
                   " window.imagelistner.openImage(this.src);"+
               " }"+
          "  }"+
      "  })()"
        );
    }

    private class MyWebViewClient extends WebViewClient{
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            pg.setVisibility(View.GONE);
            view.getSettings().setJavaScriptEnabled(true);
            super.onPageFinished(view,url);
            // html加載完成之后,添加監(jiān)聽圖片的點擊js函數(shù)
            addImageClickListner();
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            view.getSettings().setJavaScriptEnabled(true);
            super.onPageStarted(view, url, favicon);
        }
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末意乓,一起剝皮案震驚了整個濱河市樱调,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌届良,老刑警劉巖笆凌,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異士葫,居然都是意外死亡乞而,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門慢显,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爪模,“玉大人,你說我怎么就攤上這事荚藻∥莨啵” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵应狱,是天一觀的道長共郭。 經(jīng)常有香客問我,道長疾呻,這世上最難降的妖魔是什么除嘹? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮岸蜗,結(jié)果婚禮上尉咕,老公的妹妹穿的比我還像新娘。我一直安慰自己璃岳,他們只是感情好年缎,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布悔捶。 她就那樣靜靜地躺著,像睡著了一般晦款。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上枚冗,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天缓溅,我揣著相機與錄音,去河邊找鬼赁温。 笑死坛怪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的股囊。 我是一名探鬼主播袜匿,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼稚疹!你這毒婦竟也來了居灯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤内狗,失蹤者是張志新(化名)和其女友劉穎怪嫌,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柳沙,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡岩灭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赂鲤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片噪径。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖数初,靈堂內(nèi)的尸體忽然破棺而出找爱,到底是詐尸還是另有隱情,我是刑警寧澤泡孩,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布缴允,位于F島的核電站,受9級特大地震影響珍德,放射性物質(zhì)發(fā)生泄漏练般。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一锈候、第九天 我趴在偏房一處隱蔽的房頂上張望薄料。 院中可真熱鬧,春花似錦泵琳、人聲如沸摄职。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谷市。三九已至蛔垢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間迫悠,已是汗流浹背鹏漆。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留创泄,地道東北人艺玲。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像鞠抑,于是被迫代替她去往敵國和親饭聚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,527評論 25 707
  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程搁拙,因...
    小菜c閱讀 6,358評論 0 17
  • WebView·開車指南 2016-08-31BugDev 北京市東城區(qū)首席Bug布道師開山之作秒梳,一整月交通事故血...
    53c021c38a1d閱讀 826評論 0 1
  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    南城的人閱讀 4,739評論 0 19
  • 他走在前面端幼,頭也不回的說,“我叫阿泰弧满∑排埽”說完又覺得自己該看她一眼⊥ノ兀回頭滑进,她弱弱的瞧著他,第一句話就讓他抓狂了募谎。 “...
    可可豆子閱讀 79評論 0 5