1. 程式人生 > >WebView與JavaScript交互--Android

WebView與JavaScript交互--Android

btn 讀取 toa hand xmlns url get div util


轉載請註明出處: http://blog.csdn.net/forwardyzk/article/details/46819925


在工作中,有一個這種需求,須要用到WebView與javascript進行交互,以下我們就通過一個簡單的需求來介紹.

先看一下效果圖:


技術分享

需求:

1.點擊一個button進入一個載入WebView的界面,假設此界面須要分享此界面到其它平臺,那麽就在當前界面展示"分享"button,假設不須要分享,那麽就不展示"分享"button.

2.在H5界面上,有一個登陸button,點擊登陸,

2.1 假設沒有登陸,則調起登陸界面,登陸成功後,在H5界面展示登陸者.

2.2 假設登陸了,就在H5界面直接顯示當前的登陸者.

1.使webview支持js的調用.

webview.addJavascriptInterface(new JsHost(JsActivity.this, mHandler, webview), "jsObject");

當中JsHost是自己定義的一個類, jsObject是H5頁面調用clientjs方法的對象(名字也是自己定義的,僅僅要和H5javascriprt用的對象名字一樣就可以).


2.分享需求.

當H5頁面載入完成後,H5頁面調用client是否分享的方法(通過此方法講是否分享和分享的內容傳遞給client),然後控制分享button是否展示

H5頁面javascrip方法:

window.onload = function share() {
	//分享
	var json = "{‘isShare‘:0,‘shareContent‘:‘我是分享內容‘}";
	//不分享
	var noShare = "{‘isShare‘:-1}";
	window.jsObject.toShare(json);
}

這是H5調用client的javascript方法

window:代表當前頁面的對象

window.onload表示當前的H5頁面載入完成後,調用後面的方法

json:表示須要分享的json字符串

noshare:表示不分享額json字符串

jsObject:是client定義的javascript對象

toShare(json):client的javascript方法,這樣在client就能夠收到json字符串.(這裏傳的是須要分享的json字符串)


在client的JsHost中定義javascript的分享方法

 /**
     * 分享的方法
     *
     * @param json
     */
    @JavascriptInterface
    public void toShare(String json) {
        Log.d(TAG, "web:" + json);

        try {
            JSONObject jsonObject = new JSONObject(json);
            int isShare = jsonObject.optInt("isShare");
            if (isShare == 0) {//表示須要分享
                mHandler.sendEmptyMessage(0);
            } else if (isShare == -1) { //表示不須要分享
                mHandler.sendEmptyMessage(1);
            }
        } catch (JSONException e) {
            Log.d(TAG, "解析異常");
        }
    }

首先要添加標識javascript的註解,@JavascriptInerface

解析傳遞過來的json字符串,通過Handler對象發送消息來控制分享button是否展示


在JsActivity方法中定義了mHandler,通過WebView的設置addJavascriprtInterface方法傳遞給了JsHost類中

JsActivty相應的不局文件:

activity_js.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn_share"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="分享" />


    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/btn_share"></WebView>
</RelativeLayout>


private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {//顯示分享
                btnShare.setVisibility(View.VISIBLE);//顯示分享button
            } else if (msg.what == 1) {//隱藏分享button
                btnShare.setVisibility(View.GONE);//隱藏分享button
            } else if (msg.what == 2) {//調用登錄
                Intent intent = new Intent(JsActivity.this, LoginActivity.class);
                startActivityForResult(intent, JsActivity.RESULT_OK);
            }
            super.handleMessage(msg);
        }
    };


3.登陸需求

3.1點擊登陸,假設沒有登陸,彈起登陸界面

先看H5頁面點擊登陸,調用client的js方法

<input id="loginName" type="button" onclick="isLogin()" value="登錄">

function isLogin() {
	var name = window.jsObject.requestToken();
	document.getElementById("loginName").value = name;
}


