Android开发过程中,我们或多或少都会用到webview,使用webview来展示一些经常变动的界面更加方便简单,也更易于维护。在使用webview来展示网页的时候,有些时候我们需要通过JS和Android原生控件进行交互,以实现自己需要的效果或功能,本文通过一个demo简单实现了JS和Android原生控件的交互。

  • 效果图

界面上方是EditView和Button,下方是一个webview控件,通过输入url,然后点击跳转按钮,webview控件会加载该url,本次为了方便学习,我已经写好了一个html文件放置在了Asset文件中,通过file:///android_asset/test.html来进行加载。然后出现四个新的按钮,点击不同的按钮,会产生不同的效果。

  • asset文件夹下面的test.html文件
"en">   "UTF-8">  "Generator" content="EditPlus®">  "Author" content="">  "Keywords" content="">  "Description" content="">  Document    "button" value="jsAlert" οnclick="jsAlert()"/>"button" value="jsConFirm" οnclick="jsConFirm()"/>"button" value="jsPrompt" οnclick="jsPrompt()"/>"button" value="jsJava" οnclick="jsJava()"/> 

代码很简单,整个界面只有四个按钮,以及四个JS写的方法jsAlert(),jsConFirm(),jsPrompt(),jsJava(),当点击按钮触发这些方法的时候,会进一步触发我们写好的java代码,具体实现请参见java代码。

  • 具体的java代码
