背景

本人工作中日常使用React开发H5页面较多,最近有需要写一个安卓App,于是简单学习了一下安卓的基础。本文将介绍如何在安卓WebView中嵌入React页面,快速搭建一个安卓应用。本文适合那些想快速搭建一个安卓APP的H5开发。本文还包括页面通过JavaScript与原生交互的简单例子。

React

本文默认你是一个比较熟悉React的前端开发。如不熟悉可以参考React官方的QuickStart

创建完成后执行npm run build打包,工程目录下面将生成build文件夹,打开build下的index.html即可查看我们开发好的React页面,后面我们将会用到。

如果打开是空白,需要在package.json里面添加一行配置:

{
	"homepage": "."
}

安卓

安卓直接新建一个项目,选择Empty Activity。一路next最后生成一个页面显示HelloWorld项目。如下新建一个AssetsFolder,将上一步生成的build文件夹放入安卓工程的assets文件夹里。
在这里插入图片描述

放入assets文件夹:
在这里插入图片描述

修改MainActivity.java如下,记得按提示导入所需的库


public class MainActivity extends AppCompatActivity {
    private long exitTime = 0;
    private WebView webView;
    private EditText edit_text;
    private Button test_button;
    private TextView text;
    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        webView = new WebView(this);
        getSupportActionBar().hide();
        webView.setWebViewClient(new WebViewClient() {
            //设置在webView点击打开的新网页在当前界面显示,而不跳转到新的浏览器中
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                view.loadUrl(request.getUrl().toString());
                return true;
            }
        });
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setDefaultTextEncodingName("utf-8");//设置WebView属性,运行执行js脚本
        webView.loadUrl("file:///android_asset/build/index.html");          //调用loadUrl方法为WebView加入链接
        webView.addJavascriptInterface(new MyObject(MainActivity.this), "myObj");//添加一些webView方法调用原生的javascript方法
        setContentView(webView);
        
    }

    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                super.onBackPressed();
            }

        }
    }
}

添加一个类,用来封装js接口,暴露出来,用于页面与原生的交互:

public class MyObject {
    private Context context;
    public MyObject(Context context) {
        this.context = context;
    }

    //将显示Toast和对话框的方法暴露给JS脚本调用
    @JavascriptInterface
    public void showToast(String name) {
        Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
    }
    //此处返回值为空void,如需数据交互,按需返回数据,前端js代码即可收到数据
    @JavascriptInterface
    public void showDialog() {
        new AlertDialog.Builder(context)
                .setTitle("品牌列表").setIcon(R.mipmap.ic_launcher_round)
                .setItems(new String[]{"卡萨帝", "海尔", "统帅"}, null)
                .setPositiveButton("确定", null).create().show();
    }
}

页面可以如下调用MyObject类:

<input type="button" value="Toast提示" onclick="myObj.showToast('js调用原生测试');"/>
<input type="button" value="列表对话框" onclick="myObj.showDialog();"/>

然后运行及即可,打开即跳转到我们开发的React页面。
在这里插入图片描述
我们可以通过以上方法可以开发一些简单的APP,如果复杂的还需要用原生开发,毕竟WebView性能有限。

补充原生调用JS函数并返回数据:

webView.evaluateJavascript("javascript:callJS()", 
	new ValueCallback<String>() {
	    @Override
	    public void onReceiveValue(String s) {
	        //将button显示的文字改成JS返回的字符串
	        button.setText(s);
	    }
	});

前端代码:

 <script>
 // Android需要调用的方法
  function callJS(){
      document.getElementById("test").innerHTML = "调用成功";
      return 'JS返回值';
  }
 </script>
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