mui開發app之webview是什么


WebView(網絡視圖)能加載顯示網頁,可以將其視為一個瀏覽器。

在Android手機中,網頁的解析和顯示網頁的能力是由webkit內核實現的。

(如chrome瀏覽器使用的是webkit內核,現在,webkit被內置到了android系統中)

webview對網頁處理也是交給強大的webkit做的

 

webview在android SDK(原生)中:

封裝為一個叫做WebView組件,通過這個組件可以在app中顯示html+css+js,當然也就可以顯示一個遠程url,比如用它打開百度首頁是可以的。

可以理解為:android開發中的一個activity里使用了webview組件,並打開了一個html頁面呈現給用戶。

其中“activity”是android原生開發時的“一張頁面”,app的所謂跳轉到不同“頁”是在activity中跳來跳去,activity是java的一個類,布局則是使用xml(如果沒做過原生android開發就這么理解就行)

 

webview在mui app框架開發中:

在mui開發中,這些webview就是一張一張的網頁。

這些網頁是webview對象,其操作方法被封裝在html5+的plus.webview對象中

webview本身只是個瀏覽器效果組件,切換即使網頁之間的跳轉,理論上不可能像原生的activity中切換一樣流暢,本身也不會有什么動畫。

還好,mui的開發組,dcloud(數字天堂)和他們的html5+中國產業聯盟(社區)實現了webview切換的動畫效果,他們把這些webview映射到了真正的java webview,調用的也是原生的activity切換動畫,從而使得webview切換也可以像原生app activity一樣切換的效果!

 

關於dcloud的html5+和native.js技術請看我另一篇博客: http://www.cnblogs.com/devilyouwei/p/6793609.html

關於原生android webview這個組件使用的博客:http://www.jianshu.com/p/d2f5ae6b4927

 


簡約圖:

 

 

原生開發和mui的hybrid模式區別圖:

 

先來談談我對mui的webview的理解:

