0x00. 為何不直接使用內(nèi)置的WebView組件算撮?
Android中的WebView組件,在4.4以前的版本是WebKit的內(nèi)核,4.4以后才換成chromium的內(nèi)核。而且不同版本之間運(yùn)行的效率也參差不齊贴硫,適配問(wèn)題很讓人頭疼。因此考慮用第三方webview是個(gè)不錯(cuò)的選擇伊者。
0x01英遭、有哪些第三方WebView可供選擇呢?
方案1:Crosswalk
Home · crosswalk-project/crosswalk-website Wiki · GitHub
優(yōu)點(diǎn):各種流暢亦渗、強(qiáng)大挖诸,靜態(tài)集成
缺點(diǎn):體積過(guò)大,打包后的APK要48M左右法精,這個(gè)問(wèn)題有點(diǎn)致命
解決思路:使用Crosswalk的精簡(jiǎn)版 crosswalk-lite(此版本不是官方主推多律,更新也不頻繁)
Crosswalk Lite
可以看到,體積確實(shí)小了很多搂蜓,但是狼荞,請(qǐng)注意這段話:
Lite僅支持x86和ARM的32位版本。 尚不支持x86_64和ARM64帮碰。所以粘秆,如果想適配64位的Android機(jī),此方案只能舍棄收毫。
接下來(lái)我們?cè)倏纯捶桨?
方案2:騰訊TBS X5內(nèi)核webview
優(yōu)點(diǎn):體積小攻走,可以動(dòng)態(tài)集成,靜態(tài)集成此再,而且APP接入TBS后可以共享使用微信昔搂,或者手機(jī)QQ,QQ瀏覽器的X5內(nèi)核
缺點(diǎn):首次安裝APP后第一次啟動(dòng)時(shí)X5內(nèi)核總是加載失斒淠础(手機(jī)中已經(jīng)安裝了微信和QQ也不行摘符,直接運(yùn)行官網(wǎng)的demo也是首次加載失敗)策吠,kill掉程序后再次啟動(dòng)就好了(這個(gè)問(wèn)題有人已經(jīng)在官網(wǎng)反饋了逛裤,但是官方?jīng)]有給出解決方案)
集成可以動(dòng)態(tài)集成(啟動(dòng)APP后再開(kāi)始下載X5內(nèi)核)和靜態(tài)集成(X5內(nèi)核一起打包進(jìn)APK,不需再次下載)
0x02. 動(dòng)態(tài)集成TBS(studio)
A. 獲取TBS
去官網(wǎng)下載TBS的SDK文件猴抹,選擇第一個(gè)(完整版)即可带族,目前是v3.6.0.1315版本,下載后解壓文件如下:
其中蟀给,studio版的demo是module, 不能直接運(yùn)行蝙砌,如果想跑起來(lái),需要以module添加進(jìn)某個(gè)項(xiàng)目中再運(yùn)行這個(gè)module
B. 新建項(xiàng)目
新建一個(gè)studio的空項(xiàng)目跋理,把解壓SDK后的jar包文件放在libs目錄下择克,并導(dǎo)入,如圖:
C. 集成TBS
把 SDK接入示例-Android Studio.zip 解壓前普,把main目錄下的jniLibs文件夾整個(gè)復(fù)制到自己的項(xiàng)目的main目錄下肚邢,如圖:
x5暫時(shí)不提供64位so文件,為了保證64位手機(jī)能正常加載x5內(nèi)核拭卿,需如下配置:
1)打開(kāi)app的build.gradle骡湖,在defaultConfig標(biāo)簽內(nèi)加入
ndk{abiFilters"armeabi","armeabi-v7a","x86","mips"}
完整如下:
defaultConfig {
applicationId "your applicationId"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk{abiFilters "armeabi", "armeabi-v7a", "x86", "mips"}
}
2)如果配置后編譯報(bào)錯(cuò),打開(kāi)項(xiàng)目的gradle.properties文件记劈,在最后加上
android.useDeprecatedNdk=true
至此勺鸦,動(dòng)態(tài)集成TBS X5內(nèi)核webview介紹完畢,總結(jié)一下動(dòng)態(tài)集成的特點(diǎn)目木,就是先集成换途,后加載(當(dāng)手機(jī)中沒(méi)有X5內(nèi)核時(shí)TBS底層會(huì)自動(dòng)下載X5內(nèi)核)」羯洌可是军拟,如果用戶第一次安裝就沒(méi)有網(wǎng)絡(luò),手機(jī)中也沒(méi)有X5內(nèi)核誓禁,這種場(chǎng)景怎么辦呢懈息?總不能用系統(tǒng)的webview吧,如果那樣摹恰,很多功能將不可使用辫继。所以怒见,接下來(lái)介紹一下靜態(tài)集成,集成完成后不需任何網(wǎng)絡(luò)就可以使用
0x03. 靜態(tài)集成TBS(studio)
動(dòng)態(tài)集成和靜態(tài)集成大同小異姑宽,具體步驟:
1:打開(kāi)連接后遣耍,下載壓縮包,解壓后炮车,是如下文件:
2:和動(dòng)態(tài)集成一樣舵变,把jar包放在項(xiàng)目的libs目錄下面,導(dǎo)入
3:把a(bǔ)pk文件的后綴改為zip, 然后解壓瘦穆,得到多個(gè)so包纪隙,像動(dòng)態(tài)集成一樣,把jniLibs文件夾粘貼到main目錄下, 把jniLibs里面的armeabi文件夾清空扛或,把剛才解壓APK文件得到的所有so包放在armeabi文件夾中绵咱。其實(shí)整個(gè)過(guò)程就是把動(dòng)態(tài)集成中缺少的so包添加到項(xiàng)目中,這樣就不需要再下載了告喊。
至此麸拄,靜態(tài)集成TBS完畢。下面我們?cè)賮?lái)介紹一下用法(兩種集成方式使用基本相同黔姜,只有預(yù)加載X5內(nèi)核的代碼不同)
0x04. 使用WebView(studio)
A. 添加權(quán)限
打開(kāi)app的清單文件AndroidManifest.xml拢切,添加權(quán)限(從官方demo中復(fù)制即可) 如下:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- 硬件加速對(duì)X5視頻播放非常重要,建議開(kāi)啟 -->
<uses-permission android:name="android.permission.GET_TASKS"/>
B. 加載X5內(nèi)核
這一步驟靜態(tài)集成和動(dòng)態(tài)集成代碼不同秆吵,咱們分開(kāi)介紹
1)動(dòng)態(tài)集成的X5內(nèi)核加載代碼:
因?yàn)樵诖蜷_(kāi)webview之前要加載X5內(nèi)核淮椰,此過(guò)程比較耗時(shí),雖然是異步的纳寂,但是如果沒(méi)有加載完成或者沒(méi)有加載成功主穗,打開(kāi)的webview將是Android原生的控件,而不是X5內(nèi)核的WebView毙芜,所以這個(gè)動(dòng)作越早做越好忽媒,因此官方建議自定義application, 在onCreate方法中調(diào)用QbSdk.initX5Environment()來(lái)預(yù)加載X5內(nèi)核,該方法需要傳遞2個(gè)參數(shù)腋粥,第一個(gè)參數(shù)是context晦雨,第二個(gè)參數(shù)是實(shí)現(xiàn)QbSdk.PreInitCallback接口的實(shí)例,此接口是X5內(nèi)核初始化的回調(diào)接口隘冲,有兩個(gè)抽象方法闹瞧,onCoreInitFinished()和 onViewInitFinished(boolean var1),其中展辞,onCoreInitFinished()回調(diào)方法表示X5內(nèi)核初始化完成(注意奥邮,不保證一定成功),onViewInitFinished(boolean var1) 回調(diào)方法回傳的參數(shù)如果為true,表示X5內(nèi)核加載成功洽腺,否則X5內(nèi)核加載失敗脚粟。如下:
public class APPAplication extends Application {
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
@Override
public void onViewInitFinished(boolean arg0) {
// TODO Auto-generated method stub
//x5內(nèi)核初始化完成的回調(diào),為true表示x5內(nèi)核加載成功蘸朋,否則表示x5內(nèi)核加載失敗珊楼,會(huì)自動(dòng)切換到系統(tǒng)內(nèi)核。
Log.d("app", " onViewInitFinished is " + arg0);
}
@Override
public void onCoreInitFinished() {
// TODO Auto-generated method stub
}
};
//x5內(nèi)核初始化接口
QbSdk.initX5Environment(getApplicationContext(), cb);
}
}
2)靜態(tài)集成的X5內(nèi)核加載代碼:
在加載X5內(nèi)核時(shí)(即application的onCreate方法里)度液,不再調(diào)用QbSdk.initX5Environment()方法,而是調(diào)用QbSdk.preinstallStaticTbs(getApplicationContext());方法画舌,而且要在異步線程中執(zhí)行堕担。
public class LemageApplication extends Application {
public static boolean x5Init;
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
@Override
public void run() {
QbSdk.preinstallStaticTbs(getApplicationContext());
}
}).start();
}
}
最后,無(wú)論是動(dòng)態(tài)集成還是靜態(tài)集成曲聂,只要自定義了application, 別忘了在AndroidManifest.xml文件中更改名字 霹购,同時(shí),如果需要硬件加速的話朋腋,也要加上
android:hardwareAccelerated="true"
如下代碼:
<application
android:name="your applicationId"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:hardwareAccelerated="true"
android:theme="@style/AppTheme">
至此齐疙,就可以在項(xiàng)目中使用x5內(nèi)核的webview了。如果是想通過(guò)x5來(lái)播放視頻旭咽,那么請(qǐng)繼續(xù)往下看:
0x05. 播放視頻(studio)
如果需要webview播放視頻贞奋,那么有兩種方式,第一種穷绵,參考官方demo的FullScreenActivity類轿塔,此類中有一個(gè)webview加載的是本地的html,在html中通過(guò)標(biāo)簽來(lái)播放網(wǎng)絡(luò)視頻仲墨,可以調(diào)節(jié)屏幕大小勾缭,可以根據(jù)自己的需求靈活控制。第二種先要在AndroidManifest.xml中聲明一個(gè)VideoActivity類目养,如下:
<!--視頻播放界面-->
<activity
android:name="com.tencent.smtt.sdk.VideoActivity"
android:alwaysRetainTaskState="true"
android:configChanges="orientation|screenSize|keyboardHidden"
android:exported="false"
android:launchMode="singleTask">
<intent-filter>
<action android:name="com.tencent.smtt.tbs.video.PLAY"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
然后想播放視頻時(shí)俩由,可以在自己的activity中直接調(diào)用TbsVideo.openVideo()方法,該方法需要傳遞兩個(gè)參數(shù)癌蚁,第一個(gè)是context, 第二個(gè)是播放視頻的路徑. 需要注意的是幻梯,在調(diào)用TbsVideo.openVideo()方法前,需要判斷一下視頻播放器是否初始化完成匈勋,代碼如下:
private void startVideo() {
if ((TbsVideo.canUseTbsPlayer(this))) {
//可以播放視頻
TbsVideo.openVideo(this, urlTest);
} else {
Toast.makeText(this, "視頻播放器沒(méi)有準(zhǔn)備好", Toast.LENGTH_SHORT).show();
}
}
0x06. 使用office(studio)
X5內(nèi)核的一大特色就是可以在手機(jī)不安裝office的情況下礼旅,可以只需下載插件即可瀏覽office文檔(下載插件的過(guò)程由TBS內(nèi)部控制),應(yīng)用層只需調(diào)用API即可洽洁。下面以瀏覽PDF文件舉例:(注:X5內(nèi)核不能瀏覽遠(yuǎn)程office痘系,只能先下載到本地再瀏覽)
A. TbsReaderView
顯示瀏覽PDF效果的控件不是webview,而是TbsReaderView饿自,而且汰翠,TbsReaderView不能在XML中布局龄坪,必須要代碼動(dòng)態(tài)布局,否則報(bào)錯(cuò)复唤。通過(guò)查看TbsReaderView的源代碼發(fā)現(xiàn)健田,它只有一個(gè)構(gòu)造方法,需要兩個(gè)參數(shù)佛纫,第一個(gè)參數(shù)是context, 第二個(gè)參數(shù)是TbsReaderView.ReaderCallback妓局,也就是說(shuō),如果在xml中布局呈宇,那么構(gòu)造方法不會(huì)讀取XML中的屬性好爬,所以只能代碼生成實(shí)例后添加進(jìn)父控件中顯示。
B. 調(diào)用
private void displayFile() {
Bundle bundle = new Bundle();
//傳遞文件路徑
bundle.putString("filePath", url);
//加載插件保存的路徑
bundle.putString("tempPath", Environment.getExternalStorageDirectory().getPath());
boolean result = mTbsReaderView.preOpen(parseFormat("測(cè)試XLSX.xlsx"), false);
if (result) {
mTbsReaderView.openFile(bundle);
}
}
首先甥啄,創(chuàng)建一個(gè)Bundle對(duì)象存炮,然后,分別put目標(biāo)office文件的本地路徑蜈漓,和pdf插件保存的路徑穆桂,然后把bundle對(duì)象作為參數(shù)傳遞給TbsReaderView就可以了。
至此融虽,TBS X5內(nèi)核webview集成和基礎(chǔ)使用全部介紹完畢享完,對(duì)比如下:
動(dòng)態(tài)集成:體積小,所以啟動(dòng)程序后如果沒(méi)有X5內(nèi)核會(huì)自動(dòng)下載
靜態(tài)集成:體積大衣形,但是不需要下載驼侠,使用戶在沒(méi)有網(wǎng)的情況下也可以使用
*** ******注意:
網(wǎng)上有很多文章說(shuō)是無(wú)論是靜態(tài)還是動(dòng)態(tài)集成,有的機(jī)型首次安裝APP時(shí)加載X5內(nèi)核都失敗谆吴,必須要kill掉程序后再次啟動(dòng)才能加載成功倒源。這個(gè)問(wèn)題我自己也遇到過(guò)。其實(shí)產(chǎn)生這個(gè)問(wèn)題的原因是X5內(nèi)核還沒(méi)有加載完成就加載WebView句狼,此時(shí)的WebView是原生的WebView笋熬,而不是X5內(nèi)核的,此時(shí)如果不kill掉程序腻菇,哪怕X5內(nèi)核加載完成也改變不了這個(gè)WebView的內(nèi)核了胳螟。所以會(huì)造成這個(gè)問(wèn)題。解決的辦法就是想辦法在X5內(nèi)核加載完成之前不加載com.tencent.smtt.sdk.WebView就可以了筹吐,等X5內(nèi)核加載成功后再加載com.tencent.smtt.sdk.WebView糖耸。如果在X5內(nèi)核加載成功之前一定要用WebView,可以先用原生的代替丘薛。這樣哪怕是首次安裝APP也可以不用kill掉程序就可以用X5內(nèi)核了嘉竟。
但是,還有一個(gè)問(wèn)題,官網(wǎng)說(shuō)是X5內(nèi)核共享舍扰,但是手機(jī)中明明安裝了微信倦蚪,QQ,可是首次安裝為什么還需要加載X5內(nèi)核边苹?如果有知道的同仁請(qǐng)告知一下陵且,感謝。