基于X5内核的WebView安卓HybridApp开发

前言

现在的HybridApp也就是混合开发的APP越来越普遍了,其原理就是在一个APP中嵌入一个webview,然后访问我们的html5页面,而html5页面这部分内容,在我们APP不升级的情况下能动态的更新,并且具有跨平台性,也就是说Android和IOS都可以用这一个html页面,从而减小了开发成本。现在很多APP都是混合开发的了,比如淘宝,京东,还有很多银行的APP,中国移动APP等。
优点:减小开发成本,缩短开发周期,具有跨平台性。
缺点:性能不如原生的好
现在也有混合开发的架构,比如React Native,阿里的Weex,但学习成本都太高,一个项目需要混合开发,一般都需要团队的人都要懂React Native。本篇主要讲的是基于x5内核的webview的混合开发基础。
因为用原生的webview有许多问题,比如对html5的兼容性较差,内存泄漏等问题,所有就用了腾讯的x5内核的webview。
X5内核的优势
1) 速度快:相比系统webview的网页打开速度有30+%的提升;

2) 省流量:使用云端优化技术使流量节省20+%;

3) 更安全:安全问题可以在24小时内修复;

4) 更稳定:经过亿级用户的使用考验,CRASH率低于0.15%;

5) 兼容好:无系统内核的碎片化问题,更少的兼容性问题;

6) 体验优:支持夜间模式、适屏排版、字体设置等浏览增强功能;

7) 功能全:在Html5、ES6上有更完整支持;

8) 更强大:集成强大的视频播放器,支持视频格式远多于系统webview;

9) 视频和文件格式的支持x5内核多于系统内核

10) 防劫持是x5内核的一大亮点

下面就讲解从接入SDK到webview的基本用法,最后再到安卓和JS的通信实现混合开发。

一、准备工作

1.下载SDK jar包放入到工程中的libs目录下, 并右键jar包,点击Add As Library,下载地址:https://x5.tencent.com/tbs/sdk.html

2.x5暂时不提供64位so文件,为了保证64位手机能正常加载x5内核,请参照如下链接修改相关配置https://x5.tencent.com/tbs/technical.html#/detail/sdk/1/34cf1488-7dc2-41ca-a77f-0014112bcab7

3.AndroidManifest.xml里加入权限声明

    <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" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

二、初始化X5内核并创建webview

1.初始化x5内核,一般可在application的onCreate方法中,或者activity的onCreate的方法中初始化。
执行QbSdk.initX5Environment()方法来初始化内核。第一个参数是context,第二个参数是callback,这个函数内部是异步的,当初始化完成后就回调里面的2个方法。启动APP的时候,会去检查手机中是否有可用的X5内核,如果没有就在后台下载,大概23MB,这个时候就会相对有点久。QbSdk.isTbsCoreInited()用来判断x5内核是否已经加载了,因为有时候你的app可能finish掉了,但是进程还在,此时x5内核也还在,再次启动app的时候就不需要初始化x5内核了

    /**
     * 初始化x5内核并加载
     */
    private void initX5() {
        //QbSdk.isTbsCoreInited()用来判断x5内核是否已经加载了
        if (QbSdk.isTbsCoreInited()) {
            //如果已经加载
            Log.d(TAG, "QbSdk.isTbsCoreInited: true 已经加载x5内核");
            progressBar.setVisibility(View.INVISIBLE);
            textview.setText("x5内核初始化成功");
            initListener();
        } else {
            //还没加载,就要初始化内核并加载
            Log.d(TAG, "QbSdk.isTbsCoreInited: false 还没加载x5内核");
            //初始化x5内核
            QbSdk.initX5Environment(this, new QbSdk.PreInitCallback() {

                @Override
                public void onCoreInitFinished() {

                }

                @Override
                public void onViewInitFinished(boolean b) {
                    progressBar.setVisibility(View.INVISIBLE);
                    Log.d(TAG, "onViewInitFinished: x5内核初始化:" + b);
                    if (b == true) {
                        textview.setText("x5内核初始化成功");
                        initListener();
                    } else {
                        textview.setText("x5内核初始化失败");
                    }
                }
            });
        }
    }

2.动态创建webview。一般我们需要动态创建webview,因为当我们x5内核还没初始化完的时候,我们就创建了webview,此时的webview就是系统的,我们想保证只用x5内核的,不用系统的,就要在x5内核初始化完成后再去创建。

        //拿到父布局
        LinearLayout linearlayout = (LinearLayout) findViewById(R.id.linearlayout);
        //创建一个webview,并放到父布局中
        mWebView = new WebView(this);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        linearlayout.addView(mWebView, layoutParams);

