還在用Android自帶的WebView組件?太Out了!

weiwo11 8年前發布 | 553K 次閱讀 安卓開發 Android開發 移動開發

由于公司的一個產品,可能需要在APK內部內嵌WebView,以顯示HTML內容,因此花了一點時間做了一些技術方面的小嘗試。本文主要針對這個過程做一些簡單的記錄。

一、為何不直接使用內置的WebView組件?

用Android自帶的WebView組件,做過一些較復雜應用的人應該都會發現,這個自帶的組件很多時候真是讓人無力吐嘈,主要理由有二:

  1. Android中的WebView組件,內存泄漏的問題一直沒有非常有效的解決方案,讓程序猿們痛不欲生。
  2. Android中的WebView組件,在4.4以前的版本是WebKit的內核,4.4以后才換成chromium的內核,同時鑒于Google版本帝的風格,因此也導致各個版本之間的運行效率參差不齊。而且即使是chromium內核的版本,也因為要考慮兼容以前的版本,而變得不是那么美好。

也正因為如此,考慮到為了更好的體驗,以及避免后續可能帶來的更多麻煩,所以我試圖站在巨人的肩膀上,尋找一個第三方可靠的WebView組件。

二、Crosswalk與TBS服務

Crosswalk:據說各種流暢、強大,且Cordova在新的版本當中也將默認支持Crosswalk。具體的介紹可以參考: 如何輕松搞定Crosswalk之嵌入模式

TBS服務:由騰訊QQ瀏覽器團隊出品。支持“共享X5內核模式”和“獨立下載X5內核模式”。具體可參考 TBS騰訊瀏覽服務

在結合我的實際需求,綜合比較了上述兩套解決方案之后,最終我還是選擇了TBS服務,一是因為我不希望最終的APP體積突然增多了20M(Crosswalk需要整體打包進APP),另一方面是小馬哥的微信、手機QQ等APP在國內的裝機量實在是太高了,而且能夠支持以共享X5內核的方式,在自己的APP里面直接調用微信或手機QQ的瀏覽服務,我認為未嘗不是一種好的解決方案。

三、最終實現

好吧,必須承認我很久沒有碰過Android了,所以因為一時的心血來潮,我選擇了Google主推的Android Studio來體驗,而不是以前習慣的Eclipse。這一下,就給自己找了個大麻煩,說多了都是淚……也只能自我安慰,我這是跟著時代與時俱進的成長了……

首先要說明的,Android Studio采用的是Gradle來構建項目,因此每一個項目都需要在國外的官網上下載對應版本的Gradle,由于眾所周知的原因,這個過程那真是相當之漫長。最可悲的是我一開始不知道,苦苦守候了半個多小時,界面一直卡在這一步,如下圖所示:

1.png

解決的方法很簡單,網上也有很多,例如換V*N、代理之類的,我采用了最簡單粗暴的方式。根據Android Studio的運行原理,每一個新建的項目,都會在C:\Users\Administrator.gradle\wrapper\dists\gradle-2.2.1-all目錄下創建一個加碼的文件夾,如下圖所示:

2.png

找到時間最接近的這個文件夾,然后將適先下載好的、對應版本的gradle文件放里面、并解壓,最終效果如下圖所示:

3.png

最后強制結束Android Studio并重啟,恭喜你,不出意外的話,這個時候項目文件就可以順利并加載了!呃……如果要是出了意外的話,那……就只好繼續Google了……(別告訴我你不會KX上網~)

解決了上述問題之后,我們就可以正式開始進入編碼階段了。這里推薦大家可以參考TBS提供的官方示例,如果嫌麻煩的話,可以簡單參考我下面的示例。

第一步,下載jar包,并加載到項目中,下載地址 TBS——SDK下載

第二步,在xml布局中加入騰訊自定義的WebView。

<com.tencent.smtt.sdk.WebView  
    android:id="@+id/tbsContent"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"/>

第三步,申請騰訊X5所需權限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

第四步,在Activity代碼文件中使用:

package net.ltpower.tbsapp;

import android.graphics.PixelFormat;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;


public class MainActivity extends ActionBarActivity {

    com.tencent.smtt.sdk.WebView tbsContent;
    private String url = "http://www.91suke.com/s/b9271044";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        initView();
    }

    private void initView() {
        tbsContent = (com.tencent.smtt.sdk.WebView)findViewById(R.id.tbsContent);
        tbsContent.loadUrl(url);
        WebSettings webSettings = tbsContent.getSettings();
        webSettings.setJavaScriptEnabled(true);
        tbsContent.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
    }

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

好了,到這一步,連接真機,運行你的Android程序,應該就可以看到如下效果了:

4.png

那么最關鍵的問題是,如何判斷已經成功接入了騰訊的X5內核瀏覽服務呢?辨別是否使用x5webview的方法:

顯示網頁文字時,可通過長按選擇文字的標識判斷,如下水滴狀選擇效果是x5webview 的標志:

當然,上述的代碼僅僅只是一個簡單的測試案例,實際的生產使用環境中還有很多需要考慮的地方,例如APP切換到后臺運行的資源的釋放等等。具體的實現方式,建議大家可以參考TBS官方的示例。

 

來自:http://www.jianshu.com/p/d3ef9c62b6c8

 

 本文由用戶 weiwo11 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!