點擊"登錄",調用了javascript中的isLogin()方法,在isLogin方法中調用client的requestToken()方法.此requestToken()有返回值,返回值是當前登陸者的名字.


client的requestToken方法

    /**
     * 請求登陸者
     *
     * @return
     */
    @JavascriptInterface
    public String requestToken() {
        if (TextUtils.isEmpty(App.getName())) {
            mHandler.sendEmptyMessage(2);
        }
        Log.d(TAG, "登陸者名字" + "name=" + App.getName());
        return TextUtils.isEmpty(App.getName()) ? "未登錄" : App.getName();
    }


當中App操作登陸者的信息,有寫入登陸者信息和讀取登陸者信息
假設App.getName()獲取登陸者的名字,假設為空,則通過mHandelr方法調起登錄界面的通知.同一時候將當前登陸者返回給H5頁面.

Intent intent = new Intent(JsActivity.this, LoginActivity.class);
                startActivityForResult(intent, JsActivity.RESULT_OK);

通過startActivityForResult方法開啟登陸頁面

startActivityForResult的用法請參考:點擊

看一下登陸頁面:

activity_login.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="10dp"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/name_des"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="name:" />

        <EditText
            android:id="@+id/edit_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@id/name_des" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="20dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/pass_des"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="pass:" />

        <EditText
            android:id="@+id/edit_pass"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@id/pass_des" />
    </RelativeLayout>

    <Button
        android:id="@+id/btn_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="Login" />
</LinearLayout>

當點擊了loginbutton,運行登陸操作

private void login() {
        String name = editName.getText().toString().trim();
        String pass = editPass.getText().toString().trim();
        if (TextUtils.isEmpty(name)) {
            Toast.makeText(getApplicationContext(), "name is empty", Toast.LENGTH_SHORT).show();
            return;
        } else if (TextUtils.isEmpty(pass)) {
            Toast.makeText(getApplicationContext(), "pass is empty", Toast.LENGTH_SHORT).show();
            return;
        } else {
            App.writeLoginInfo(name, pass);
            setResult(JsActivity.RESULT_OK);
            finish();
        }
    }

登陸成功後,把name和pass存到了App中

public class App extends Application {
    private static SharedPreferences sharedPreferences;

    @Override
    public void onCreate() {
        super.onCreate();
        sharedPreferences = getApplicationContext().getSharedPreferences("login", Context.MODE_PRIVATE);
    }

    public static void writeLoginInfo(String name, String pass) {
        sharedPreferences.edit().putString("name", name).putString("pass", pass).commit();
    }

    public static String getName() {
        return sharedPreferences.getString("name", "");
    }
}


同一時候在JsActivity中的onActivityResult方法中獲取到通知,然後調用H5頁面的loginSuccess方法,傳遞給H5client的登錄者

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RESULT_OK) {

            String name = App.getName();
            name = TextUtils.isEmpty(name) ?

"未登錄" : name; Log.d(TAG, "onActivityResult:" + "name=" + name); //調用H5的javascript中的loginSuccess方法 webview.loadUrl("javascript:loginSuccess(‘" + name + "‘)"); } }


webview.loadUrl("javascript:loginSuccess(‘"+name+"‘)");

這是client調用H5中的javascript的方法.

function loginSuccess(name) {
	document.getElementById("loginName").value = name;
}

講name賦給id為loginName控件的value屬性.

loginSuccess:是H5中的javascript方法

name:是方法參數



總結:

使用webview的addJavascriprtInterface(操作的對象,"javascript對象名稱");

H5調用client方法:

無返回值: window.javascript對象.clientjs方法;

有返回值: var value=window.javascript對象.clientjs方法;

client調用H5的方法:

webview.loadUrl("javascript:方法名稱(參數)");

webview.loadUrl("javascript:方法名稱()");

到此WebView與javascript方法互相調用已經解說完成,希望對大家有幫助,有不足之處往大家指出.


源代碼下載: server和client的源代碼


WebView與JavaScript交互--Android