混合开发在移动开发中很常见,比如qq中的运动,厘米秀等功能都是用网页实现的。
混合开发中一个重要的功能就是网页和原生接口的数据交互,下面将实现一个小demo.
新建一个activity,布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.h.learn.WebViewActivity">
<WebView
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/my_web_view"
/>
<LinearLayout
android:background="@drawable/webview_bg"
android:layout_weight="1"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/edit_info"
android:text="text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_confirm"
android:text="确定"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/log_text_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
布局中定义了一个webview,在屏幕上半部分。
底部是原生的一个输入框和按钮,输入框用于输入数据,按钮用于调用网页中的接口。
网页中也应该是类似的,一个输入框和一个调用原生接口的按钮。
assets文件夹中的网页代码如下:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script>
//供原生代码调用
function showEditInfo(str){
alert(str);
};
//调用原生接口,并把网页中文本框的内容传过去
function callNative()
{
var str=document.getElementById("mytext").value;
window.webview.actionFromJsWithParam(str);
};
//alert(1);
//showEditInfo('123');
</script>
<input type="text" value="123" name="mytext" id="mytext">
<button onClick="callNative()">调用原生接口</button>
</body>
</html>
public class WebViewActivity extends AppCompatActivity {
@BindView(R.id.my_web_view)WebView webview;
@BindView(R.id.edit_info)EditText editInfo;
@BindView(R.id.log_text_view)TextView logTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
ButterKnife.bind(this);
//webview = (WebView) findViewById(R.id.my_web_view);
Log.d("flag--","onCreate(WebViewActivity.java:20)-->>"+webview);
initView();
}
//调用js接口,并把editText中的内容传到网页接口中
@OnClick(R.id.btn_confirm)
public void confirm(){
Log.d("flag--","confirm(WebViewActivity.java:35)-->>"+"javascript:showEditInfo('"+editInfo.getText()+"')");
webview.loadUrl("javascript:showEditInfo('"+editInfo.getText()+"')");
}
private void initView() {
//加载网页
webview.loadUrl("file:///android_asset/webview.html");
//允许弹框
webview.setWebChromeClient(new WebChromeClient());
WebSettings webSettings= webview.getSettings();
//允许运行js
webSettings.setJavaScriptEnabled(true);
webview.addJavascriptInterface(this, "webview");
}
//供js调用的接口
@android.webkit.JavascriptInterface
public void actionFromJsWithParam(final String str) {
runOnUiThread(new Runnable() {
@Override
public void run() {
String text = logTextView.getText() + "\njs调用了Native函数传递参数:" + str;
logTextView.setText(text);
}
});
}
}
webview.addJavascriptInterface(this, “webview”);中第二个参数可以自定义,但要和js中相对应,因此js中调用原生接口的方法为 window.webview.actionFromJsWithParam(str);
最终效果:
常用框架:
https://weex.apache.org/cn/guide/