1. 程式人生 > >Android WebView 呼叫React Js 程式碼

Android WebView 呼叫React Js 程式碼

    最近公司專案需要結合Android 載入H5 頁面加快工作效率。前端頁面採用目前比較流行的React編寫,由於React 的特殊性,我們在Android 很難使用常規的

mWebView.evaluateJavascript("xxx()") 方式來找到React 的物件方法來呼叫。研究了一下React 的編譯機制,如果webpack 打包的js生成bundle.js 這個js 中是一個很長的立即執行函式,這就導致我們根本無法去呼叫,之前寫好的類和方法。

解決方法:

   將ES6 編寫的React 類的例項暴露給window 就可以了。

mport React from 'react';
import {Tabs, Badge,ImagePicker} from "antd-mobile";
import './my.css'
import {Link} from 'react-router-dom';
import Height from '../height'
import $ from 'jquery';
import plus from '../../images/plus.png'
import VConsole from 'vconsole'

window.updateValue = function(url) {
    console.log(url);
    if(window.callback != undefined) {
        window.callback.updateValue(url);
    }
};

window.setCallback = function(callback) {
    window.callback = callback;
};

export default class MyFeedback extends React.Component {
    state = {
        files: [],
        multiple: false,
        value:"我們非常重視你的建議11"
    };

    onChange = (files, type, index) => {
        console.log(files, type, index);
        this.setState({
            files,
        });
    };

    onSegChange = (e) => {
        const index = e.nativeEvent.selectedSegmentIndex;
        this.setState({
            multiple: index === 1,
        });
    };

    onAddImageClick() {
        console.log(navigator.userAgent);
        //window.location.assign("?action=uploadimg");
        if (window.andpicker != null) {
            window.andpicker.test("hello");
        }
    }

    componentWillMount() {
        document.title = "反饋";
        var vConsole = new VConsole();
        window.setCallback(this);
    }

    updateValue(val) {
        this.setState({
            files: this.state.files.concat({
                url: val,
                id: '311',
            }),
        });
    }

    render() {
        return (
            <div style={{minHeight: 'calc(100vh - 43.5px)', backgroundColor: '#fff'}}>
                <div>
                    <div style={{padding:'8px',background:'#ccc'}}>問題和建議</div>
                    <div style={{margin:'8px'}}><input style={{height:'200px',width:'-webkit-fill-available'}} value={this.state.value} /></div>
                    <div style={{padding:'8px',background:'#ccc'}}>上傳圖片</div>
                    <div>
                        <ImagePicker
                            files={this.state.files}
                            onChange={this.onChange}
                            onImageClick={(index, fs) => console.log(index, fs)}
                            onAddImageClick={this.onAddImageClick}
                            selectable={this.state.files.length < 7}
                            multiple={this.state.multiple}/>
                    </div>
                    <div style={{margin:'8px',background:"#f00",color:'#fff',height:'20px',textAlign:'center',padding:'10px'}}>提交</div>
                </div>
                <Height></Height>
            </div>
        )
    }
}

window.setCallback(this); 就是重點,這樣可以在Java 端呼叫window.updateValue();來實現和React js 的互動

Java 端程式碼:

package com.example.jerry.h5project;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.util.HashMap;
import java.util.Map;

public class FeedbackAct extends AppCompatActivity implements AndroidPickerJs.Callback{
    private static final String TAG = FeedbackAct.class.getSimpleName();
    private static final int CHOOSE_PICTURE = 1;

    private WebView mWebView;
    private AndroidPickerJs mJsInstance;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_feedback);

        initViews();
    }

    private void initViews() {
        mJsInstance = new AndroidPickerJs();
        mJsInstance.setCallback(this);
        mWebView = findViewById(R.id.web_view);
        mWebView.setWebViewClient(mWebViewClient);
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        webSettings.setSupportZoom(true);
        mWebView.addJavascriptInterface(mJsInstance,"andpicker");

        mWebView.loadUrl("http://10.0.0.24:3000/myfeedback");
    }

    @Override
    public void selectPic() {
        choosePictures();
    }

    private WebChromeClient mWebChromeClient = new WebChromeClient() {
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
            return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
        }
    };

    private WebViewClient mWebViewClient = new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
           
            return super.shouldOverrideUrlLoading(view, request);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            Log.d(TAG,"error = " + error.toString());
            super.onReceivedError(view, request, error);
        }

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

    };

    private void choosePictures() {
        Intent intent = new Intent(
                Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, CHOOSE_PICTURE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CHOOSE_PICTURE && resultCode == RESULT_OK) {
            final Uri uri = data.getData();
            Log.d(TAG,"evaluate js script ... uri = " + uri);
            Bitmap bitmap = BitmapUtils.getBitmapFromUri(this, uri);
            final String base64str = "data:image/png;base64," + Base64Utils.bitmapToBase64(bitmap);
            Log.d(TAG,"base64 = " + base64str);
            //final String base64 = "https://zos.alipayobjects.com/rmsportal/hqQWgTXdrlmVVYi.jpeg";
            mWebView.post(new Runnable() {
                @Override
                public void run() {
                    mWebView.evaluateJavascript("window.updateValue('"+base64str+"')", new ValueCallback<String>() {
                        @Override
                        public void onReceiveValue(String value) {
                            //此處為 js 返回的結果
                        }
                    });
                }
            });
        }
    }
}

相關推薦

Android WebView 呼叫React Js 程式碼

    最近公司專案需要結合Android 載入H5 頁面加快工作效率。前端頁面採用目前比較流行的React編寫,由於React 的特殊性,我們在Android 很難使用常規的 mWebView.evaluateJavascript("xxx()") 方式來找到React

