安卓APP承载网页(WebView)

安卓APP自身如何打开网页,如何制作一个简单的浏览器,WebView在其中将是一个重要的角色。WebView是一个基于WebKit引擎、展现Web页面的控件。

Webview 是一个基于webkit引擎,可以解析DOM 元素,展示html页面的控件,它和浏览器展示页面的原理是相同的,所以可以把它当做浏览器看待。(chrome浏览器也是基于webkit引擎开发的,Mozilla浏览器是基于Gecko引擎开发的)

简而言之,WebView可以实现安卓APP中承载网页

 

手机浏览器:

国内手机的自带浏览器不是chrome,主要是版权的原因,自带的浏览器都是手机厂商基于国内主流的几大浏览器自己定制,然后发布在自己手机系统版本中.不过国内几大浏览器厂商如QQ浏览器,UC浏览器、都是基于webkit引擎的,iphone的自带浏览器是Safari,Safari浏览器的内核是webkit

 

使用WebView的好处:

  1. 使用内核都是webkit,所以APP中网页展示的效果与主流浏览器差别无几
  2. 这是一个BS架构即浏览器和服务器的,所以在某些要经常改变的界面嵌入WebView,可以方便随时在后台修改其内容

加载一个网页的方法

加载服务器的网页

//获取到webview控件
WebView webv=findViewById(R.id.mywebview); //加载网页
webv.loadUrl("https://www.cnblogs.com/dongxiaodong/");

加载资源文件(assets目录)的网页

assets目录是Android的一种特殊目录,用于放置APP所需的固定文件,且该文件被打包到APK中时,不会被编码到二进制文件。

//获取到webview控件
WebView webv=findViewById(R.id.mywebview); //加载网页
webv.loadUrl("file:///android_asset/androidt.html");

网页加载时附加网页代码

baseUrl表示基础的网页

data表示要加载的内容

mimeType表示加载网页的类型

encoding表示编码格式

historyUrl表示可用历史记录,可以为null值

 

网页浏览器的基础属性

canGoBack()   是否可以后退

canGoForward() 是否可以前进

canGoBackOrForward(int step) 是否可以前进或者后退多少步,正数为前进,负数为后退

goBack() 后退

goBack() 前进

goBackOrForward(int step)前进或者后退多少步,正数为前进,负数为后退

reload() 重新加载或刷新界面

stopLoading() 停止加载

实现:



public void But_back(View v){

    //查询是否可以返回上一级

    boolean canx=webv.canGoBack();

    //返回上一级

    if(canx) webv.goBack();

    //不可返回

    else  Toast.makeText(MainActivity.this,"已经到达底端",Toast.LENGTH_SHORT).show();

}

//前进函数实现

public void But_forward(View v){

    boolean canx=webv.canGoForward();

    //返回上一级

    //查询是否可以返回上一级

    if(canx) webv.goForward();

        //不可返回

    else  Toast.makeText(MainActivity.this,"已经到达顶端",Toast.LENGTH_SHORT).show();

}

//刷新页面

public void But_reload(View v){

    webv.reload();

}

//停止界面加载

public void But_stop(View v){

    webv.stopLoading();

 

WebView配置类(WebSettings)

 

    //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript

    webSettings.setJavaScriptEnabled(true);

 

    //设置自适应屏幕,两者合用

    webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小

    webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小

 

    webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); //支持内容重新布局

 

    //缩放操作

    webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。

    webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放

    webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

    webSettings.setTextZoom(2);//设置文本的缩放倍数,默认为 100

 

    webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);  //提高渲染的优先级

 

    webSettings.setStandardFontFamily("");//设置 WebView 的字体,默认字体为 "sans-serif"

    webSettings.setDefaultFontSize(20);//设置 WebView 字体的大小,默认大小为 16

    webSettings.setMinimumFontSize(12);//设置 WebView 支持的最小字体大小,默认为 8

 

    // 5.1以上默认禁止了https和http混用,以下方式是开启

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

    }

 

    //其他操作

    webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存

    webSettings.setAllowFileAccess(true); //设置可以访问文件

    webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口

    webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片

    webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式

    webSettings.setGeolocationEnabled(true);//允许网页执行定位操作

    webSettings.setUserAgentString("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0");//设置User-Agent

 

 

    //不允许访问本地文件(不影响assets和resources资源的加载)

    webSettings.setAllowFileAccess(false);

    webSettings.setAllowFileAccessFromFileURLs(false);

 

