Android WebView系列文章3 WebView其他使用说明

目录
1.通过webview控件下载文件
2.webview同步cookies
3.使用第三方WebView


1.通过webview控件下载文件
通常webview渲染的界面中含有可以下载文件的链接,点击该链接后,应该开始执行下载的操作并保存文件到本地中。webview来下载页面中的文件通常有两种方式:
1.自己通过一个线程写java io的代码来下载和保存文件(可控性好)
2.调用系统download的模块(代码简单)

方法一:
首先要写一个下载并保存文件的线程类
public class HttpThread extends Thread {
    private String mUrl;
    public HttpThread(String mUrl) {
        this.mUrl = mUrl;
    }

    @Override
    public void run() {
        URL url;
        try {
            url = new URL(mUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            InputStream in = conn.getInputStream();

            File downloadFile;
            File sdFile;
            FileOutputStream out = null;
            if(Environment.getExternalStorageState().equals(Environment.MEDIA_UNMOUNTED)){
                downloadFile = Environment.getExternalStorageDirectory();
                sdFile = new File(downloadFile, "test.file");
                out = new FileOutputStream(sdFile);
            }
            byte[] buffer = new byte[1024 * 4];
            int len = 0;
            while((len = in.read(buffer)) != -1){
                if(out != null)
                    out.write(buffer, 0, len);
            }
            if(out != null)
                out.close();

            if(in != null){
                in.close();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
随后要实现一个DownloadListener接口,这个接口实现方法OnDownloadStart(),当用户点击一个可以下载的链接时,该回调方法被调用同时传进来该链接的URL,随后即可以对该URL塞入HttpThread进行下载操作:
//创建DownloadListener (webkit包)
class MyDownloadListenter implements DownloadListener{
        @Override
        public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype, long contentLength) {
            System.out.println("url ==== >" + url);
            new HttpThread(url).start();
        }
}
//给webview加入监听
webview.setDownloadListener(new MyDownloadListenter());
方法二:
直接发送一个action_view的intent即可:
class MyDownloadListenter implements DownloadListener{
        @Override
        public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
            System.out.println("url ==== >" + url);
            Uri uri = Uri.parse(url);
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);
        }
}

2.webview同步cookies
cookies是服务器用来保存每个客户的常用信息的,下次客户进入一个诸如登陆的页面时服务器会检测cookie信息,如果通过则直接进入登陆后的页面。
在webview中,如果之前已经登陆过了,那么下次再进入同样的登陆界面时,若需要再次登陆的话,一定会很恼人,所以这里提供一个webview同步cookies的方法。
1.首先,我们假设某个网站的登陆界面需要提供两个参数,一个是name,一个是pwd,那么要是对这个页面进行登陆,那么必须给与这两个信息。我们假设服务器已经注册了name为jason,pwd为123456这个账号。
2.下面,写一个Thread用来将name和pwd自动的登入,在服务器返回的response中获得cookie信息,稍后对这个cookie进行保存,这里先给出这个Thread的代码:

public class HttpCookie extends Thread {

    private Handler mHandler;
    public HttpCookie(Handler mHandler) {
        this.mHandler = mHandler;
    }

    @Override
    public void run() {
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost("");//this place should add the login address

        List list = new ArrayList();
        list.add(new BasicNameValuePair("name", "jason"));
        list.add(new BasicNameValuePair("pwd", "123456"));

        try {
            post.setEntity(new UrlEncodedFormEntity(list));
            HttpResponse reponse = client.execute(post);
            if(reponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                AbstractHttpClient absClient = (AbstractHttpClient) client;
                List cookies = absClient.getCookieStore().getCookies();
                for(Cookie cookie:cookies){
                    if(cookie != null){
                        **//TODO**
**                        //this place would get the cookies**
                        Message msg = new Message();
                        msg.obj = cookie;
                        if(mHandler != null){
                            mHandler.sendMessage(msg);
                            return;
                        }
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private Handler mHandler = new Handler(){
        public void handleMessage(android.os.Message msg) {

            CookieSyncManager.createInstance(MainActivity.this);
            CookieManager cookieMgr = CookieManager.getInstance();
            cookieMgr.setAcceptCookie(true);
            cookieMgr.setCookie("", msg.obj.toString());// this place should add the login host address(not the login index address)
            CookieSyncManager.getInstance().sync();

            webview.loadUrl("");// login index address
        };
};

这个时候发现webview加载的login index页面中可以自动的登陆了并显示登陆后的界面。

3.使用第三方WebView
一.为何不直接使用内置的WebView组件?

用Android自带的WebView组件,做过一些较复杂应用的人应该都会发现,这个自带的组件很多时候真是让人无力吐嘈,主要理由有二:
Android中的WebView组件,内存泄漏的问题一直没有非常有效的解决方案,让程序猿们痛不欲生。
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的浏览服务,我认为未尝不是一种好的解决方案。

三.这里推荐大家可以参考TBS提供的官方示例,如果嫌麻烦的话,可以简单参考我下面的示例。
第一步,下载jar包,并加载到项目中,下载地址 TBS——SDK下载 。
第二步,在xml布局中加入腾讯自定义的WebView。


第三步,申请腾讯X5所需权限。






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

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);
    }
}

四.如何判断已经成功接入了腾讯的X5内核浏览服务呢?辨别是否使用x5webview的方法:

Image.png

后续:
平时喜欢写写文章,笔记。别人建议我把笔记,以前写的东西整理,然后写成博客,所以我会陆续整理文章,只发自己写的东西,敬请期待:
知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts
领英:https://www.linkedin.com/in/chong-yang-049216146/
:http://www.jianshu.com/u/b7b2c6ed9284
csdn:http://my.csdn.net/m0_37700275
网易博客:http://yangchong211.blog.163.com/
新浪博客:http://blog.sina.com.cn/786041010yc
github:https://github.com/yangchong211
喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/
脉脉:yc930211

你可能感兴趣的:(Android WebView系列文章3 WebView其他使用说明)