騰訊x5開(kāi)源庫(kù)進(jìn)行Js交互

騰訊的x5開(kāi)源庫(kù)的優(yōu)勢(shì):提高webView開(kāi)發(fā)效率套媚,大概要節(jié)約你百分之六十的時(shí)間成本。該案例支持處理js的交互邏輯且無(wú)耦合逝段、同時(shí)暴露進(jìn)度條加載進(jìn)度私股、可以監(jiān)聽(tīng)異常error狀態(tài)、支持視頻播放并且可以全頻冤留、支持加載word碧囊,xls,ppt纤怒,pdf糯而,txt等文件文檔、發(fā)短信泊窘、打電話熄驼、發(fā)郵件像寒、打開(kāi)文件操作上傳圖片、喚起原生App瓜贾、x5庫(kù)為最新版本诺祸,功能強(qiáng)大。

那么我們就來(lái)使用一下吧

導(dǎo)入依賴庫(kù)

implementation 'cn.yc:WebViewLib:1.1.2'

最簡(jiǎn)單使用

  • 項(xiàng)目初始化
X5WebUtils.init(this);
  • 最普通使用祭芦,需要自己做手動(dòng)設(shè)置setting相關(guān)屬性
<BridgeWebView
    android:id="@+id/web_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbarSize="3dp" />
  • 也可以使用X5WebView筷笨,已經(jīng)做了常見(jiàn)的setting屬性設(shè)置
<X5WebView
    android:id="@+id/web_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbarSize="3dp" />
  • 如果想有帶進(jìn)度的,可以使用ProgressWebView可以使用ProgressWebView
<ProgressWebView
    android:id="@+id/web_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbarSize="3dp" />

常用api

  • 關(guān)于web的接口回調(diào)龟劲,包括常見(jiàn)狀態(tài)頁(yè)面切換胃夏,進(jìn)度條變化等監(jiān)聽(tīng)處理
mWebView.getX5WebChromeClient().setWebListener(interWebListener);
private InterWebListener interWebListener = new InterWebListener() {
    @Override
    public void hindProgressBar() {
        pb.setVisibility(View.GONE);
    }

    @Override
    public void showErrorView() {
        //設(shè)置自定義異常錯(cuò)誤頁(yè)面
    }

    @Override
    public void startProgress(int newProgress) {
        pb.setProgress(newProgress);
    }
};
具體的X5WebView的用法(帶進(jìn)度條)
public class Two_Activity extends AppCompatActivity {

