美文网首页
Android与H5交互

Android与H5交互

作者: 夜行者_姚 | 来源:发表于2019-08-15 17:18 被阅读0次

1、项目做了N个版本,整理一下用到的一些知识,Android与JS交互

由于Api最低是19,所以就不考虑17以前的方法了。下面是自己重写的webview,可以参考使用

public class SuperWebView extends WebView {

    private Context context;

    private WebViewCallback viewCallback;

    private Gson gson = new Gson();

    private boolean isNoFresh;

    private int width;

    private String specificUserId;

    public SuperWebView(Context context) {

        super(context);

        initView(context);

    }

    public SuperWebView(Context context, AttributeSet attrs) {

        super(context, attrs);

        initView(context);

        initAttr(context, attrs);

    }

    public SuperWebView(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        initView(context);

        initAttr(context, attrs);

    }

    @Override

    protected void onConfigurationChanged(Configuration newConfig) {

        super.onConfigurationChanged(newConfig);

    }

    private void initAttr(Context context, AttributeSet attrs) {

    }

    private void initView(Context context) {

        this.context = context;

        width = AppUtils.getScreenDispaly(context)[0];

        initErrorPage();

        setVerticalScrollBarEnabled(false);

        WebSettings webSettings = getSettings();

        webSettings.setJavaScriptEnabled(true);

        webSettings.setAllowFileAccess(true);// 设置允许访问文件数据

        webSettings.setSupportZoom(false);

        webSettings.setBuiltInZoomControls(true);

        webSettings.setDomStorageEnabled(true);

        webSettings.setDatabaseEnabled(true);

        webSettings.setTextZoom(100);

        webSettings.setUseWideViewPort(true);

        webSettings.setSupportZoom(true);

        webSettings.setLoadWithOverviewMode(true);

        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            webSettings.setMixedContentMode(webSettings.getMixedContentMode());

        }

        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

        webSettings.setBlockNetworkImage(false);

        setWebViewClient(new WebViewClient() {

            @Override

            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                view.loadUrl(url);

                return super.shouldOverrideUrlLoading(view, url);

            }

            @Override

            public void onReceivedError(WebView webView, int i, String s, String s1) {

                isError = true;

                super.onReceivedError(webView, i, s, s1);

            }

            @Override

            public void onReceivedHttpError(WebView webView, WebResourceRequest webResourceRequest, WebResourceResponse webResourceResponse) {

                isError = true;

                super.onReceivedHttpError(webView, webResourceRequest, webResourceResponse);

            }

            @Override

            public void onPageStarted(WebView view, String url, Bitmap favicon) {

                if (viewCallback != null) {//回调方法

                    viewCallback.loadShow();

                }

                webUrl = url;

                isFinish = false;

                super.onPageStarted(view, url, favicon);

            }

            @Override

            public void onPageFinished(WebView view, String url) {

                if (isError && !isFinish) {

                    mHandler.sendEmptyMessageDelayed(1, 0);

                    isFinish = true;

                    isError = false;

                    showErrorPage();

                }

                if (!isFinish) {

                    jsGetParams(jsParams);

                    hideErrorPage();

                    mHandler.sendEmptyMessageDelayed(1, 800);

                    isFinish = true;

                }

                super.onPageFinished(view, url);

            }

        });

//主要在此方法  将Android里面定义的类对象AndroidJs暴露给javascript

//new JavascriptInterface()用来管理交互代码  Androidports 约定标识 (可以自己定义)

        addJavascriptInterface(new JavascriptInterface(), "Androidports");

    }

@Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

if (width != 0) {

                int mExpandSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);

                super.onMeasure(mExpandSpec, heightMeasureSpec);

            } else {

                super.onMeasure(widthMeasureSpec, heightMeasureSpec);

            }

    }

    private boolean isFinish = false;

    private boolean isError = false;

    public void setWebChromeClients(WebChromeClient webChromeClient) {

        setWebChromeClient(webChromeClient);

    }

    public void setNoFresh(boolean b) {

        isNoFresh = b;

    }

    private Handler mHandler = new Handler(Looper.getMainLooper()) {

        @Override

        public void handleMessage(Message msg) {

            if (msg.what == 1) {

                if (viewCallback != null) {

                    viewCallback.loadHide();

                }

            } else if (msg.what == 2) {

                if (titleCallback != null) {

                    titleCallback.titleChange((String) msg.obj);

                }

            }

        }

    };

    /**

    * 每次打开域名时都调下方法 jsGetParams 把参数传递过来

    */

    private String jsParams = "";

    private String webUrl = "";

    public void setJsParams(Map<String, String> map) {

        Map<String, String> map2 = publicParameters(map);

        JSONObject json = new JSONObject(map2);

        jsParams = json.toString();

    }

    public void jsGetParams(String s) {

        String str = "javascript:jsGetParams(" + s + ")";

        this.evaluateJavascript(str, new ValueCallback<String>() {

            @Override

            public void onReceiveValue(String s) {

                String ss = s;

            }

        });

    }

    /**

    * 发送信息 java 调用中的方法

    */

    public void sendCommentsMsg(String info) {

        String str = "javascript:jsSendMsg(" + info + ")";

        this.evaluateJavascript(str, new ValueCallback<String>() {

            @Override

            public void onReceiveValue(String s) {

            }

        });

    }

