• WebView与JavaScript交互--Android



    转载请注明出处:  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的源代码


  • 相关阅读:
    python复习-数据类型与运算
    爬虫笔记
    网络爬虫-总结
    pymongo使用方法
    Mac下,安装redis之后,启动时遇到的问题
    java实现23种设计模式之迭代器模式
    java实现23种设计模式之观察者模式
    java实现23种设计模式之模版方法模式
    java实现23种设计模式之策略模式
    jvm参数的优化
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6900682.html
Copyright © 2020-2023  润新知