理解Android中WebView相關(guān)的幾個(gè)概念

學(xué)知識(shí)就是要掌握一些概念的內(nèi)涵和外延。So,讓我們看看與WebView相關(guān)的幾個(gè)概念吧认臊。

概念 內(nèi)涵 外延
WebView 一個(gè)絕對(duì)布局容器 用來展示或渲染W(wǎng)eb頁面
WebSettings 一個(gè)抽象類寨辩,包含對(duì)WebView的設(shè)置方法吓懈。 用來對(duì)WebView進(jìn)行設(shè)置,比如支持JS靡狞、緩存模式等
WebViewClient 這個(gè)類的方法有一個(gè)特點(diǎn)耻警,就是參數(shù)的第一項(xiàng)就是WebView,其他項(xiàng)是事件或數(shù)據(jù)信息甸怕。WebView通過該類對(duì)外通知頁面加載相關(guān)的消息 用來在頁面加載的各個(gè)階段進(jìn)行業(yè)務(wù)處理甘穿,處理加載錯(cuò)誤情況,攔截頁面內(nèi)和頁面外的請(qǐng)求
WebChromeClient WebView通過該類梢杭,通知獲取到站點(diǎn)圖標(biāo)温兼、標(biāo)題、加載進(jìn)度武契,以及JS對(duì)話框等 用來更好地展示頁面和交互

理解了上面幾個(gè)概念后募判,我們就可以處理一般的業(yè)務(wù)需求了。比如

設(shè)置緩存

緩存模式

獲取到WebSettings然后調(diào)用其中的設(shè)置方法就可以了咒唆。

WebSettings webSettings = webView.getSettings();
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

緩存模式有LOAD_DEFAULT(默認(rèn))届垫、LOAD_CACHE_ELSE_NETWORK(先緩存后網(wǎng)絡(luò))、LOAD_NO_CACHE(不要緩存)全释、LOAD_CACHE_ONLY(只要緩存)装处,可以根據(jù)業(yè)務(wù)要求選擇。

緩存機(jī)制

(1)瀏覽器緩存機(jī)制

  • 概念:通過 HTTP 協(xié)議頭里的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段來控制文件緩存的機(jī)制浸船。
  • 適用:適用于 Web 的靜態(tài)資源文件妄迁。

(2)Dom Storage(Web Storage)

  • 概念:通過存儲(chǔ)字符串的 Key/Value 對(duì)來提供找前,并提供 5MB (不同瀏覽器可能不同,分 HOST)的存儲(chǔ)空間(Cookies 才 4KB)判族。分為 sessionStorage 和 localStorage躺盛。
  • 適用:代替掉將一些不需要讓服務(wù)器知道的信息存儲(chǔ)到 cookies 里的這種傳統(tǒng)方法。webSettings.setDomStorageEnabled(true);

(3)Web SQL Database

  • 概念:基于 SQL 的數(shù)據(jù)庫存儲(chǔ)機(jī)制形帮,用于存儲(chǔ)適合數(shù)據(jù)庫的結(jié)構(gòu)化數(shù)據(jù)槽惫。
  • 適用:Web SQL Database 存儲(chǔ)機(jī)制不再推薦使用,將來也不再維護(hù)辩撑,而是推薦使用 AppCache 和 IndexedDB界斜。
webSettings.setDatabaseEnabled(true);
final String dbPath = getApplicationContext().getDir("db", Context.MODE_PRIVATE).getPath();
webSettings.setDatabasePath(dbPath);

(4)Application Cache(AppCache)

  • 概念:為支持 Web App 離線使用而開發(fā)的緩存機(jī)制。以文件為單位進(jìn)行緩存合冀,且文件有一定更新機(jī)制各薇。
  • 適用:AppCache 是對(duì)瀏覽器緩存機(jī)制的補(bǔ)充,不是替代君躺。不推薦使用了,標(biāo)準(zhǔn)也不會(huì)再支持棕叫。
webSettings.setAppCacheEnabled(true);
final String cachePath = getApplicationContext().getDir("cache", Context.MODE_PRIVATE).getPath();
webSettings.setAppCachePath(cachePath);
webSettings.setAppCacheMaxSize(5*1024*1024);

(5)Indexed Database

  • 概念:NoSQL 數(shù)據(jù)庫林螃,類似于 Dom Storage 的 key-value 的存儲(chǔ)方式,但功能更強(qiáng)大俺泣,且存儲(chǔ)空間更大疗认。
  • 適用:用于存儲(chǔ)大塊或復(fù)雜結(jié)構(gòu)的數(shù)據(jù),提供更大的存儲(chǔ)空間伏钠,使用起來也比較簡單横漏。可以作為 Web SQL Database 的替代熟掂。不太適合靜態(tài)文件的緩存缎浇。webSettings.setJavaScriptEnabled(true);

(6)File System API

  • 概念:為 Web App 提供了一個(gè)虛擬的文件系統(tǒng),運(yùn)行在沙盒中
  • 適用:任何需要通過文件來管理數(shù)據(jù)打掘,或通過文件系統(tǒng)進(jìn)行數(shù)據(jù)管理的場景都比較適合华畏。到目前,Android 系統(tǒng)的 Webview 還不支持 File System API尊蚁。

處理頁面導(dǎo)航

方法一

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
        myWebView.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

方法二