使用mui開發的app,其實是在做web前端開發,打開的webview是網頁,用js+html+css替代了原來的xml+java activity的傳統android開發模式,h5最終性能相對原生一定是降低了很多(主要原因不在webkit的解析速度,而是最終所有的ui和業務邏輯還是會轉化為android sdk交由java去實現,google可沒有直接提供android的js開發接口,mui的dcloud則是采用了native.js來提供js開發接口(js映射為原生代碼)

我們按照傳統網頁的方式去理解:

app理解為瀏覽器,將webview理解為瀏覽器下不同標簽tab,每一個tab也是一個不同的頁面,瀏覽器瀏覽可以在tab之中切換,以此來實現app不同webview(頁面)的切換

 

場景一:

在mainfest.json中我們配置的首頁,比如login.html,然后我們啟動app,login.html將會第一個呈現在我們屏幕上,這就是第一個tab標簽(稱之為launchWebView),如果此時我們關閉這個tab,那么瀏覽器沒有其他tab將會關閉。

app也是一個道理,只有一個webView的情況下(假設就是launchWebView,首頁),將會退出,可以在首頁login.html使用plus.webview.getLaunchWebView().close()測試,app將會直接退出!

(在原生的android開發中,如果只有一個activity的時候關閉當前activity也會退出app,其實webview之於html5 app,相較於,activity之於android app,邏輯處理十分相似^_^)

 

場景二:

瀏覽器已經有了首頁的tab,我們新建更多tab,瀏覽更多頁面,並且跳轉到這些新tab下

這就像使用mui.openWindow()方法打開新的webview,該方法傳入一些參數,如下官方說法:

mui.openWindow({
    url:new-page-url,
    id:new-page-id,
    styles:{
      top:newpage-top-position,//新頁面頂部位置
      bottom:newage-bottom-position,//新頁面底部位置
      width:newpage-width,//新頁面寬度,默認為100%
      height:newpage-height,//新頁面高度,默認為100%
      ......
    },
    extras:{
      .....//自定義擴展參數,可以用來處理頁面間傳值
    },
    createNew:false,//是否重復創建同樣id的webview,默認為false:不重復創建,直接顯示
    show:{
      autoShow:true,//頁面loaded事件發生后自動顯示,默認為true
      aniShow:animationType,//頁面顯示動畫,默認為”slide-in-right“;
      duration:animationTime//頁面動畫持續時間,Android平台默認100毫秒,iOS平台默認200毫秒;
    },
    waiting:{
      autoShow:true,//自動顯示等待框,默認為true
      title:'正在加載...',//等待對話框上顯示的提示內容
      options:{
        width:waiting-dialog-widht,//等待框背景區域寬度,默認根據內容自動計算合適寬度
        height:waiting-dialog-height,//等待框背景區域高度,默認根據內容自動計算合適高度
        ......
      }
    }
})

openWindow打開了一個新的webView並且跳轉到了新的webView,就像瀏覽器新建一個tab並且切換過去,只不過切換過程帶了參數,實現了動畫(這由native.js交給了原生動畫實現的),傳遞頁面參數,這也是比瀏覽器訪問網頁的強大之處

openWindow遇到已經打開過並且id仍然在緩存中的webview(這些webview通常是被hide()掉的),會直接跳轉過去,相當於getWebviewById().show()

openWindow有兩個核心參數,一個是url表示打開的html文件,打開tab也得知道網頁地址對吧?還一個是id,這個參數相當於句柄,以后尋找這個webview就靠它了,使用getWebviewById()方法抓到這個webview並進行操作!

請注意:openWindow下有一個特殊的參數:createNew

如果它為false,使用openWindow打開新窗口的時候,會先判斷是不是有一樣id的webview,如果有,直接跳過去,沒有的話,就新建一個窗口再跳過去!

如果它是true,使用openWindow打開新窗口的時候,不管有沒有相同id的tab,都回去新創建一個,也就是可能會創建重復ID的webview,這是很蛋疼的,因為會造成app跳轉webview時,與預期效果不同(跳轉的webview不是自己想要的),或者getWebviewById()返回的不是自己想要的webview對象,造成誤操作。

請盡量不要使用createNew,除非特殊的頁面需要創建重復的多個。

注:我遇到過創建了重復的webview后造成的自定義觸發事件(fire)發生了意想不到的結果,在返回前,對返回頁面的dom進行修改刷新,但dom並沒有被改變,其實是因為重復webview,修改了別的!

 

場景三:

我要關閉一個頁面!

方法一:隱藏掉(非真關閉),這樣會暫時從當前webview切出去,返回上一個webview,但是這樣不會清除這個webview,webview依然保存在緩存中。

此種方法用於不需要反復刷新創建的頁面,打開一次后長時間駐留在內存中的webview,使用plus.webview.getWebviewById().hide()隱藏,同理使用show()方法再次喚出這個webview

此種方法打開webview下的html是不會重新執行一遍JS,也不會再次渲染CSS了。一般采用自定義事件監聽,然后觸發相應的JS。

 

方法二:觸發mui.back()或返回事件,這里注意了back並不會像瀏覽器那樣history.go(-1)返回上一頁,而是相當於瀏覽器直接關閉當前tab!

就是說mui.back()將會關閉當前的webview后返回上一個webview,此時我們如果使用plus.webview.getWebviewById()獲取那個被返回的webview已經是查找不到,因為webview被關閉了,緩存也消失了。

下一次打開需要重新加載整個html頁面,重新執行一遍JS代碼,重新渲染一次CSS布局

 

方法三:不要返回,而要關閉指定的一個webview,那使用plus.webview.getWebviewById().close()即可,這是不帶返回效果的關閉某個頁面。

比如關閉當前的頁面,plus.webview.currentWebview().close(),這個方法的效果會和mui.back()一樣。

 

方法四:直接清理掉,清理掉的話將會導致頁面跳轉不產生動畫或者顯示加載中,因為頁面將被認為從未打開過,使用:plus.webview.getWebviewById().clear()

 

終極關閉大法:假設我設置的主頁是login.html,現在我的用戶退出了登陸,那么我要清空他已經打開的所有webview,不留使用痕跡,使用如下代碼:

    toLogin = function() {
        var all = plus.webview.all();
        var launch = plus.webview.getLaunchWebview() //基座,不可以關掉
        for(var i = 0; i < all.length; i++) {
            if(all[i] === launch)
                continue;
            all[i].close();
            all[i].clear();
        }
        //立刻退出
        setTimeout(function() {
            launch.show();  //不要重新打開login,app的基座就是login頁面,直接show出來就行了
        }, 0);
    }

其中不能粗魯的把所有的webview統統關閉並清空,那將會導致app直接關閉,只要僅剩的最后一個webview被關閉,也就默認app退出,應保留基座:launchWebView(就是首頁)!

 

場景四:

打開已經打開過並且沒有被close或者clear的webview:

使用:plus.webview.getWebviewById().show()

使用:plus.webview.getWebviewById().hide()  //隱藏掉

注意:被關閉(close)和清空(clear),返回掉(back)的webview將會返回null,不可以操作!並且每次重新openWindow打開的時候都會重新加載頁面,執行一遍頁面的JS代碼

 

總結一下webview!

mui提供的plus對象封裝了對webview的操作,hbuilder中輸入plus.webview即可獲取對象下面的變量

下面有三個get方法獲取webview:

分別獲取:基座(就是首頁),當前頂部頁面(其實就是當前顯示的),根據id獲得webview

返回的是WebViewObject,這個object下面有:

等等的方法,自行在hbuilder中查看吧!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM