还在用Android自带的WebView组件?太Out了!

weiwo11 8年前
   <p>由于公司的一个产品,可能需要在APK内部内嵌WebView,以显示HTML内容,因此花了一点时间做了一些技术方面的小尝试。本文主要针对这个过程做一些简单的记录。</p>    <h2>一、为何不直接使用内置的WebView组件?</h2>    <p>用Android自带的WebView组件,做过一些较复杂应用的人应该都会发现,这个自带的组件很多时候真是让人无力吐嘈,主要理由有二:</p>    <ol>     <li>Android中的WebView组件,内存泄漏的问题一直没有非常有效的解决方案,让程序猿们痛不欲生。</li>     <li>Android中的WebView组件,在4.4以前的版本是WebKit的内核,4.4以后才换成chromium的内核,同时鉴于Google版本帝的风格,因此也导致各个版本之间的运行效率参差不齐。而且即使是chromium内核的版本,也因为要考虑兼容以前的版本,而变得不是那么美好。</li>    </ol>    <p>也正因为如此,考虑到为了更好的体验,以及避免后续可能带来的更多麻烦,所以我试图站在巨人的肩膀上,寻找一个第三方可靠的WebView组件。</p>    <h2>二、Crosswalk与TBS服务</h2>    <p>Crosswalk:据说各种流畅、强大,且Cordova在新的版本当中也将默认支持Crosswalk。具体的介绍可以参考: <a href="/misc/goto?guid=4959677372028608600" rel="nofollow,noindex"> <strong> <em>如何轻松搞定Crosswalk之嵌入模式</em> </strong> </a></p>    <p>TBS服务:由腾讯QQ浏览器团队出品。支持“共享X5内核模式”和“独立下载X5内核模式”。具体可参考 <a href="/misc/goto?guid=4959677372118986035" rel="nofollow,noindex"> <strong> <em>TBS腾讯浏览服务</em> </strong> </a></p>    <p>在结合我的实际需求,综合比较了上述两套解决方案之后,最终我还是选择了TBS服务,一是因为我不希望最终的APP体积突然增多了20M(Crosswalk需要整体打包进APP),另一方面是小马哥的微信、手机QQ等APP在国内的装机量实在是太高了,而且能够支持以共享X5内核的方式,在自己的APP里面直接调用微信或手机QQ的浏览服务,我认为未尝不是一种好的解决方案。</p>    <h2>三、最终实现</h2>    <p>好吧,必须承认我很久没有碰过Android了,所以因为一时的心血来潮,我选择了Google主推的Android Studio来体验,而不是以前习惯的Eclipse。这一下,就给自己找了个大麻烦,说多了都是泪……也只能自我安慰,我这是跟着时代与时俱进的成长了……</p>    <p>首先要说明的,Android Studio采用的是Gradle来构建项目,因此每一个项目都需要在国外的官网上下载对应版本的Gradle,由于众所周知的原因,这个过程那真是相当之漫长。最可悲的是我一开始不知道,苦苦守候了半个多小时,界面一直卡在这一步,如下图所示:</p>    <p><img src="https://simg.open-open.com/show/670e1d8e9d15f1878cad105257e23f7e.png"></p>    <p>1.png</p>    <p>解决的方法很简单,网上也有很多,例如换V*N、代理之类的,我采用了最简单粗暴的方式。根据Android Studio的运行原理,每一个新建的项目,都会在C:\Users\Administrator.gradle\wrapper\dists\gradle-2.2.1-all目录下创建一个加码的文件夹,如下图所示:</p>    <p><img src="https://simg.open-open.com/show/da41f8e3a664199f345d6461130e6931.png"></p>    <p>2.png</p>    <p>找到时间最接近的这个文件夹,然后将适先下载好的、对应版本的gradle文件放里面、并解压,最终效果如下图所示:</p>    <p><img src="https://simg.open-open.com/show/88a55e96335586153007ee772911e20e.png"></p>    <p>3.png</p>    <p>最后强制结束Android Studio并重启,恭喜你,不出意外的话,这个时候项目文件就可以顺利并加载了!呃……如果要是出了意外的话,那……就只好继续Google了……(别告诉我你不会KX上网~)</p>    <p>解决了上述问题之后,我们就可以正式开始进入编码阶段了。这里推荐大家可以参考TBS提供的官方示例,如果嫌麻烦的话,可以简单参考我下面的示例。</p>    <p>第一步,下载jar包,并加载到项目中,下载地址 <a href="/misc/goto?guid=4959677372210583483" rel="nofollow,noindex"> <strong> <em>TBS——SDK下载</em> </strong> </a> 。</p>    <p>第二步,在xml布局中加入腾讯自定义的WebView。</p>    <pre>  <code class="language-java"><com.tencent.smtt.sdk.WebView        android:id="@+id/tbsContent"        android:layout_width="match_parent"        android:layout_height="match_parent"/></code></pre>    <p>第三步,申请腾讯X5所需权限。</p>    <pre>  <code class="language-java"><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" /></code></pre>    <p>第四步,在Activity代码文件中使用:</p>    <pre>  <code class="language-java">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);      }  }</code></pre>    <p>好了,到这一步,连接真机,运行你的Android程序,应该就可以看到如下效果了:</p>    <p><img src="https://simg.open-open.com/show/0c1ef3f063fdb5e58c83a0ed21321da6.png"></p>    <p>4.png</p>    <p>那么最关键的问题是,如何判断已经成功接入了腾讯的X5内核浏览服务呢?辨别是否使用x5webview的方法:</p>    <p><em>显示网页文字时,可通过长按选择文字的标识判断,如下水滴状选择效果是x5webview 的标志:</em></p>    <p><img src="https://simg.open-open.com/show/57b74a6ab8da6579d2f23814a3b0ac04.jpg"></p>    <p>当然,上述的代码仅仅只是一个简单的测试案例,实际的生产使用环境中还有很多需要考虑的地方,例如APP切换到后台运行的资源的释放等等。具体的实现方式,建议大家可以参考TBS官方的示例。</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/d3ef9c62b6c8</p>    <p> </p>