注意,这里实例化的Webview的导入的包是com.tencent.smtt.sdk
这里写图片描述

3.对WebView的生命周期处理

    @Override
    protected void onResume() {
        //激活WebView为活跃状态,能正常执行网页的响应
        mWebView.onResume();
        super.onResume();
    }

    @Override
    protected void onPause() {
        //当页面被失去焦点被切换到后台不可见状态,需要执行onPause
        //通过onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。
        mWebView.onPause();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        if (mWebView != null) {
            //先让webview加载null内容
            mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
            mWebView.clearHistory();

            //父布局移除webview
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            //最后webview在销毁
            mWebView.destroy();
            mWebView = null;
        }
        super.onDestroy();
    }

三、WebView的基本使用及常用方法

3.1 WebView的常用方法

  • 作用:对WebView进行配置和管理
  • 加载url
    //方式1. 加载一个网页:
    webView.loadUrl("http://www.baidu.com/");

    //方式2:加载apk包中的html页面
    webView.loadUrl("file:///android_asset/index.html");

    //方式3:加载手机本地的html页面
    webView.loadUrl("content://com.example.fu.x5hybriddemo/sdcard/index.html");
  • WebView的状态
    //激活WebView为活跃状态,能正常执行网页的响应
    webView.onResume() ;

    //当页面被失去焦点被切换到后台不可见状态,需要执行onPause
    //通过onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。
    webView.onPause();

    //当应用程序(存在webview)被切换到后台时,这个方法不仅仅针对当前的webview而是全局的全应用程序的webview
    //它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
    webView.pauseTimers()
    //恢复pauseTimers状态
    webView.resumeTimers();

    //销毁Webview
    //在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview
    //但是注意:webview调用destory时,webview仍绑定在Activity上
    //这是由于自定义webview构建时传入了该Activity的context对象
    //因此需要先从父容器中移除webview,然后再销毁webview:
    rootLayout.removeView(webView); 
    webView.destroy();
  • 前进/后退网页
        //判断是否可以后退网页,但是不是后退网页的动作,后退网页的动作是mWebview.goBack()
        //这个方法的返回值是boolean,当不是第一个页面的时候,就是又点进其他页面,调用的话就返回true,如果就是在第一个页面就返回false
    Webview.canGoBack() 
    //后退网页
    Webview.goBack()

    //是否可以前进                     
    Webview.canGoForward()
    //前进网页
    Webview.goForward()

    //以当前的index为起始点前进或者后退到历史记录中指定的steps
    //如果steps为负数则为后退,正数则为前进
    Webview.goBackOrForward(intsteps)

我们不对Back键做处理的话,按下Back键会把activity给finish掉,以至于WebView也destroy了,但通常情况下我们希望Back键是网页后退,当是首页的时候,我们再按Back键就finish掉了activity,只需这样实现。

    @Override
    public void onBackPressed() {
        //判断是否可以后退网页,但是不是后退网页的动作,后退网页的动作是mWebview.goBack()
        //这个方法的返回值是boolean,当不是第一个页面的时候,
        //就是又点进其他页面,调用的话就返回true,如果就是在第一个页面就返回false
        if (mWebView.canGoBack()) {
            mWebView.goBack();  //后退网页
        } else {
            super.onBackPressed();
        }
    }
  • 清除缓存数据
    //清除网页访问留下的缓存
    //由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
    Webview.clearCache(true);

    //清除当前webview访问的历史记录
    //只会webview访问历史记录里的所有记录除了当前访问记录
    Webview.clearHistory();

    //这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据
    Webview.clearFormData();

3.2 WebSettings类的常用方法

  • 拿到WebSettings
    //声明WebSettings子类
    WebSettings webSettings = webView.getSettings();
  • 常用方法
    //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
    webSettings.setJavaScriptEnabled(true);  
    // 若加载的 html 里有JS 在执行动画等操作,会造成资源浪费(CPU、电量)
    // 在 onStop 和 onResume 里分别把 setJavaScriptEnabled() 给设置成 false 和 true 即可

    //支持插件
    webSettings.setPluginsEnabled(true); 

    //设置自适应屏幕,两者合用
    webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小 
    webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小

    //缩放操作
    webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
    webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
    webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

    //其他细节操作
    webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存 
    webSettings.setAllowFileAccess(true); //设置可以访问文件 
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口 
    webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
    webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
  • 设置WebView缓存
    当加载 html 页面时,WebView会在/data/data/包名目录下生成 database 与 cache 两个文件夹,请求的 URL记录保存在 WebViewCache.db,而 URL的内容是保存在 WebViewCache 文件夹下。
    是否启用缓存
    //优先使用缓存: 
    WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
    //缓存模式如下:
    //LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
    //LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
    //LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
    //LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。

    //不使用缓存: 
    WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);

