zoukankan      html  css  js  c++  java
  • WebView上实现Java与JavaScript交互

          在安卓开发上,考虑到开发效率和界面更新,有时使用WebView结合web页面技术,可以快速迭代地开发移动应用。WebView加载资源的速度并不慢,但是如果资源多了,就很慢。图片、css、js、html这些资源每个大概需要10-200ms,一般都是30ms以内就行了。但是,WebView是等全部资源加载完成才开始渲染的,所以最后用原生js来写,别用太多jQuery之类的框架,以改善用户体验。

      在混合开发中,有时会用到安卓原生SDK,如调用相机、查看相册、录音等,这就需要web页面中的JavaScript能调用到安卓SDK接口。由于Android的WebView是基于webkit内核的,集成了js与java互调的接口函数,可以方便地进行开发使用。

    界面布局xml:

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent" >
     5 
     6     <WebView
     7         android:id="@+id/webView"
     8         android:layout_width="fill_parent"
     9         android:layout_height="fill_parent"
    10         android:layout_above="@+id/linearLayout"
    11          />
    12     <LinearLayout 
    13         android:id="@+id/linearLayout"
    14         android:layout_width="match_parent"
    15         android:layout_height="wrap_content"
    16         android:layout_alignParentBottom="true"
    17         >
    18         <Button
    19             android:id="@+id/btn"
    20             android:layout_width="wrap_content"
    21             android:layout_height="wrap_content"
    22             android:text="Java调用JavaScript接口"
    23             >
    24         </Button>
    25     </LinearLayout>
    26 </RelativeLayout>

     java代码:

     1 private WebView webView;
     2     private Handler handler = new Handler();
     3     private Button button;
     4     @SuppressLint("SetJavaScriptEnabled")
     5     @Override
     6     protected void onCreate(Bundle savedInstanceState) {
     7         super.onCreate(savedInstanceState);
     8         setContentView(R.layout.activity_main);
     9         webView = (WebView) findViewById(R.id.webView);
    10         
    11         //自定义webView设置
    12         WebSettings webSettings = webView.getSettings();
    13         webSettings.setJavaScriptEnabled(true);
    14         webView.addJavascriptInterface(new MyJavaScriptInterface(MainActivity.this), "javaInterface");
    15         //如果注释了,javaScript中的alert弹窗等就会失效,不显示
    16         webView.setWebChromeClient(new WebChromeClient());
    17         //webView.setWebChromeClient(new MyWebChromeClient());
    18         
    19         //测试webView加载是否正常
    20         //webView.loadUrl("http://www.baidu.com/");
    21         webView.setWebViewClient(new HelloWebView());
    22         webView.loadUrl("file:///android_asset/index.html");
    23         
    24         button = (Button) findViewById(R.id.btn);
    25         button.setOnClickListener(new View.OnClickListener() {
    26             
    27             @Override
    28             public void onClick(View v) {
    29                 String param = "bb";
    30                 webView.loadUrl("javascript:showTitle('"+param+"')");
    31             }
    32         });
    33     }
    34 
    35     private  class HelloWebView extends WebViewClient{
    36         @Override
    37         public boolean shouldOverrideUrlLoading(WebView view, String url) {
    38             // TODO Auto-generated method stub
    39             view.loadUrl(url);
    40             return true;
    41         }        
    42     }
    43     
    44     /**
    45      * 在主线程中定义JavaScript可以调用的安卓接口
    46      * @author CHQ
    47      * API 17以后,每个被调用java函数都要叫声明 @JavascriptInterface
    48      */
    49     public class MyJavaScriptInterface{
    50         private Context context;
    51         
    52         public MyJavaScriptInterface(Context context){
    53             this.context = context;
    54         }
    55         @JavascriptInterface
    56         public String toString() {
    57             return "this is interface";
    58         }
    59         @JavascriptInterface
    60         public void clickOnAndroid() {
    61             Toast.makeText(context, "js调用安卓:....", Toast.LENGTH_SHORT).show();
    62         }
    63         /**
    64          * 安卓调用JS接口,要开启子线程调用
    65          */
    66         @JavascriptInterface
    67         public void call() {
    68             Toast.makeText(context, "安卓客户端再调用JavaScript接口", Toast.LENGTH_SHORT).show();
    69             handler.post(new Runnable() {            
    70                 @Override
    71                 public void run() {
    72                     String param = "bb";
    73                     webView.loadUrl("javascript:showTitle('"+param+"')");
    74                 }
    75             });
    76             
    77         }
    78         
    79     }

    其中:有几点必须注意的,网上早期关于WebView的描述中,有几点变化。1)安卓4.2以上的版本中使用WebView实现Java与Js互调,java接口需要声明@JavascriptInterface ; 2)WebView要调用setWebChromeClient(),以适应Js等弹窗等实现;3)addJavascriptInterface中绑定的接口中调用JavaScript接口,需要开启子线程来调用(报错:Caused by: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. );

    HTML代码:

    <html>
        <script type="text/javascript">
            //安卓定义的接口1
            function callAndroidInterface() {
                window.javaInterface.clickOnAndroid();
            }
            //
            function showTitle(param) {
                alert("传参:"+param);
                var x = document.getElementById("title");
                alert("标题:"+x.innerHTML);
            }
        </script>
        <body>
        <h3 id="title">关于安卓与JavaScript的交互</h3>
        <input  type="button" value="调用接口1" onclick="callAndroidInterface()"></input>    
        <input  type="button" value="测试接口可用性" onclick="showTitle('aa')"></input>    
        <input  type="button" value="调用接口2" onclick="window.javaInterface.call()"></input>
        
        </body>
    </html>

     以上html文件,其中javaInterface就是webView中addJavacriptInterface()方法中注入的接口入口名称,通过该名称就可以直接调用Java中的接口。(该html页面需要保持到项目assets目录中,由webView.loadUrl("file:///android_asset/index.html")来加载);

    效果图:

     
    其中,对话框弹出:网址为"file://"的网页显示:,如果是服务器上的web页面就会显示源IP地址等等,显然不是我们想要的。下一篇,我们可以重写WebChromeClient来修改对话框、确认框等webView的优化。
  • 相关阅读:
    EzHttp 流传输调用代码示例
    使用EzHttp框架 开发基于HTTP协议的CS轻应用
    [转]Installing Memcached on Windows
    SQLiteServer+SQLiteClient 用于.Net项目的SQLite服务端程序和客户端类库
    ERROR: Pillow-5.2.0-cp35-cp35m-win_amd64.whl is not a supported wheel on this platform.
    Linux下的tar压缩解压缩命令详解
    scp 基于 SSH 的安全远程服务器文件拷贝
    大批量删除列表中元素的方法,自己用本办法做的
    Python 列表 pop() 方法
    可遍历的数据对象enumerate() 方法的使用
  • 原文地址:https://www.cnblogs.com/chq3272991/p/5283667.html
Copyright © 2011-2022 走看看