事件监听

各种通知和请求事件(WebViewClient)

onPageStarted()   页面加载时

onPageFinished():页面加载完毕时调用。

shouldOverrideKeyEvent():重写此方法才能处理浏览器中的按键事件。

shouldInterceptRequest():页面每一次请求资源之前都会调用这个方法(非UI线程调用)。

onLoadResource():页面加载资源时调用,每加载一个资源(比如图片)就调用一次。

onReceivedError():加载页面的服务器出现错误(比如404)时回调。

onReceivedSslError():重写此方法可以让webview处理https请求。

doUpdateVisitedHistory():更新历史记录。

onFormResubmission():应用程序重新请求网页数据。

onReceivedHttpAuthRequest():获取返回信息授权请求。

onScaleChanged():WebView发生缩放改变时调用。

onUnhandledKeyEvent():Key事件未被加载时调用。

 

辅助 WebView 处理补充问题(WebChromeClient)

onProgressChanged():获得网页的加载进度并显示。

onReceivedTitle():获得网页的标题时回调。

onReceivedIcon():获得网页的图标时回调。

onCreateWindow():打开新窗口时回调。

onCloseWindow():关闭窗口时回调。

 

上例程

统一统一步骤:

第一步:

在AndroidManifest.xml下添加网络访问权限,如果需要外网访问的情况下

<!--网络权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!--文件读写权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

第二步:

在xml下添加WebView控件

<WebView     android:layout_width="match_parent"     android:id="@+id/mywebview"     android:layout_height="match_parent" />

加载可服务器的网页:

 第三步:

编写逻辑程序

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.view.KeyEvent;

import android.webkit.WebView;

import android.webkit.WebViewClient;

public class MainActivity extends AppCompatActivity {

    private WebView webv=null;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        //获取到webview控件

        webv=findViewById(R.id.mywebview);

        //设置访问的URL,此条将会触发系统调用浏览器打开,博客园东小东

        webv.loadUrl("https://www.cnblogs.com/dongxiaodong/");

        //通过下面的代码阻止APP直接通过浏览器打开网页

        webv.setWebViewClient(new WebViewClient(){

            @Override

            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                //使用WebView加载URL内容

                view.loadUrl(url);

                return  true;

            }

        });

    }

    //监听程序的返回事件

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        //如果按下返回键且网页有历史记录,可以返回上一级

        if ((keyCode == KeyEvent.KEYCODE_BACK) && webv.canGoBack()) {

            //返回上一级

            webv.goBack();

            return true;

        }

        //否则返回真实的按键信息给系统,系统将将退出程序

        return super.onKeyDown(keyCode, event);

    }

}

 

 

加载资源文件(assets目录)的网页

assets目录是Android的一种特殊目录,用于放置APP所需的固定文件,且该文件被打包到APK中时,不会被编码到二进制文件。

 

 第三步:

编写HTML代码,保存到文件androidt.html

 

<!doctype html>

<html>

<head>

<meta charset="utf-8">

<title>这里是网页头</title>

</head>

<body style="margin: 0 auto;text-align: center">

    <h1>我是网页标题1</h1>

    <h3>(资源文件方法)</h3>

    <button onClick="showA()" style="width: 100%;height: 100px;">点我弹框</button>

</body>

    <script>

        function showA(){

            alert("弹框内容,完成");

        }

    </script>

</html>

 

第四步

创建assets目录

右键【app】-【New】-【Folder】-【Assets Folder】-【finish】

第五步

将HTML文件拷贝到assets目录下

第六步

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.webkit.JsResult;

import android.webkit.WebChromeClient;

import android.webkit.WebSettings;

import android.webkit.WebView;

import android.webkit.WebViewClient;