结合使用(离线加载)

    if (NetStatusUtil.isConnected(getApplicationContext())) {
        //根据cache-control决定是否从网络上取数据。
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
    } else {
        //没网,则从本地获取,即离线加载
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
    }

    // 开启 DOM storage API 功能
    webSettings.setDomStorageEnabled(true); 
    //开启 database storage API 功能
    webSettings.setDatabaseEnabled(true);   
    //开启 Application Caches 功能
    webSettings.setAppCacheEnabled(true);

    String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACAHE_DIRNAME;
    webSettings.setAppCachePath(cacheDirPath); //设置  Application Caches 缓存目录

注意: 每个 Application 只调用一次 WebSettings.setAppCachePath(),WebSettings.setAppCacheMaxSize()。

3.3 WebViewClient类的常用方法

  • 作用:处理各种通知 & 请求事件
        /**
         * 作用:处理各种通知 & 请求事件
         */
        mWebView.setWebViewClient(new WebViewClient() {
            //复写shouldOverrideUrlLoading会使打开网页不调用系统浏览器,就显示在本webview中
            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                //这里回调的url就是你点击的页面的链接,会传到这里来
                webView.loadUrl(url);
                return true;   //返回true,拦截url
            }

            //加载页面资源的时候会调用,比如图片,加载一个就调用一次
            @Override
            public void onLoadResource(WebView webView, String url) {
                super.onLoadResource(webView, url);
//                Log.d(TAG, "onLoadResource: ");
            }


            //加载的页面服务器出现错误的时候调用,如404
            //一般这个方法用在比如出现404的错误,显示系统自带的提示错误的页面会很low,这时我们就可以加载自己的页面
            @Override
            public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl) {
                super.onReceivedError(webView, errorCode, description, failingUrl);
            }

            //webView默认是不处理https请求的,页面显示空白,需要进行如下设置
            @Override
            public void onReceivedSslError(WebView webView, SslErrorHandler handler, SslError error) {
                handler.proceed(); //表示等待证书响应
                Log.d(TAG, "onReceivedSslError: ");
//                super.onReceivedSslError(webView, handler, error);
            }

            //页面开始加载的时候调用
            @Override
            public void onPageStarted(WebView webView, String url, Bitmap favicon) {
                super.onPageStarted(webView, url, favicon);
                Log.d(TAG, "onPageStarted: 开始");
            }

            //页面加载完成的时候调用
            @Override
            public void onPageFinished(WebView webView, String url) {
                super.onPageFinished(webView, url);
                Log.d(TAG, "onPageFinished: 完成");
            }
        });

3.4 WebChromeClient类的常用方法

  • 作用:辅助 WebView 处理 Javascript 的对话框,网站图标,网站标题等等。
        /**
         * 作用:辅助 WebView 处理 Javascript 的对话框,网站图标,网站标题等等。
         * 要设置了这个WebChromeClient才能显示js的弹窗,如alert()
         */
        mWebView.setWebChromeClient(new WebChromeClient() {
            //获得网页的加载进度并显示
            @Override
            public void onProgressChanged(WebView webView, int newProgress) {
                String progress = newProgress + "%";
                Log.d(TAG, "progress:" + progress);
            }

            //获取Web页面中的标题
            @Override
            public void onReceivedTitle(WebView webView, String title) {
                Log.d(TAG, "onReceivedTitle: 标题:" + title);
            }

            /**
             * 当页面中触发了alert(),confirm(),prompt()这三个方法,就会对应回调到下面三个方法中
             * 相当于js调用了安卓的方法,这也算是一种安卓和js的通信,
             * 复写了下面这3方法并且返回true就不会显示页面的弹窗了,而且一定要有确认或者取消的操作,不然会卡死
             * 但能拿到弹出里的所有信息,可以自己写原生弹窗等,如alert,toast等,很灵活
             *
             */
            @Override
            public boolean onJsAlert(WebView webView, String url, String message, JsResult result) {
                Log.d(TAG, "onJsAlert: message:" + message);
                //这里我把js中的alert()变成安卓中的toast
                Toast.makeText(WebViewTestActivity.this, "alert变成toast啦", Toast.LENGTH_SHORT).show();
                result.confirm();  //确认
                return true;
            }


            @Override
            public boolean onJsConfirm(WebView webView, String url, String message, final JsResult result) {
                Log.d(TAG, "onJsConfirm: message:" + message);
                //这里我把js中的confirm()变成安卓中的dialog
                new AlertDialog.Builder(WebViewTestActivity.this)
                        .setTitle("js的confirm变成安卓的dialog啦")
                        .setMessage(message)
                        .setPositiveButton("确认", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                result.confirm();
                            }
                        })
                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                result.cancel();
                            }
                        })
                        .setCancelable(false)
                        .show();
                return true;
            }

            @Override
            public boolean onJsPrompt(WebView webView, String url, String message, String defalutValue, JsPromptResult result) {
                Log.d(TAG, "onJsPrompt: message:" + message);
                Log.d(TAG, "onJsPrompt: defalutValue:" + message);
                //这里prompt的确认是要传参数的,这个参数会传到js中去,所以这个方法能实现安卓和js的相互通信
                result.confirm("啦啦啦啦,我是安卓原生来的内容");
                return true;
            }
        });