Android webview呼叫js程式碼無效 webView.loadUrl("javascript:alert('hello')")

1) WebSettings設定支援javascript mWebView.getSettings().<span style="font-family: STHeiti;">setJavaScriptEnabled(true);</span> 2) 在執行指令碼前,要有docum

android webview 呼叫微信 h5 支付方式

參考網址:http://www.2cto.com/kf/201605/505727.html http://blog.csdn.net/u010940300/article/details/51426874 最終實現: 在webview 的 setWebViewCl

ANDROID webview載入本地內容程式碼

由於我目前的應用大部分為html網頁內容,所以之前一直沿用webview.load(url)的方式來載入網頁,所以就出現了很多網頁載入很慢的情況,看網上所述大部分由載入遠端載入js,css導致的。所以就把webview.load(url)調整為載入本地內容,js和css均有

android webview呼叫微信支付

有個需求是呼叫微信支付和支付寶支付,原本以為要整合SDK,之後才知道後臺返回的是html,只需要用webview顯示出來,之前沒有接觸過這種,結果跳了幾天的坑 o(////▽////)q 傻傻地直接顯示,結果什麼都沒有顯示!!Σ(⊙▽⊙” 既然不懂,就查查吧

android WebView呼叫檔案管理器,點選返回鍵退出app的解決辦法

在清單檔案中,給含有該WebView的activity設定屬性: alwaysRetainTaskState屬性 和 configChanges屬性 這裡,我的是WebActivity: <activity android:name=".activity.We

WebView 無法執行js程式碼

下午在研究webView 與js之間的呼叫,於是到w3school上找了一個html的頁面。 html頁面: <html> <head> <script type="text/javascript"> function show

Android端使用WebView注入一段js程式碼實現js呼叫android

需求:為網頁上個連結增加點選事件,但是這個連結無法增加js程式碼 url:http://public.rongcloud.cn/view/D4F444BE2D94D760329F3CF38B4AE35C 網頁截圖: 需要給“投融資訊“四個字設定點選事件 但是觀察原始碼 &

Android webView載入html程式碼 不執行js方法的情況

頁面中有一個webView顯示後臺返回的富文字資料,富文字資料是一串html程式碼,但是並沒有<html><body>這些標籤,webView不做任何處理,使用 webView.loadData(html, "text/html; charset=U

android webview呼叫js的時候混淆注意事項

今天有一個bug,就是webview跟js互動的方法怎麼也調不起來,debug包沒問題,release包就出錯,想想是打包時混淆的問題,打了一個不混淆的包,果不其然,就是混淆的問題。 然後就找解決方案,在proguard-project檔案中有這麼一句 <span s

android webview javascriptinterface實現從HTML JS呼叫ANDROID內部程式

1. 先在ANDROID程式內部建立一個公共類,公共類內建立@JavascriptInterface標註的公共程式,以備呼叫。 public class AndroidJavaScript{ @JavascriptInterface public string mypubl

Androidjs程式碼互相呼叫

在js中,有如下程式碼: <script> //js呼叫安卓 function sendDataToAndroid(){ //呼叫android程式中的方法,並傳遞引數。 var name = document.getE

android webview java呼叫js方法沒反應

之前公司寫了一個功能,需要呼叫H5介面,並且在H5介面裡面呼叫本地方法獲取照片,通過webview.loadUrl()方法再將照片流傳給伺服器。 本身呢,這個功能不是我做的,我對這塊使用也並不是特別清楚,測試真是個好測試,公司的測試機不夠,他們就給爸媽重新買了新的手機,把他

JS 呼叫IOS Android webview方法

JS 呼叫IOS webview方法 《html》   <div  onclick="authCheckLogin()"> 《JavaScript》 function authCheckLogin() {try { //JS 呼叫android webView

android webview 運用小結(選取圖片,js呼叫,混淆保留,cookie問題,高低版本問題)

由於專案需求,對webview要進行大量運用,所以對webview進行了一番學習與研究。廢話不多說,直接按流程進行。 首先,關於webview的基本的內容,簡單描述一下,作為記錄。     1、關於返回上個頁面:重寫一下 onKeyDown() 或者 onKeyUp() ,

android webview呼叫js的時候混淆失效問題

轉自他人: 今天有一個bug,就是打包簽名後,webview跟js互動的方法怎麼也調不起來,debug包沒有問題,release包就出錯,想想是打包時混淆的問題,打了一個不混淆的包,果不其然,就是混淆的問題。 然後就找解決方案,在proguard-project檔案中有這

安卓與JS互調之android webview addJavascriptInterface 的方法不能呼叫

以前一直覺著用HTML5做Android app是一件很雞肋的事(勿噴,請恕小的見識少)。 後來又發現很多大公司做的app中都或多或少的使用了html元素,比如微信、qq之類。 最近在網上閒逛發現一個IDE可以使用純html js css設計app併發布到多個平臺,並

Android WebView 加載超長 JS 數據

int strong catch [] size set native logs 業務 在之前的文章裏面,我總結過WebView如何與網頁交互,也就是Java如何和JS交互 —— Android WebView 總結 —— Java和JavaScript交互。 基於這篇文章

android webview JS傳值 prompt

near gravity should 使用 sre pen you eat fir 1. <!DOCTYPE html> <html style="min-height: 100%"> <head> <meta cha

Webview呼叫Android相機,錄影,相簿遇到的坑

轉自:https://blog.csdn.net/a_running_wolf/article/details/77983739   今天拿到一個h5頁面,發現需要呼叫到Android系統相簿,錄影,相機的時候,任你怎麼點選上傳圖片,死活沒有反應,奇怪的是,使用瀏覽器和微信直接載入