1. 程式人生 > >Android與H5介面的互動(引數互傳)以及遇到的一些問題

Android與H5介面的互動(引數互傳)以及遇到的一些問題

前言

在開發專案時,有部分介面是H5介面,原本以為直接載入H5介面就能搞定,後來還是遇到引數互傳問題了,然後網上意見不一,只好自己摸索,下面就給大家聊聊我遇到的問題~~~

1.先給大家看看成功之後的介面跳轉:

這裡寫圖片描述

解釋一下:
介面跳轉流程: 首頁的限時特賣–>限時特賣的H5介面–>商品詳情頁.

(1)由App原生介面跳轉

由首頁的限時特賣進入顯示特賣的H5介面:
直接將後臺返回的H5連結載入到WebView介面,對大家來說肯定沒有絲毫難度吧,在這裡就不粘程式碼了

(2)從H5的商品列表頁進入到商品詳情頁時需要商品的id,這就真正的涉及到與H5的互動了,看程式碼:

public class MyGoods {
    Context context;

    public MyGoods(Context context) {
        this.context = context;
    }

    //該方法將暴露給js呼叫,打來商品詳情頁
    @JavascriptInterface
    public void getCall(String goodsid) {
        Intent intent = new Intent(context, GoodsDetailsAct.class);
        intent.putExtra("goods_id"
, goodsid); context.startActivity(intent); } }

定義一個全域性的類,在這個類裡面只需要寫一個Intent,開啟商品詳情頁,並將id傳過去;MyGoods中的方法使用@JavascriptInterface修飾,因此會將這兩個方法暴露給JS指令碼,則允許JS指令碼通過MyGood來呼叫MyGoods裡面的方法:

然後我自己封裝了一個關於公共的載入WebView的類:
初始化完成之後作如下操作:

WVJBWebView.getSettings().setJavaScriptEnabled(true);
WVJBWebView.addJavascriptInterface
(new MyGoods(PublicWebViewAct.this), "MyGood");

第一行程式碼開啟了JS呼叫Android方法的功能;第二行則負責將Android應用中的MyGoods物件暴露給JS指令碼;

前端的同學在他的程式碼裡只寫了一下這行程式碼:

MyGood.getCall(goods_id);

最後就大功告成了,點選的條目的Id就傳過來了~~~

2.在與H5互動過程中遇到其他的問題

(1) 我們H5介面比較多,然後我們的介面的標題欄用的都是原生的,然後前端同學就把自己H5介面的標題欄給幹掉了,之後就需要獲取標題,然後就在網上找到了這個方法:

這裡寫圖片描述

每次載入新的介面就能獲取到該H5介面的標題,當然了,這也離不開H5同學的配合哦~~

(2) 關於H5介面在Android5.0 以上系統載入報錯的問題:

if (android.os.Build.VERSION.SDK_INT >= 21) {
            WVJBWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

        }

在載入資料之前做個判斷就行了,設定上面的屬性就沒問題了;

(3) 在一個比較複雜的H5介面需要呼叫系統的相簿和攝像頭,在呼叫時 APP崩潰:

WVJBWebView.setWebChromeClient(new WebChromeClient() {

            // For Android < 3.0
            public void openFileChooser(ValueCallback<Uri> valueCallback) {
                uploadMessage = valueCallback;
                openImageChooserActivity();
            }

            // For Android  >= 3.0
            public void openFileChooser(ValueCallback valueCallback, String acceptType) {
                uploadMessage = valueCallback;
                openImageChooserActivity();
            }

            //For Android  >= 4.1
            public void openFileChooser(ValueCallback<Uri> valueCallback,
                                        String acceptType, String capture) {
                uploadMessage = valueCallback;
                openImageChooserActivity();
            }

            // For Android >= 5.0
            @Override
            public boolean onShowFileChooser(WebView webView,
                                             ValueCallback<Uri[]> filePathCallback,
                                             WebChromeClient.FileChooserParams fileChooserParams) {

                uploadMessageAboveL = filePathCallback;
                openImageChooserActivity();
                return true;
            }
        });

開啟相簿的方法:


    private void openImageChooserActivity() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        startActivityForResult(Intent.createChooser(i,"ImageChooser"),FILE_CHOOSER_RESULT_CODE);
    }

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == FILE_CHOOSER_RESULT_CODE) {
            if (null == uploadMessage && null == uploadMessageAboveL) return;
            Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
            if (uploadMessageAboveL != null) {
                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (uploadMessage != null) {
                uploadMessage.onReceiveValue(result);
                uploadMessage = null;
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
        if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
            return;
        Uri[] results = null;
        if (resultCode == Activity.RESULT_OK) {
            if (intent != null) {
                String dataString = intent.getDataString();
                ClipData clipData = intent.getClipData();
                if (clipData != null) {
                    results = new Uri[clipData.getItemCount()];
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        results[i] = item.getUri();
                    }
                }
                if (dataString != null)
                    results = new Uri[]{Uri.parse(dataString)};
            }
        }
        uploadMessageAboveL.onReceiveValue(results);
        uploadMessageAboveL = null;
    }

在載入WebView時遇到的主要問題就是這些了,只是給大家單純的做一個實用的程式碼總結,做到上手能用就行,想了解更多底層原理的同學需要自己努力了哦~~我只是個小菜鳥

需要我那個公共的WebView的同學可以私信或者加我QQ哦,祝大家工作順利~~~