今天说说安卓混合开发。
曾经有一个话题是web终会一统app,然后我们看到随着时间的推移。web越来越强大(H5啊,JS各种框架啊),但同时原生app也在不断发展。
或许在将来还会再有这种话题论战,但目前,混合开发,结合web和原生app二者各自的优势,已经是众望所归了。
其中最常见的一种方式,在安卓的webview中嵌套web,通过各类设计,让二者进行交互。使得用户体验上几乎无法分辨出究竟是否纯原生。
这种方式最值得深入研究的就是,
安卓中的java代码与web端的javascript代码进行相互交互调用。
简单介绍一下背景知识:(Java和JavaScript)
说到java,作为目前(以及此前这么多年来)最受青睐最有用武之地的语言,就不多介绍了。贴百科:
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点[2] 。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等[3] 。
说到javascript。贴百科:JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。
这么晦涩难懂? 那就简单一句话,
其实java和JavaScript,完全是两码事。前者是面向对象,后者是内置对象。且后者借鉴了前者,但二者并没有关系.
好了,来到正题吧,先上效果图。
图中,
上半部分(蓝色背景)是安卓中实现的简单布局
下半部分(白色背景)是一个webview,里面的内容自然就是一个网页。
但是我们看到,点击上半部分安卓中的视图,能够改变webview中网页的视图。
同样,点击下半部分网页中的Button,能够调用安卓的Toast对话框。
这就是简单的一个android与web交互,目前在安卓界普遍称为
JS交互
理论的东西讲完了,接下来上代码:
今天的主角其实是两方面:安卓和web,
但我们分为4个类:
1.index.html,这是一个简单的web页面。
2.activity_main.xml 安卓的布局
3.MainActivity 安卓的主界面,同时也是本例的入口
4.JsInterface,这个类其实算帮助类,只是为了代码好看才抽出来
1.首先是index.html: web的布局及函数 (注意,
这个文件要放在安卓的assets文件下
)
<html>
<!-- 简单写,就省略了head -->
<body>
<script language="javascript">
//这个方法是与java事先商定的方法,让java来调用
function java_call_Js(param) {
var x = document.getElementById('test');
x.innerHTML = "Hello , New text form java ! ------------>" + param;
}
//Html自身Button的方法,去调用Java
function btn_js() {
jsInterface.js_call_java();
}
</script>
<input type="button" onClick="btn_js()"
style="height: 60px; width: 240px; margin-top: 40px ; margin-bottom: 10px"
value="(JS call Java)I'm a Button in html">
<div id="test">
<font color="#FF0000">this is the old text</font>
</div>
</body>
2.其次是activity_main: 安卓的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#336699"
android:gravity="center_vertical"
android:orientation="vertical" >
<EditText
android:id="@+id/text_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入你想在html显示的数字(不输入参数会报空指针)"
android:inputType="number"
android:maxLength="7"
android:textColor="#ffffff" />
<Button
android:id="@+id/btn_java"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="java call js(I'm a Button in Android" />
</LinearLayout>
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
3.其三是MainActivity: 主要的逻辑代码
public class MainActivity extends Activity {
private EditText mEditText;
private Button mButton;
private WebView webview;
private JsInterface jsInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText = (EditText) findViewById(R.id.text_edit);
mButton = (Button) findViewById(R.id.btn_java);
webview = (WebView) findViewById(R.id.webview);
// 实例化接口JsInterface
jsInterface = new JsInterface(webview);
// 初始化WebSetting
initWebSetting();
webview.loadUrl("file:///android_asset/index.html");
}
@SuppressLint("SetJavaScriptEnabled")
private void initWebSetting() {
// 允许JS交互
webview.getSettings().setJavaScriptEnabled(true);
// 设置JS的接口
webview.addJavascriptInterface(jsInterface, "jsInterface");
webview.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int param = Integer.parseInt(mEditText.getText().toString());
jsInterface.java_call_Js(param);
param = 0;
}
});
}
});
}
}
4.最后是JsInterface,封装了两个函数
//虽然命名为Interface,其实是伪接口,主要是为了方便理解及以后做抽象处理
public class JsInterface {
private WebView mWebView;
// 构造方法,传入一个参数WebView
public JsInterface(WebView webView) {
this.mWebView = webView;
}
// 这个方法是js调用java
@JavascriptInterface
public void js_call_java() {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
// 主线程更新UI
Toast.makeText(mWebView.getContext(), "I'm a function in java", Toast.LENGTH_SHORT).show();
}
});
}
// 这个方法 是java调用js
public void java_call_Js(int param) {
// 这里调用html中的js代码的 java_call_Js 方法
mWebView.loadUrl(String.format("javascript:java_call_Js(" + param + ")"));
}
}
注释都有,就不多说了。
在模拟器上运行代码,就会看到如上的效果图
这里主要看交互的双方(安卓和html):
都保留着两个方法(一个用来被对方调用,一个去调用对方)。
所有,做JS的前提是,要达成一种约定。要明确了对方的什么对象的什么方法可以被调用,才能如鱼得水。
另外这个地方值得注意:
// 允许JS交互 ------>意味着可能会被JS注入等攻击,安全问题需要考虑//
webview.getSettings().setJavaScriptEnabled(true);
// 设置JS的接口--------->第二个参数"jsInterface" 定义了给html中使用的对象就叫jsInterface
webview.addJavascriptInterface(jsInterface, "jsInterface")
//html中使用这个对象的代码就是: jsInterface.js_call_java();
好了,大功告成,献上我的Demo源码:
http://download.csdn.net/detail/lebang08/9656823