//同理 java 调用js方法 加载更多 jsAddMore次参数是js中的方法。

    public void jsAddMore() {

        this.evaluateJavascript("javascript:jsAddMore()", new ValueCallback<String>() {

            @Override

            public void onReceiveValue(String s) {

            }

        });

    }

    private class JavascriptInterface extends Object {

        private JavascriptInterface() {

        }

//必须要用注解,否则不对

        @android.webkit.JavascriptInterface

        public void getContentWidth(String info) {

            String ss = info;

        }

//必须要用注解,否则不对

        @android.webkit.JavascriptInterface

        public void sendFirstLoadOver() {

            VideoHighlightsActivity.isFirstLoadOver = true;

        }

//必须要用注解,否则不对 in就是js传入的参数,一般是json对象,然后自己解析,根据类型做判断,做出相应操作

        @android.webkit.JavascriptInterface

        public void sendInfo(String info) {

            if (!TextUtils.isEmpty(info)) {

                Bean bean = gson.fromJson(info, Bean.class);

                if (TextUtils.equals("MethodeType", bean.getType())) {

                  //自己操作

                } else {

                    WebBean lBean = gson.fromJson(info, WebBean.class);

                    Intent intent = new Intent();

                    switch (lBean.getType()) {

                        case "OpenMain":

                            //跳转 最好自己先判断一下连击

                            intent.setClass(context, MainActivity.class);

                            intent.putExtra("WebBean", lBean);

                            context.startActivity(intent);

                            break;

                        default:

                            break;

                    }

                }

            }

        }

    }

//传入一些公共参数

    public Map<String, String> publicParameters(Map<String, String> map) {

        if (map == null) {

            map = new HashMap<>();

        }

        map.put("uid", uid);

        map.put("token", token);

        map.put("appid", appId);

        return map;

    }

    /**

    * 显示自定义错误提示页面,用一个View覆盖在WebView

    */

    private void showErrorPage() {

        try {

            RelativeLayout layout = (RelativeLayout) this.getParent();

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);

            if (mErrorView.getParent() != null) {

                ((RelativeLayout) mErrorView.getParent()).removeView(mErrorView);

            }

            layout.addView(mErrorView, layoutParams);

        } catch (Exception e) {

        }

    }

    private void hideErrorPage() {

        try {

            if (mErrorView.getParent() != null) {

                ((RelativeLayout) mErrorView.getParent()).removeView(mErrorView);

            }

        } catch (Exception e) {

        }

    }

    /***

    * 显示加载失败时自定义的网页

    */

    private View mErrorView;

    private void initErrorPage() {

        if (mErrorView == null) {

            mErrorView = View.inflate(context, R.layout.layout_load_error, null);

            mErrorView.findViewById(R.id.load_web_error_tv).setOnClickListener(new OnClickListener() {

                @Override

                public void onClick(View v) {

                    if (!StringUtil.isEmpty(webUrl)) {

                        loadUrl(webUrl);

                    }

                }

            });

        }

    }

    /**

    * 设置web的回调方法

    *

    * @param callback

    */

    public void setWebViewCallback(WebViewCallback callback) {

        viewCallback = callback;

    }

    /**

    * 回调接口

    */

    public interface WebViewCallback {

        void loadHide();

        void loadShow();

    }

    /**

    * 如果想要加入其它回调,请按照此方法添加即可

    *

    * @param callback

    */

    public void setTitleCallback(TitleCallback callback) {

        titleCallback = callback;

    }

    public interface TitleCallback {

        void titleChange(String change);

    }

}

相关文章

网友评论

      本文标题:Android与H5交互

      本文链接:https://www.haomeiwen.com/subject/ctazjctx.html