    private X5WebView mXView;
    private ProgressBar mPb;
    private QbSdk.PreInitCallback cb;
    private static final String StringURL  ="https://www.baidu.com/";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_two_);
        initView();
    }

    private void initView() {
        mXView = (X5WebView) findViewById(R.id.x_view);
        mXView.getX5WebChromeClient().setWebListener(interWebListener);
        mPb = (ProgressBar) findViewById(R.id.pb);
        initLoad();
    }

    private void initLoad() {

        cb = new QbSdk.PreInitCallback() {
            @Override
            public void onCoreInitFinished() {
            }

            @Override
            public void onViewInitFinished(boolean b) {
                //x5內(nèi)核初始化完成的回調(diào),為true表示x5內(nèi)核加載成功昌跌,否則表示x5內(nèi)核加載失敗构订,會(huì)自動(dòng)切換到系統(tǒng)內(nèi)核。
                Log.e("tag", " onViewInitFinished is " + b);

            }
        };
        //x5內(nèi)核初始化接口
        QbSdk.initX5Environment(getApplicationContext(), cb);
        mXView.loadUrl(StringURL);
    }



    private InterWebListener interWebListener = new InterWebListener() {
        @Override
        public void hindProgressBar() {
            mPb.setVisibility(View.GONE);
        }

        @Override
        public void showErrorView() {
            //設(shè)置自定義異常錯(cuò)誤頁(yè)面
            Toast.makeText(Two_Activity.this, "未知錯(cuò)誤", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void startProgress(int newProgress) {
            mPb.setProgress(newProgress);
        }
    };
}

  • 關(guān)于視頻播放的時(shí)候避矢,web的接口回調(diào)悼瘾,主要是視頻相關(guān)回調(diào),比如全頻审胸,取消全頻亥宿,隱藏和現(xiàn)實(shí)webView
x5WebChromeClient = x5WebView.getX5WebChromeClient();
x5WebChromeClient.setVideoWebListener(new VideoWebListener() {
    @Override
    public void showVideoFullView() {
        //視頻全頻播放時(shí)監(jiān)聽(tīng)
    }

    @Override
    public void hindVideoFullView() {
        //隱藏全頻播放,也就是正常播放視頻
    }

    @Override
    public void showWebView() {
        //顯示webView
    }

    @Override
    public void hindWebView() {
        //隱藏webView
    }
});

使用建議

  • 優(yōu)化一下相關(guān)的操作 關(guān)于設(shè)置js支持的屬性
@Override
public void onResume() {
    super.onResume();
    if (mWebView != null) {
        mWebView.getSettings().setJavaScriptEnabled(true);
    }
}

@Override
protected void onStop() {
    super.onStop();
    if (mWebView != null) {
        mWebView.getSettings().setJavaScriptEnabled(false);
    }
}
關(guān)于destroy銷毀邏輯
@Override
protected void onDestroy() {
    try {
        if (webView != null) {
            webView.stopLoading();
            webView.destroy();
            webView = null;
        }
    } catch (Exception e) {
        Log.e("X5WebViewActivity", e.getMessage());
    }
    super.onDestroy();
}

js調(diào)用(如何使用項(xiàng)目js調(diào)用)

  • 代碼如下所示砂沛,下面中的jsname代表的是js這邊提供給客戶端的方法名稱
mWebView.registerHandler("jsname", new BridgeHandler() {
    @Override
    public void handler(String data, CallBackFunction function) {
        
    }
});
  • 如何回調(diào)數(shù)據(jù)給web那邊
function.onCallBack("回調(diào)數(shù)據(jù)");

js的調(diào)用時(shí)機(jī)分析

  • onPageFinished()或者onPageStarted()方法中注入js代碼
    做過(guò)WebView開(kāi)發(fā)烫扼,并且需要和js交互,大部分都會(huì)認(rèn)為js在WebViewClient.onPageFinished()方法中注入最合適碍庵,此時(shí)dom樹(shù)已經(jīng)構(gòu)建完成映企,頁(yè)面已經(jīng)完全展現(xiàn)出來(lái)。但如果做過(guò)頁(yè)面加載速度的測(cè)試静浴,會(huì)發(fā)現(xiàn)WebViewClient.onPageFinished()方法通常需要等待很久才會(huì)回調(diào)(首次加載通常超過(guò)3s)堰氓,這是因?yàn)閃ebView需要加載完一個(gè)網(wǎng)頁(yè)里主文檔和所有的資源才會(huì)回調(diào)這個(gè)方法。
    能不能在WebViewClient.onPageStarted()中注入呢苹享?答案是不確定双絮。經(jīng)過(guò)測(cè)試,有些機(jī)型可以得问,有些機(jī)型不行囤攀。在WebViewClient.onPageStarted()中注入還有一個(gè)致命的問(wèn)題——這個(gè)方法可能會(huì)回調(diào)多次,會(huì)造成js代碼的多次注入宫纬。
    從7.0開(kāi)始焚挠,WebView加載js方式發(fā)生了一些小改變,官方建議把js注入的時(shí)機(jī)放在頁(yè)面開(kāi)始加載之后漓骚。
    WebViewClient.onProgressChanged()方法中注入js代碼
    WebViewClient.onProgressChanged()這個(gè)方法在dom樹(shù)渲染的過(guò)程中會(huì)回調(diào)多次蝌衔,每次都會(huì)告訴我們當(dāng)前加載的進(jìn)度榛泛。
    在這個(gè)方法中,可以給WebView自定義進(jìn)度條胚委,類似微信加載網(wǎng)頁(yè)時(shí)的那種進(jìn)度條
    如果在此方法中注入js代碼,則需要避免重復(fù)注入叉信,需要增強(qiáng)邏輯亩冬。可以定義一個(gè)boolean值變量控制注入時(shí)機(jī)
    那么有人會(huì)問(wèn)硼身,加載到多少才需要處理js注入邏輯呢硅急?
    正是因?yàn)檫@個(gè)原因,頁(yè)面的進(jìn)度加載到80%的時(shí)候佳遂,實(shí)際上dom樹(shù)已經(jīng)渲染得差不多了营袜,表明WebView已經(jīng)解析了標(biāo)簽,這時(shí)候注入一定是成功的丑罪。在WebViewClient.onProgressChanged()實(shí)現(xiàn)js注入有幾個(gè)需要注意的地方:
    1 上文提到的多次注入控制荚板,使用了boolean值變量控制
    2 重新加載一個(gè)URL之前,需要重置boolean值變量吩屹,讓重新加載后的頁(yè)面再次注入js
    3 如果做過(guò)本地js跪另,css等緩存,則先判斷本地是否存在煤搜,若存在則加載本地免绿,否則加載網(wǎng)絡(luò)js
    4 注入的進(jìn)度閾值可以自由定制,理論上10%-100%都是合理的擦盾,不過(guò)建議使用了75%到90%之間可以嘲驾。

問(wèn)題反饋

視頻播放寬度超過(guò)屏幕
  • 視頻播放寬度比webView設(shè)置的寬度大,超過(guò)屏幕:這個(gè)時(shí)候可以設(shè)置ws.setLoadWithOverviewMode(false);
x5加載office資源
  • 關(guān)于加載word迹卢,pdf辽故,xls等文檔文件注意事項(xiàng):Tbs不支持加載網(wǎng)絡(luò)的文件,需要先把文件下載到本地腐碱,然后再加載出來(lái)
  • 還有一點(diǎn)要注意榕暇,在onDestroy方法中調(diào)用此方法mTbsReaderView.onStop(),否則第二次打開(kāi)無(wú)法瀏覽喻杈。更多可以看FileReaderView類代碼彤枢!
