Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android 的webview調用php服務器js , js 調用Android的webview

android 的webview調用php服務器js , js 調用Android的webview

編輯:關於Android編程

最近項目的需求: Android通過webView調用php的數據 , 這時候是需要整理webview和JavaScript之間相互調用的時候了

一. 理清思路:
(1) . 雙方都是客戶端 , 一個是Android , 一個是js( js當然是客戶端 , 後面說明)
(2) . Android的webview需要支持JavaScript , 即

WebSettings settings = myWebView.getSettings();
settings.setJavaScriptEnabled(true);

(3) 注意設置網絡權限 , 因為這裡調用的js是在遠程服務器端

(4) 設置webview實現的相關接口 , 注意順序:


(1 . 設置JavaScript調用Android接口
webView.addJavascriptInterface(new JsInteration(), "control");
(2 . 設置webView提供網頁加載的各個階段的通知
webView.setWebChromeClient(new WebChromeClient() {});
(3 . 設置提供網頁加載過程中提供的數據內容
webView.setWebChromeClient(new MyWebChromeClient());
(4 . 最後 , 設置webView加載網頁URL
webView.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) {

            result =   total_fee;//這裡將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代碼:

"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</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只是個示范

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved