Android(安卓)WebView 调用React Js 代码
16lz
2022-05-02
最近公司项目需要结合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 ( 问题和建议 上传图片 console.log(index, fs)} onAddImageClick={this.onAddImageClick} selectable={this.state.files.length < 7} multiple={this.state.multiple}/> 提交 ) }}
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 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() { @Override public void onReceiveValue(String value) { //此处为 js 返回的结果 } }); } }); } }}
更多相关文章
- 专题 - Web应用
- 如何使用Jdbc和Servlet操作Mysql数据库,编写Android登录注册服务
- android 两个应用之间的通信与调用
- Android(安卓)Intent调用方法总结
- android之Fragment(官网资料翻译)
- android横竖屏总结
- Android横竖屏+补充
- android的action
- Android(安卓)GLES多线程处理