Android WebView call React Js Code

    Recently the company projects require a combination of Android H5 page load speed up productivity. The front page using the more popular writing React, due to the special nature of React, it is difficult to use conventional in the Android

mWebView.evaluateJavascript ( "xxx ()") to find a way to call the object methods React. Study a little compilation mechanism React if webpack packed js js generated bundle.js this is a very long immediately execute the function, which can not lead us to call, classes and methods previously written.

Solution:

   React instance of the class to write ES6 exposed to the window on it.

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); that is the focus, so you can call window.updateValue in Java end (); to achieve interaction and React js

Java-side code:

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 返回的结果
                        }
                    });
                }
            });
        }
    }
}

 

Published 35 original articles · won praise 9 · views 30000 +

Guess you like

Origin blog.csdn.net/ZHOUYONGXYZ/article/details/82760929