android 的webview调用php服务器js , js 调用Android的webview
来源:互联网 发布:迅雷 2.7.5 mac 破解 编辑:程序博客网 时间:2024/05/22 11:30
最近项目的需求: Android通过webView调用php的数据 , 这时候是需要整理webview和JavaScript之间相互调用的时候了
一. 理清思路:
(1) . 双方都是客户端 , 一个是Android , 一个是js( js当然是客户端 , 后面说明)
(2) . Android的webview需要支持JavaScript , 即
WebSettings settings = myWebView.getSettings();settings.setJavaScriptEnabled(true);
(3) 注意设置网络权限 , 因为这里调用的js是在远程服务器端
<uses-permission android:name="android.permission.INTERNET" />
(4) 设置webview实现的相关接口 , 注意顺序:
(1 . 设置JavaScript调用Android接口webView.addJavascriptInterface(new JsInteration(), "control");(2 . 设置webView提供网页加载的各个阶段的通知webView.setWebChromeClient(new WebChromeClient() {});(3 . 设置提供网页加载过程中提供的数据内容webView.setWebChromeClient(new MyWebChromeClient());(4 . 最后 , 设置webView加载网页URLwebView.loadUrl(mConn_url);
二 . 贴上代码 , 然后分解
package com.lxj.sdk.webView.demo;import android.content.pm.ActivityInfo;import android.graphics.Bitmap;import android.net.Uri;import android.net.http.SslError;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v4.app.FragmentActivity;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.webkit.JavascriptInterface;import android.webkit.JsPromptResult;import android.webkit.JsResult;import android.webkit.SslErrorHandler;import android.webkit.WebChromeClient;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;import android.widget.Button;import android.widget.RelativeLayout;import android.widget.TextView;/** * Created by xiaojun.lan on 2016/6/21. */public class TestWebViewActivity extends FragmentActivity implements View.OnClickListener { private static final String TAG = "StartActivity"; private static final int TOTAL_FEE = 1; private WebSettings setting; private String mConn_url; private Integer total_fee; ///////////////////////////////view private WebView webView; private TextView webView_title; private RelativeLayout pay_layout; private TextView price; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); pay_layout.setVisibility(View.VISIBLE); if (msg.what == TOTAL_FEE) { price.setText(total_fee); } } }; private Button gopay; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); featureNoTitle(); setContentView(R.layout.start); //初始化数据 initData(); //初始化视图 initView(); //设置监听 initOnlistener(); } private void initData() { mConn_url = "http://www.lovewild.pub"; } private void initOnlistener() { gopay.setOnClickListener(this); } private void initView() { webView = (WebView) findViewById(R.id.webView); webView_title = (TextView) findViewById(R.id.webView_title); pay_layout = (RelativeLayout) findViewById(R.id.pay_layout); price = (TextView) findViewById(R.id.price); gopay = (Button) findViewById(R.id.gopay); } @Override protected void onResume() { super.onResume(); loadURLInAndroid(); } @Override public void onClick(View v) { if (v.getId() == R.id.gopay) {// Intent intent = new Intent(TestWebViewActivity.this, NextActivity.class);// startActivity(intent); } } ///////////////////////////////////////////////////////////////////////////////////////// /** * 当退出加载webView的Activity时 , 记得将webView销毁 */ @Override protected void onDestroy() { super.onDestroy(); webView.destroy(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) { webView.goBack(); // goBack()表示返回WebView的上一页面 return true;//这里返回true , 表示webview返回到初始页面时 , 不会退出应用 } else { finish(); } return super.onKeyDown(keyCode, event); } /** * 设置webView的属性 */ private void loadURLInAndroid() { setting = webView.getSettings(); webView.setHorizontalScrollbarOverlay(false); webView.setHorizontalScrollBarEnabled(false); webView.requestFocus(); webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);//滚动条风格,为0指滚动条不占用空间,直接覆盖在网页上 /** * 设置js调用Android的接口 */ webView.addJavascriptInterface(new JsInteration(), "control"); /** * 提供网页加载各阶段的通知 * */ webView.setWebViewClient(new MyWebViewClient()); /** * 提供网页加载过程中提供的数据内容 * */ webView.setWebChromeClient(new MyWebChromeClient()); webView.loadUrl(mConn_url); } /** * js调用和传递的数据 * 类JsInteration里面的方法被js调用 * 以下三个接口都是提供给js调用的接口 * -------注意, 一定要加 @JavascriptInterface 在每个方法上面,否则无法执行 */ public class JsInteration { @JavascriptInterface public void payInfoMessage(String payInfoJson) { //js将返回payInfoJson 信息 , 具体是什么信息 , 需要js传入 , 我这里传入的是json //获取payInfoJson之后 , 就可以在这里使用了 , 最好用handler } @JavascriptInterface public void checkPaymentApp(String validate){ Log.e(TAG,"======>"+validate); } @JavascriptInterface public void onSumResult(int result) { total_fee = result ;//这里将JavaScript返回的result传递给total_fee Message mes = new Message(); mes.what = TOTAL_FEE; handler.sendMessage(mes);//使用handler来处理js返回的结果 } } class MyWebViewClient extends WebViewClient { /** * 内核加载完当前页面时会通知我们的应用程序 * 在页面加载完毕后调用网页的js,确保js完全加载,Android调用时能调用到 */ @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); setting.setBlockNetworkImage(false);//false下载图片 //try是处理getBooleanQueryParameter返回数据越界时的异常 try{ //这里是判断 , 当url的参数main_page 不为空 , 且等于checkout_confirmation或者checkout_payment //时 , 将调用JavaScript的响应方法 , 如果URL没有main_page参数 , 将调用JavaScript的onSumResult, //并且传入 "我传onSumResult给js" 这个值,注意书写格式 if(Uri.parse(url).getBooleanQueryParameter("main_page",false)){ //根据URL参数判断获取预支付订单 if(Uri.parse(url).getQueryParameter("main_page").equals("checkout_confirmation")){ //这里调用js里面的方法去请求预支付订单 String call = "javascript:payInfoMessage()"; webView.loadUrl(call); }else if(Uri.parse(url).getQueryParameter("main_page").equals("checkout_payment")){ //这里调用js里面的方法去说明是移动应用访问服务器 String call = "javascript:checkPaymentApp(\"" + "android" + "\")"; webView.loadUrl(call); pay_layout.setVisibility(View.GONE); }else{ String call = "javascript:onSumResult(\"" + "我传onSumResult给js" + "\")"; webView.loadUrl(call); pay_layout.setVisibility(View.GONE); } } }catch (Exception e){ Log.e(TAG,"getBooleanQueryParameter error"); } } /** * 内核加载当前主框架开始时调用 * 在网页还没被加载之前设置setting , 确保网页以最快速度加载 , 增加用户体验 */ @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); setting.setDefaultTextEncodingName("UTF-8");//设置字符编码 setting.setJavaScriptEnabled(true);//true加载JavaScript setting.setCacheMode(WebSettings.LOAD_DEFAULT);//是否覆盖缓存 setting.setDefaultZoom(WebSettings.ZoomDensity.FAR); setting.setSupportZoom(false);//是否支持缩放 true支持,false不支持 setting.setBuiltInZoomControls(false);//WebView是否应该使用其内置的放大机制,false不使用 setting.setDisplayZoomControls(false);//使用其内置的放大机制时,是否显示放大缩小的图标,false不显示,true显示 setting.setAppCacheEnabled(true); setting.setDomStorageEnabled(true); setting.setBlockNetworkImage(true);//true不下载图片 setting.setCacheMode(WebSettings.LOAD_DEFAULT); setting.setSavePassword(false); setting.setUseWideViewPort(false); setting.setLoadWithOverviewMode(false); } /** * 网页是否由webView显示,返回true是由浏览器显示,返回false由webView显示 */ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //webView.loadUrl(url);//不要加这行,否则将会引起正常网页加载错误 return super.shouldOverrideUrlLoading(view, url); } /** * 如果网页加载失败(超时 , 没有网络等) , 在这里处理 * @param view * @param errorCode * @param description * @param failingUrl */ @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); // 信任所有的证书 默认是handler.cancle(),即不做处理 } /** * 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。 */ @Override public void onLoadResource(WebView view, String url) { super.onLoadResource(view, url); Log.e(TAG,"无论加载图片还是js文件 ,都会调用一次"); } } final class MyWebChromeClient extends WebChromeClient { /** * 处理js返回的Alter他框 * @param view * @param url * @param message * @param result * @return */ @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { //这里弹出的框界面不友好 , 你可以使用AlertDialog.Builder来自定义弹出框 , 下同 result.confirm(); return super.onJsAlert(view, url, message, result); } /** * 处理js返回的Confirm框 * @param view * @param url * @param message * @param result * @return */ @Override public boolean onJsConfirm(WebView view, String url, String message, JsResult result) { result.confirm(); return super.onJsConfirm(view, url, message, result); } /** * 处理js返回的Prompt框 * @param view * @param url * @param message * @param defaultValue * @param result * @return */ @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { result.confirm(); return super.onJsPrompt(view, url, message, defaultValue, result); } /** * 处理网页加载过程中进度条 * @param view * @param newProgress */ @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); } /** * 获取网页标题 */ @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); webView_title.setText(title); } } /** * 设置全屏、设置无状态栏、设置竖屏 */ private void featureNoTitle() { // 设置无标题 requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置全屏 ,不显示状态栏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置横屏// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //设置竖屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); }}
服务器端的JavaScript代码:
<?php$arr = array( "age"=>"18", "name"=>"xiaojun.lan");$jsonData = json_encode($arr,true);$str = "I am come from js";$age = 18;$age = intval($age);//确保$age 是整形数据 , 避免Android出错//这里我直接在php里面调用JavaScript , php里面调用js , js可以很方便从php中获取数据 , //而php从js获取数据就需要ajax , 比较麻烦echo "<script language=\"JavaScript\" type=\"text/JavaScript\">; \r\n<!--\r\n function sayHello() { alert(\"Hello\") } //这是给Android调用的payInfoMessage function payInfoMessage() { //这是js调用Android的payInfoMessage window.control.payInfoMessage('".$jsonData."') } function checkPaymentApp(str){ window.control.checkPaymentApp('".$str."') } //这个str是Android传过来的字符串 function onSumResult(str) //这个number是js传给Android的整形数据{ window.control.onSumResult('".$age."') } function payInfoMessage() { window.control.payInfoMessage('" . $app_payInfo . "') } \r\n-->; \r\n</script>;";?>
三. 分解
1. Android 在onPageFinished 里面判断url, 当url参数为什么的情况下 , 将会调用不同的js方法 ( 同时可以传递值给js )
2. 当js方法被调用时(这里写在php代码里面) , 就回调用Android相关方法 , 并传递值给Android
3. Android接收到值之后进行处理
四. 之前忘记附上代码下载 , 这里附上了
使用方法:
1. Android代码 , 新建一个工程 , 设置网络权限
将代码TestWebViewActivity.java复制进去 , 去TestWebViewAcitity.java的XML文件中设置webview控件和button控件\TextView控件
2. 将php文件复制到你的服务器上, 获取服务器url之后 , 在Android里面更改url地址
3. 我的url只是个示范
主要代码下载地址:
http://download.csdn.net/detail/xkjscm/9570548
五. 补充 , php引用js值
这个是同事意外发现的 , 我无法明白其原理:
你也可以新建一个php文件,将下列demo测试:
<?php//JavaScript里面的变量abc值为 echo " <script> var abc = 'this is the javascript value'; </script> ";//将JavaScript的值通过此途径赋给php的变量$a $a = "<script>document.write(abc);</script>"; //在php里面讲$a打印出来 echo $a ;?>
- android 的webview调用php服务器js , js 调用Android的webview
- Android webview和js的相互调用
- android与js的调用(WebView)
- 关于android webview 调用js
- Android WebView调用js传参
- Android的WebView的使用及JS调用
- android中webView中js调用java无效的问题
- Android WebView JS不能调用Java对象的问题
- android webView调用js函数的几种方法
- android webview中调用了js的时候混淆注意事项
- android WebView 和js互调用的使用说明。
- Android 中WebView调用JS的跨域问题
- android webview中调用了js的时候混淆注意事项
- Android的WebView通过JS调用java代码
- Android WebView JS不能调用Java对象的问题
- Android中WebView和JavaScript(JS)的互相调用
- Android的WebView中js与java代码相互调用
- Android的WebView中js与java代码相互调用
- 数据分析中会常犯哪些错误,如何解决? 四
- 【命令】rm
- springmvc+bootstarp备份与恢复orcle10g数据库实现
- IE下判断IE版本的语句...[if lte IE 8]……[endif]
- 初探并查集
- android 的webview调用php服务器js , js 调用Android的webview
- 二叉树基础-由中根序列和后根序列重建二叉树(数据结构基础 第5周)
- laravel资源路由,控制器中的接收方式,详解
- 关于Fragment使用的一些见解
- HBase 高性能获取数据 - 多线程批量式解决办法
- UIImagePickerController详解
- dplyr do: Some Tips for Using and Programming
- 让Gradle支持中文 -- 关于 "编码 GBK 的不可映射字符"错误的解决
- EXTJs前后台交互 常用哦3种方式