import android.app.AlertDialog;import android.app.ProgressDialog;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.graphics.Bitmap;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.view.View;import android.webkit.JavascriptInterface;import android.webkit.JsPromptResult;import android.webkit.JsResult;import android.webkit.WebChromeClient;import android.webkit.WebView;import android.webkit.WebViewClient;import android.widget.EditText;import android.widget.Toast;public class JSActivity extends AppCompatActivity {    //assets下的文件的test.html所在的绝对路径    private static final String DEFAULT_URL = "file:///android_asset/test.html";    private EditText et_url;    private WebView webView;    private ProgressDialog progressDialog;//加载界面的菊花    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_js);        initView();        initWebView();    }    /**     * 初始化控件     */    private void initView() {        webView = (WebView) findViewById(R.id.webView);        et_url = (EditText) findViewById(R.id.et_url);    }    /**     * 初始化webview     */    private void initWebView() {        //首先设置Webview支持JS代码        webView.getSettings().setJavaScriptEnabled(true);        //Webview自己处理超链接(Webview的监听器非常多,封装一个特殊的监听类来处理)        webView.setWebViewClient(new WebViewClient() {            /**             * 当打开超链接的时候,回调的方法             * WebView:自己本身webView             * url:即将打开的url             */            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                //自己处理新的url                webView.loadUrl(url);                //true就是自己处理                return true;            }            //重写页面打开和结束的监听。添加友好,弹出菊花            /**             * 界面打开的回调             */            @Override            public void onPageStarted(WebView view, String url, Bitmap favicon) {                if (progressDialog != null && progressDialog.isShowing()) {                    progressDialog.dismiss();                }                //弹出菊花                progressDialog = new ProgressDialog(JSActivity.this);                progressDialog.setTitle("提示");                progressDialog.setMessage("软软正在拼命加载……");                progressDialog.show();            }            /**             * 界面打开完毕的回调             */            @Override            public void onPageFinished(WebView view, String url) {                //隐藏菊花:不为空,正在显示。才隐藏                if (progressDialog != null && progressDialog.isShowing()) {                    progressDialog.dismiss();                }            }        });        //设置进度条        //WebChromeClient与webViewClient的区别        //webViewClient处理偏界面的操作:打开新界面,界面打开,界面打开结束        //WebChromeClient处理偏js的操作        webView.setWebChromeClient(new WebChromeClient() {            /**             * 进度改变的回调             * WebView:就是本身             * newProgress:即将要显示的进度             */            @Override            public void onProgressChanged(WebView view, int newProgress) {                if (progressDialog != null && progressDialog.isShowing())                    progressDialog.setMessage("软软正在拼命加载……" + newProgress + "%");            }            /**             * 重写alert、confirm和prompt的回调             */            /**             * Webview加载html中有alert()执行的时候,回调             * url:当前Webview显示的url             * message:alert的参数值             * JsResult:java将结果回传到js中             */            @Override            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {                AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);                builder.setTitle("提示");                builder.setMessage(message);//这个message就是alert传递过来的值                builder.setPositiveButton("确定", new OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        //处理确定按钮了,且通过jsresult传递,告诉js点击的是确定按钮                        result.confirm();                    }                });                builder.show();                //自己处理                return true;            }            @Override            public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {                AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);                builder.setTitle("提示");                builder.setMessage(message);//这个message就是alert传递过来的值                builder.setPositiveButton("确定", new OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        //处理确定按钮了,且通过jsresult传递,告诉js点击的是确定按钮                        result.confirm();                    }                });                builder.setNegativeButton("取消", new OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        //处理取消按钮,且通过jsresult传递,告诉js点击的是取消按钮                        result.cancel();                    }                });                builder.show();                //自己处理                return true;            }            /**             * defaultValue就是prompt的第二个参数值,输入框的默认值             * JsPromptResult:向js回传数据             */            @Override            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,                                      final JsPromptResult result) {                AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);                builder.setTitle("提示");                builder.setMessage(message);//这个message就是alert传递过来的值                //添加一个EditText                final EditText editText = new EditText(JSActivity.this);                editText.setText(defaultValue);//这个就是prompt 输入框的默认值                //添加到对话框                builder.setView(editText);                builder.setPositiveButton("确定", new OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        //获取edittext的新输入的值                        String newValue = editText.getText().toString().trim();                        //处理确定按钮了,且过jsresult传递,告诉js点击的是确定按钮(参数就是输入框新输入的值,我们需要回传到js中)                        result.confirm(newValue);                    }                });                builder.setNegativeButton("取消", new OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        //处理取消按钮,且过jsresult传递,告诉js点击的是取消按钮                        result.cancel();                    }                });                builder.show();                //自己处理                return true;            }        });        //java与js回调,自定义方法        //1.java调用js        //2.js调用java        //首先java暴露接口,供js调用        /**         * obj:暴露的要调用的对象         * interfaceName:对象的映射名称 ,object的对象名,在js中可以直接调用         * 在html的js中:JSTest.showToast(msg)         * 可以直接访问JSTest,这是因为JSTest挂载到js的window对象下了         */        webView.addJavascriptInterface(new Object() {            //定义要调用的方法,注意4.2及以后的则多了注释语句@JavascriptInterface            //msg由js调用的时候传递            @JavascriptInterface            public void showToast(String msg) {                Toast.makeText(getApplicationContext(),                        msg, Toast.LENGTH_SHORT).show();            }        }, "JSTest");    }    public void onClick(View view){        String url = et_url.getText().toString().trim();        if(TextUtils.isEmpty(url)){            url = DEFAULT_URL;        }        webView.loadUrl(url);    }    @Override    public void onBackPressed() {        if (webView.canGoBack()) {            //返回上一个页            webView.goBack();            return ;        }        super.onBackPressed();    }}
  • 布局文件activity_js.xml
"http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".JSoupHtmlActivity" >    "fill_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        "@+id/et_url"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:hint="请输入地址" />        

代码过程描述的废话我就不多说了,注释写的算是比较仔细了,另外再强调两点需要注意的地方:

一、不要忘记通过setJavaScriptEnabled(true)设置webview支持JS代码

二、在使用addJavascriptInterface方法添加挂载对象时,要注意在Android4.2之后需要给对象方法加上@JavascriptInterface注解。

最后附上demo下载地址

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. 玩一下android的反编译和代码混淆
  3. Android(安卓)学习之《第一行代码》第二版 笔记(十八)调用摄像头拍
  4. 使用html开发软件界面
  5. Android06之RecyclerView详解
  6. 直播一对一源码在Android音频开发中如何实现对讲机实时语音对话
  7. Android获取其他包的Context实例,然后调用它的方法,反射!!!
  8. Servlet中POST服务延时返回数据
  9. RN 与 Android(安卓)代码交互

随机推荐

  1. Flutter和Android中的View区别
  2. 开始使用Android(安卓)Sutdio(四)Android(
  3. kotlin第一次运行在Android上
  4. Android 5.0使用android:onClick属性出现
  5. Android 按钮点击切换背景,同时修改文字颜
  6. Android下的图形处理
  7. NDK开发
  8. Android的RIL驱动模块启动流程
  9. 【Android 开发】:数据存储之 SQLite 数据
  10. 【Android】直接连接SqlServer