四、WebView与JavaScript的交互

4.1 交互方式

WebView与JavaScript的交互其实就是我们需要的Android和JS的交互,交互其实就是

  • Android调用JS的代码
  • JS调用安卓的代码
    他们之间就是通过WebView来当做桥梁实现相互调用的。

Android调用JS的方法有2种:

  1. 通过WebView的loadUrl()方法
  2. 通过WebView的evaluateJavascript()方法

JS调用Android的方法有3种:

  1. 通过WebView的addJavascriptInterface()进行对象映射
  2. 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url
  3. 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息

4.2 Android调用JS代码

方式一:通过WebView的loadUrl()方法
- html页面

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <meta charset="utf-8">
    <title>simple</title>

    <script>


        function callJS(){
            alert("我是被安卓调用的");
            document.getElementById("p").innerHTML = "我被安卓调用了"
        }

    </script>
</head>
<body>
    <h4>Android调用JS方式一</h4>
    <p id="p"></p>
</body>
</html>
  • java代码
    //android调用js方式一
    //此方式一定要在onPageFinished之后调用才有用
    mWebView.loadUrl("javascript:callJS()"); //调用当前页面的javascript中的callJS()方法

方式二: 通过WebView的evaluateJavascript()方法

    //android调用js方式二,这个方法能接受js方法的返回值
    mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
        //此处为js返回的结果,value为js函数的返回值,没有返回值就为null
        Log.i(TAG, "onReceiveValue: vlue:" + value);
        Toast.makeText(AndroidCallJs2Activity.this, value, Toast.LENGTH_SHORT).show();
        }
    });

4.3 JS调用Android代码

方式一: 通过WebView的addJavascriptInterface()进行对象映射

  • html页面
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <meta charset="utf-8">
    <title>simple</title>

    <script>
      function callAndroid() {
        androidObject.hello("啦啦啦啦,我是html页面通过js来的内容");
      }
    </script>
</head>
<body>
    <h4>JS调用Android方式一</h4>
    <input type="button" onclick="callAndroid()" value="我是HTML按钮,要调用Android"/>
</body>
</html>
  • 我们需要创建一个类
public class JSCallAndroid extends Object {

    private Context context;

    public JSCallAndroid(Context context){
        this.context = context;
    }

    // 定义JS需要调用的方法
    // 被JS调用的方法必须加入@JavascriptInterface注解
    @JavascriptInterface
    public void hello(String msg) {
        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
    }
}
  • 然后在需要JS调用安卓的时候加入下面这一条语句
    //js调用android方式一:通过addJavascriptInterface()将Java对象映射到JS对象
    //参数1:java对象,js要调用安卓的方法的那个对象要传过去
    //参数2:javascript对象名,html页面中这个名字就相当于参数一的对象了
    mWebView.addJavascriptInterface(new JSCallAndroid(JsCallAndroid1Activity.this), "androidObject");
  • JS中调用直接写androidObject就是安卓传过来的对象然后调用hello方法
    <script>
      function callAndroid() {
        androidObject.hello("啦啦啦啦,我是html页面通过js来的内容");
      }
    </script>