WebView播放視頻問(wèn)題

1、此次的方案用到WebView筒饰,而且其中會(huì)有視頻嵌套缴啡,在默認(rèn)的WebView中直接播放視頻會(huì)有問(wèn)題, 而且不同的SDK版本情況還不一樣瓷们,網(wǎng)上搜索了下解決方案业栅,在此記錄下.
webView.getSettings.setPluginState(PluginState.ON);webView.setWebChromeClient(new WebChromeClient());
2秒咐、然后在webView的Activity配置里面加上: android:hardwareAccelerated="true"
3、以上可以正常播放視頻了碘裕,但是webview的頁(yè)面都finish了居然還能聽(tīng) 到視頻播放的聲音携取, 于是又查了下發(fā)現(xiàn)webview的onResume方法可以繼續(xù)播放,onPause可以暫停播放帮孔, 但是這兩個(gè)方法都是在Added in API level 11添加的雷滋,所以需要用反射來(lái)完成。
4文兢、停止播放:在頁(yè)面的onPause方法中使用:webView.getClass().getMethod("onPause").invoke(webView, (Object[])null);
5晤斩、繼續(xù)播放:在頁(yè)面的onResume方法中使用:webView.getClass().getMethod("onResume").invoke(webView,(Object[])null);這樣就可以控制視頻的暫停和繼續(xù)播放了。

無(wú)法獲取webView的正確高度
  • 偶發(fā)情況姆坚,獲取不到webView的內(nèi)容高度
    其中htmlString是一個(gè)HTML格式的字符串澳泵。
WebView view = new WebView(context);
view.loadData(htmlString, "text/html", "utf-8");

view.setWebViewClient(new WebViewClient() {
    public void onPageFinished(WebView view, String url) {
     super.onPageFinished(view, url);
     Log.d("2", view.getContentheight() + "");
    }
});

這是因?yàn)閛nPageFinished回調(diào)指的WebView已經(jīng)完成從網(wǎng)絡(luò)讀取的字節(jié)數(shù),這一點(diǎn)兼呵。在點(diǎn)onPageFinished被激發(fā)的頁(yè)面可能還沒(méi)有被解析兔辅。

第一種解決辦法:提供onPageFinished()一些延遲
webView.setWebViewClient(new WebViewClient() {
 @Override
 public void onPageFinished(WebView view, String url) {
  super.onPageFinished(view, url);
  new Handler().postDelayed(new Runnable() {
   @Override
   public void run() {
    int contentHeight = webView.getContentHeight();
    int viewHeight = webView.getHeight();
   }
  }, 500);
 }
});
WebView硬件加速導(dǎo)致頁(yè)面渲染閃爍

4.0以上的系統(tǒng)我們開(kāi)啟硬件加速后击喂,WebView渲染頁(yè)面更加快速幢妄,拖動(dòng)也更加順滑。但有個(gè)副作用就是茫负,當(dāng)WebView視圖被整體遮住一塊蕉鸳,然后突然恢復(fù)時(shí)(比如使用SlideMenu將WebView從側(cè)邊滑出來(lái)時(shí)),這個(gè)過(guò)渡期會(huì)出現(xiàn)白塊同時(shí)界面閃爍忍法。解決這個(gè)問(wèn)題的方法是在過(guò)渡期前將WebView的硬件加速臨時(shí)關(guān)閉潮尝,過(guò)渡期后再開(kāi)啟

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市饿序,隨后出現(xiàn)的幾起案子勉失,更是在濱河造成了極大的恐慌,老刑警劉巖原探,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乱凿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡咽弦,警方通過(guò)查閱死者的電腦和手機(jī)徒蟆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)型型,“玉大人段审,你說(shuō)我怎么就攤上這事∧炙猓” “怎么了寺枉?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵抑淫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我姥闪,道長(zhǎng)始苇,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任筐喳,我火速辦了婚禮催式,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疏唾。我一直安慰自己蓄氧,他們只是感情好函似,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布槐脏。 她就那樣靜靜地躺著,像睡著了一般撇寞。 火紅的嫁衣襯著肌膚如雪顿天。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天蔑担,我揣著相機(jī)與錄音牌废,去河邊找鬼。 笑死啤握,一個(gè)胖子當(dāng)著我的面吹牛鸟缕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播排抬,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼懂从,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蹲蒲?” 一聲冷哼從身側(cè)響起番甩,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎届搁,沒(méi)想到半個(gè)月后缘薛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卡睦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年宴胧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片表锻。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡牺汤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出浩嫌,到底是詐尸還是另有隱情檐迟,我是刑警寧澤补胚,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站追迟,受9級(jí)特大地震影響溶其,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜敦间,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一瓶逃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧廓块,春花似錦厢绝、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至拴清,卻和暖如春靶病,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背口予。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工娄周, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沪停。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓煤辨,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親木张。 傳聞我的和親對(duì)象是個(gè)殘疾皇子众辨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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