@Override
public void onBackPressed() {
    if (contentWeb.canGoBack()) {
        contentWeb.goBack();
    } else {
        super.onBackPressed();
    }
}

與Activity/Fragment生命周期相適應(yīng)

參考WebViewFragment實(shí)現(xiàn)

/**
 * A fragment that displays a WebView.
 * <p>
 * The WebView is automically paused or resumed when the Fragment is paused or resumed.
 */
public class WebViewFragment extends Fragment {
    private WebView mWebView;
    private boolean mIsWebViewAvailable;

    public WebViewFragment() {
    }

    /**
     * Called to instantiate the view. Creates and returns the WebView.
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (mWebView != null) {
            mWebView.destroy();
        }
        mWebView = new WebView(getActivity());
        mIsWebViewAvailable = true;
        return mWebView;
    }

    /**
     * Called when the fragment is visible to the user and actively running. Resumes the WebView.
     */
    @Override
    public void onPause() {
        super.onPause();
        mWebView.onPause();
    }

    /**
     * Called when the fragment is no longer resumed. Pauses the WebView.
     */
    @Override
    public void onResume() {
        mWebView.onResume();
        super.onResume();
    }

    /**
     * Called when the WebView has been detached from the fragment.
     * The WebView is no longer available after this time.
     */
    @Override
    public void onDestroyView() {
        mIsWebViewAvailable = false;
        super.onDestroyView();
    }

    /**
     * Called when the fragment is no longer in use. Destroys the internal state of the WebView.
     */
    @Override
    public void onDestroy() {
        if (mWebView != null) {
            mWebView.destroy();
            mWebView = null;
        }
        super.onDestroy();
    }

    /**
     * Gets the WebView.
     */
    public WebView getWebView() {
        return mIsWebViewAvailable ? mWebView : null;
    }
}

展示頁面加載進(jìn)度

舊有的實(shí)現(xiàn)

參考Android: The progress bar in the window's title does not display文中的一種實(shí)現(xiàn)亡笑,然而看了下發(fā)布時(shí)間是2010.06。注意:那時(shí)候用的是Android 2.3横朋,BrowserActivity不是繼承自AppCompactActivity仑乌,使用的主題也不是AppCompact主題。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    requestWindowFeature(Window.FEATURE_PROGRESS);
    currentURL = BrowserActivity.this.getIntent().getExtras().getString("currentURL");

    setContentView(R.layout.browser);

    setProgressBarIndeterminateVisibility(true);
    setProgressBarVisibility(true);

    try {
        mWebView = (WebView) findViewById(R.id.webview);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setWebViewClient(new browserActivityClient());

        mWebView.setWebChromeClient(new WebChromeClient() {
           public void onProgressChanged(WebView view, int progress) {
               setProgress(progress * 100);
              if(progress == 100) {
                 setProgressBarIndeterminateVisibility(false);
                 setProgressBarVisibility(false);
              }
           }
        });
        mWebView.loadUrl(currentURL);
    } catch (Exception e) {
        Log.e(getClass().getSimpleName(), "Browser: " + e.getMessage());
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
    } 
}

自定義實(shí)現(xiàn)

  • 思路:在webView內(nèi)部或外部添加一個(gè)ProgressBar(水平樣式),并通過WebChromeClient獲知頁面的加載進(jìn)度晰甚,進(jìn)而調(diào)整ProgressBar的進(jìn)度衙传。
  • 實(shí)現(xiàn):

    WebChromeClient webChromeClient = new WebChromeClient() {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress == 100) {
                progressBar.setVisibility(View.GONE);
            } else {
                progressBar.setVisibility(View.VISIBLE);
                progressBar.setProgress(newProgress);
            }
        }
    };
    webView.setWebViewClient(webViewClient);
    

參考文檔

  1. H5 緩存機(jī)制淺析 移動(dòng)端 Web 加載性能優(yōu)化
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市厕九,隨后出現(xiàn)的幾起案子蓖捶,更是在濱河造成了極大的恐慌,老刑警劉巖扁远,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俊鱼,死亡現(xiàn)場離奇詭異,居然都是意外死亡畅买,警方通過查閱死者的電腦和手機(jī)并闲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谷羞,“玉大人帝火,你說我怎么就攤上這事∨榷校” “怎么了犀填?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雁歌。 經(jīng)常有香客問我宏浩,道長,這世上最難降的妖魔是什么靠瞎? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮求妹,結(jié)果婚禮上乏盐,老公的妹妹穿的比我還像新娘。我一直安慰自己制恍,他們只是感情好父能,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著净神,像睡著了一般何吝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鹃唯,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天爱榕,我揣著相機(jī)與錄音,去河邊找鬼坡慌。 笑死黔酥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播跪者,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼棵帽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了渣玲?” 一聲冷哼從身側(cè)響起逗概,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎忘衍,沒想到半個(gè)月后逾苫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淑履,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年隶垮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秘噪。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡狸吞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出指煎,到底是詐尸還是另有隱情蹋偏,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布至壤,位于F島的核電站威始,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏像街。R本人自食惡果不足惜黎棠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望镰绎。 院中可真熱鬧脓斩,春花似錦、人聲如沸畴栖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吗讶。三九已至燎猛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間照皆,已是汗流浹背重绷。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纵寝,地道東北人论寨。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓星立,卻偏偏與公主長得像,于是被迫代替她去往敵國和親葬凳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子绰垂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

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