方式二: 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url

  • 复写WebWebViewClient类中的shouldOverrideUrlLoading()方法,在此方法中对我们的URL进行捕获,根据自己定义的URL规则来判断JS是不是调用安卓方法,是的话就调用安卓方法,并且拦截URL(不加载网页),不是的话就不拦截。
    @Override
    public boolean shouldOverrideUrlLoading(WebView webView, String url) {
        //这里回调的url就是你点击的页面的链接,会传到这里来
        //js调用android方式二,在这里拦截url,进行解析然后调用安卓方法
        //然和这个url的规则啊什么的都是自己定义,有点类似http协议
        Log.d(TAG, "shouldOverrideUrlLoading: url:" + url);
        Uri uri = Uri.parse(url);
        String scheme = uri.getScheme();
        String authority = uri.getAuthority();
        Set<String> queryParameterNames = uri.getQueryParameterNames();

        Log.d(TAG, "scheme: " + scheme);
        Log.d(TAG, "authority: " + authority);
        //拿到的参数
        Log.d(TAG, "queryParameterNames: " + queryParameterNames.toString());
        Iterator<String> iterator = queryParameterNames.iterator();
        ArrayList<String> argList = new ArrayList<>();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String queryParameter = uri.getQueryParameter(key);
            argList.add(queryParameter);
            Log.d(TAG, key + "=" + queryParameter);
        }

        if (scheme.equals("js")) {
            //说明是js要调用android啦,然后进行自己的安卓操作
            Toast.makeText(JsCallAndroid2Activity.this, "安卓被js调用啦,还传来了参数,参数1:" + argList.get(0)
                    + " 参数2:" + argList.get(1), Toast.LENGTH_LONG).show();
        } else {
            //这个url就是你在网页上点击后要跳转的那个url
            //scheme不是js,说明不是要调用安卓的
            webView.loadUrl(url);
        }
        return true;   //返回true,拦截url
    }
  • html页面中的JS代码
        function callAndroid() {
            // 相当于给请求这个url,会被webview中的shouldOverrideUrlLoading()捕捉到
            document.location = "js://webview?arg1=111&arg2=222";
        }

方式三: 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息
这三个方法都可以用来JS调用安卓,但prompt要比另两个方便些,并且安卓还能向js会传参数,所以这里我们就采用prompt()来进行讲解。

  • 重新WebChromeClient类中的这3个方法
    //js调用android方式三要在这里面
    mWebView.setWebChromeClient(new WebChromeClient() {

        /**
         * 复写了下面这3方法并且返回true就不会显示页面的弹窗了,而且一定要有确认或者取消的操作,不然会卡死
         * 但能拿到弹出里的所有信息,可以自己写原生弹窗等,如alert,toast等,很灵活
         * 这也算是一种java和js的通信
         *
         * js调用android方式三
         *
         * 这个3个方法都可以用来js和android通信,但最好用的是onJsPrompt
         */

        @Override
        public boolean onJsAlert(WebView webView, String s, String s1, JsResult jsResult) {
            return super.onJsAlert(webView, s, s1, jsResult);
        }

        @Override
        public boolean onJsConfirm(WebView webView, String s, String s1, JsResult jsResult) {
            return super.onJsConfirm(webView, s, s1, jsResult);
        }

        @Override
        public boolean onJsPrompt(WebView webView, String url, String message, String defalutValue, JsPromptResult result) {
            Log.i(TAG, "onJsPrompt: message:" + message);
            Log.i(TAG, "onJsPrompt: defalutValue:" + defalutValue);
            Toast.makeText(JsCallAndroid3Activity.this, "我是被js调用的,还传了参数: " + message
                    + ":" + defalutValue, Toast.LENGTH_LONG).show();
            result.confirm("啦啦啦啦,我是安卓原生来的内容");
            return true;
        }
    });
  • 当JS中调用prompt()方法,就会触发安卓众onJsPrompt方法,并且prompt()方法还能携带参数。
        function callAndroid() {
          var name = prompt('标题', '通过prompt与android通信');
                if (name != null && name !== "") {
                    var e = document.getElementById("p");
                    e.innerHTML = "安卓返回给js的数据是:" + name;
                }
        }

以上就是基于X5内核的WebView安卓HybridApp开发模式的基础知识,也是本人对混合开发的初步理解,如有错误的地方,还望指正。

参考文献:

  1. Android开发:最全面、最易懂的Webview使用详解
  2. 最全面总结 Android WebView与 JS 的交互方式
  3. 腾讯浏览服务接入指南
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值