WebView

WebView

预备知识

新建asserts文件:

image-20220109190423405

assets目录下主要存放四种文件:文本文件、图像文件、网页文件(包括html中引用的js/ccs/jpg等资源)、音频视频文件

加载网页

  • 加载URL(网络或者本地asserts文件夹下的html文件)
  • 加载html代码
  • Native和JavaScript相互调用(JS和WebView混合调用)

加载网络URL

  • webview.loadUrl(“http://m.tiantiantech.cn”) ;

加载asserts下的html文件

  • webview.loadUrl(“file:///android_asset/test.html”); // 没有s和r,就asset

加载html代码

  • webview.loadData();
  • webview.loadDataWithBaseURL();

按下返回键,默认是退出Activity,如果是希望WebView内页面后退

重写onKeyDown方法

@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
    if((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()){
        webview.goBack();
        return true; // true表示处理完该事件 , false表示该事件可以传递下去
    }
    return super.onKeyDown(keyCode, event);
}
webview其他方法:

webview.canGoBack()

webview.goBack()

webview.canGoForward()

webview.goForward()

webview.canGoBackOrForward(int steps)

webview.goBackOrForward(int steps)

添加网络权限:

<uses-permission android:name="android.permission.INTERNET"/>

具体代码(加载百度):

public class WebViewBaidu extends AppCompatActivity {

    WebView mWvMain;

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

        mWvMain = findViewById(R.id.web_view_baidu);

        mWvMain.getSettings().setJavaScriptEnabled(true);

        mWvMain.setWebViewClient(new MyWebViewClient());

        mWvMain.setWebChromeClient(new MyWebChromeClient());

        mWvMain.loadUrl("https://m.baidu.com"); // mobile移动端地址

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if((keyCode == KeyEvent.KEYCODE_BACK) && mWvMain.canGoBack()){
            mWvMain.goBack();;
            return true;
        }else {//如果WebView不能回退
            //提示应用是否退出程序
            new AlertDialog.Builder(WebViewBaidu.this).setTitle("提示")
                    .setMessage("确定退出浏览器吗?").setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // TODO Auto-generated method stub

                    WebViewBaidu.this.finish();//退出程序
                }
            }).setNegativeButton("取消", null).show();

            return super.onKeyDown(keyCode, event);
        }
        
        return super.onKeyDown(keyCode, event);
    }


    class MyWebChromeClient extends WebChromeClient{
        // 加载页面进度事件
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
            setTitle(title);  // 修改网页标题
        }
    }

    class MyWebViewClient extends WebViewClient {
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            view.loadUrl(request.getUrl().toString());
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            Log.d("WebView","onPageStarted...");
            // mWvMain.loadUrl("javascript:alert('loading')");  // 用js弹出对话框
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            Log.d("WebView","onPageFinished");
            // mWvMain.loadUrl("javascript:alert('loaded')"); // 用js弹出对话框

        }
    }
}

WebViewClient与WebChromeClient的区别

在WebView的设计中,不是什么事都要WebView类干的,有些杂事是分给其他人的,这样WebView专心干好自己的解析、渲染工作就行了。WebViewClient就是帮助WebView处理各种通知、请求事件的,具体来说包括:

onLoadResource
onPageStart
onPageFinish
onReceiveError
onReceivedHttpAuthRequest

WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等比如

onCloseWindow(关闭WebView)
onCreateWindow()
onJsAlert (WebView上alert无效,需要定制WebChromeClient处理弹出)
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle

解析并执行JS操作的方法:

//        mWvMain.evaluateJavascript(“ ”,null);
//        mWvMain.loadUrl("");

常出现的问题

1.Android WebView 加载失败(net::ERR_CLEARTEXT_NOT_PERMITTED)
解锁正确姿势:

首先保证App申明了网络权限

<uses-permission android:name="android.permission.INTERNET" />

然后在manifest 中application节点添加

android:usesCleartextTraffic="true"
2.net:err_unknown_url_scheme

R文件

当 Android 应用程序被编译,会自动生成一个 R 类,其中包含了所有 res/ 目录下资源(res资源:如layout、string、drawable等)。

如何使用R文件

1、 在java文件中使用R文件

1)使用res资源下: R.子类.资源名(资源标识符) R.type.name

//字符
R.string.name1
R.string.name2
//图片
R.drawable.icon1
R.drawable.icon2
//布局
R.layout.first_layout
R.layout.second_layout
//....

2)使用android自带的资源下,android.R.type.name

只需要再前面加上android. 以申明来自Android系统

2、在XML中使用R文件

1)在res资源下,@[package:]type/name(使用我们自己包下的资源可以省略 package)

@drawable/icon
/*
其中@代表R.java类
drawable代表的是R.java中的静态内部类drawable
icon代表静态内部类drawable中的静态属性icon
而该属性可以指向 res 目录下的“drawable-*dpi”中的 icon.png 图标
*/

2)在android内置资源下,则要添上包名“android:”

android:textColor=”@android:color/red”
最后说明一下“@+id/string_name”表达式

顺便说一下,在布局文件当中我们需要为一些组件添加 Id 属性作为标示,可以使
用如下的表达式“@+id/string_name”
其中“+”表示在 R.java 的名为 id 的内部类中添加一条记录。如”@+id/button”的含义是在 R.java 文件中的 id 这个静态内部类添加一条常量名为 button,该常量就是该资源的标识符。如果 id 这个静态内部类不存在,则会先生成它。
通过该方式生成的资源标识符,仍然可以以“@id/string_name”的方式引用。

参考博客:

https://blog.csdn.net/u012810020/article/details/51820240

https://blog.csdn.net/u012810020/article/details/51820240

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

剽悍兔八哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值