public class MainActivity extends AppCompatActivity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        //获取到webview控件

        WebView webv=findViewById(R.id.mywebview);


        WebSettings webSettings = webv.getSettings();

        webSettings.setJavaScriptEnabled(true);//设置支持Javascript

        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);//允许js弹出窗口


        //访问本地资源文件网页

        webv.loadUrl("file:///android_asset/androidt.html");


        //通过下面的代码阻止APP直接通过浏览器打开网页

        webv.setWebViewClient(new WebViewClient(){

            @Override

            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                //使用WebView加载URL内容

                view.loadUrl(url);

                return  true;

            }

        });

        //如果要实习alert弹框,必须实现此监听事件

        webv.setWebChromeClient(new WebChromeClient() {

            @Override

            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {

                // TODO Auto-generated method stub

                return super.onJsAlert(view, url, message, result);

            }

        });

    }

 

 

加载部分源代码

直接写一部分的HTML代码,可以直接显示在WebView上

 

 第三步:

编写逻辑程序

package com.example.myapplication;


import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.view.KeyEvent;

import android.webkit.WebSettings;

import android.webkit.WebView;

import android.webkit.WebViewClient;

public class MainActivity extends AppCompatActivity {

    private WebView webv=null;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        //获取到webview控件

        webv=findViewById(R.id.mywebview);

        WebSettings webSettings = webv.getSettings();


        //将网页界面缩放至手机屏幕大小

        webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小

        webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小


        //设置支持缩放操作

        webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。

        webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放

        webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件


        //编辑网页代码

        String myhtml="<h1 >东小东标题</h1>" +

                      "<hr/>" +

                      "<a href='https://www.cnblogs.com/dongxiaodong/'>去东小东博客园看看<a/>" +

                      "<h3 >网页显示小标题</h3>" +

                      "<img style=\"width: 100%;\" src=\"https://img2018.cnblogs.com/blog/1485202/201811/1485202-20181116215233782-319594948.png\"/>";

        //设置显示

        webv.loadDataWithBaseURL("",myhtml,"text/html", "utf-8",null);


        //通过下面的代码阻止APP直接通过浏览器打开网页

        webv.setWebViewClient(new WebViewClient(){

            @Override

            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                //使用WebView加载URL内容

                view.loadUrl(url);

                return  true;

            }

        });

    }

    //监听程序的返回事件

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        //如果按下返回键且网页有历史记录,可以返回上一级

        if ((keyCode == KeyEvent.KEYCODE_BACK) && webv.canGoBack()) {

            //返回上一级

            webv.goBack();

            return true;

        }

        //否则返回真实的按键信息给系统,系统将将退出程序

        return super.onKeyDown(keyCode, event);

    }

}

 

综合案例

缺点:工程未实现网页的音频和视频播放

实现功能:

l  标题显示

l  网页加载进度条显示

l  后退、前进、刷新、停止加载四大常用功能适配

l  连接跳转,在APP本地打开网页

视图源码

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity">

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="vertical">


     <TextView

         android:layout_width="match_parent"

         android:layout_height="wrap_content"

         android:textSize="15dp"

         android:id="@+id/show_text"

         android:background="@color/colorPrimary"

         android:text="标题显示"/>

    <ProgressBar

        android:max="100"

        android:progress="10"

        android:id="@+id/show_progres"

        style="?android:attr/progressBarStyleHorizontal"

        android:background="@color/colorPrimary"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"/>


    <WebView

        android:layout_width="match_parent"

        android:id="@+id/mywebview"

        android:layout_height="match_parent" />

    </LinearLayout>

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_gravity="bottom"

        android:orientation="horizontal">


        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:onClick="But_back"

            android:text="后退"/>

        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:onClick="But_forward"

            android:layout_weight="1"

            android:text="前进"/>

        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:onClick="But_reload"

            android:layout_weight="1"

            android:text="刷新"/>

        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:onClick="But_stop"

            android:layout_weight="1"

            android:text="停止"/>



    </LinearLayout>


 

逻辑源码

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.view.KeyEvent;

import android.view.View;

import android.webkit.WebChromeClient;

import android.webkit.WebSettings;

import android.webkit.WebView;

import android.webkit.WebViewClient;

import android.widget.ProgressBar;

import android.widget.TextView;

import android.widget.Toast;


public class MainActivity extends AppCompatActivity {

    private WebView webv=null;

    private TextView showtext=null;

    private ProgressBar showpro=null;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        //隐藏状态栏

        getSupportActionBar().hide();

        setContentView(R.layout.activity_main);

        //获取到webview控件

        webv=findViewById(R.id.mywebview);

        showtext=findViewById(R.id.show_text);

        showpro=findViewById(R.id.show_progres);


        WebSettings webSettings = webv.getSettings();


       webSettings .setAllowFileAccess(true);

        //设置支持缩放操作

        webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。

        webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放

        webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件


        //编辑网页代码

        String myhtml="<h1 >东小东标题</h1>" +

                "<hr/>" +

                "<h2><a href='https://www.cnblogs.com/dongxiaodong/'>去东小东博客园看看<a/></h2>" +

                "<h3 >网页显示小标题</h3>" +

                "<img style=\"width: 300px;\" src=\"https://img2018.cnblogs.com/blog/1485202/201811/1485202-20181116215233782-319594948.png\"/>";

        //设置显示

        webv.loadDataWithBaseURL("",myhtml,"text/html", "utf-8",null);


        //通过下面的代码阻止APP直接通过浏览器打开网页

        webv.setWebViewClient(new WebViewClient(){

            @Override

            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                //使用WebView加载URL内容

                view.loadUrl(url);

                return  true;

            }

        });

        webv.setWebChromeClient(new WebChromeClient() {

            @Override

            public void onReceivedTitle(WebView view, String title) {

                //标题显示

                showtext.setText(title);

                //Toast.makeText(MainActivity.this,title,Toast.LENGTH_SHORT).show();

            }


            @Override

            public void onProgressChanged(WebView view, int newProgress) {

                super.onProgressChanged(view, newProgress);

                //进度条显示

                showpro.setProgress(newProgress);

                //Toast.makeText(MainActivity.this,newProgress+"",Toast.LENGTH_SHORT).show();

            }

        });


    }

    //监听程序的返回事件

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        //如果按下返回键且网页有历史记录,可以返回上一级

        if ((keyCode == KeyEvent.KEYCODE_BACK) && webv.canGoBack()) {

            //返回上一级

            webv.goBack();

            return true;

        }

        //否则返回真实的按键信息给系统,系统将将退出程序

        return super.onKeyDown(keyCode, event);

    }


    //后退函数实现

    public void But_back(View v){

        //查询是否可以返回上一级

        boolean canx=webv.canGoBack();

        //返回上一级

        if(canx) webv.goBack();

        //不可返回

        else  Toast.makeText(MainActivity.this,"已经到达底端",Toast.LENGTH_SHORT).show();

    }

    //前进函数实现

    public void But_forward(View v){

        boolean canx=webv.canGoForward();

        //返回上一级

        //查询是否可以返回上一级

        if(canx) webv.goForward();

            //不可返回

        else  Toast.makeText(MainActivity.this,"已经到达顶端",Toast.LENGTH_SHORT).show();

    }

    //刷新页面

    public void But_reload(View v){

        webv.reload();

    }

    //停止界面加载

    public void But_stop(View v){

        webv.stopLoading();

    }

}

 

参考:

https://blog.csdn.net/Jolting/article/details/81223904?utm_source=blogxgwz9

https://blog.csdn.net/weixin_40438421/article/details/85700109

https://www.jianshu.com/p/3e0136c9e748

 



上一篇: Android WebView 的使用(超详细用法)
下一篇: php实现的网页正文提取算法
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: android
相关日志:
评论: 0 | 引用: 0 | 查看次数: 143
发表评论
昵 称:
密 码: 游客发言不需要密码.
邮 箱: 邮件地址支持Gravatar头像,邮箱地址不会公开.
网 址: 输入网址便于回访.
内 容:
验证码:
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 开启 | [img]标签 关闭

 广告位

↑返回顶部↑