【Android进阶】(九)WebView
【Android进阶】(9)WebView
下面我们来看一个使用JavaScript脚本来实现Android应用的一个例子:
文章出处:http://blog.csdn.net/scarthr/article/details/42211979
今天我们来学习和网络相关的控件——WebView
一 浏览网页
WebView可以直接显示指定的网页:
webView.loadUrl("http://www.baidu.com");我们通过这个方法可以自己写一个简单的网页浏览器。我们创建一个输入网页地址的EditText,一个跳转的按钮,菜单提供前进和后退的功能:
package cn.thr.browser; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; import android.view.View; import android.view.View.OnClickListener; import android.webkit.URLUtil; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.EditText; import android.widget.ImageButton; import android.widget.Toast; import cn.thr.browser.R; public class Main extends Activity implements OnClickListener, OnMenuItemClickListener { private WebView webView; private EditText etAddress; @Override public void onClick(View view) { String url = etAddress.getText().toString(); if (URLUtil.isNetworkUrl(url)) webView.loadUrl(url); else Toast.makeText(this, "输入的网址不正确.", Toast.LENGTH_LONG).show(); } @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { // 向后(back) case 0: webView.goBack(); break; // 向前(Forward) case 1: webView.goForward(); break; } return false; } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuItem miBack = menu.add(0, 0, 0, "向后"); MenuItem miForward = menu.add(0, 1, 1, "向前"); miBack.setOnMenuItemClickListener(this); miForward.setOnMenuItemClickListener(this); return super.onCreateOptionsMenu(menu); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); webView = (WebView) findViewById(R.id.webview); etAddress = (EditText) findViewById(R.id.etAddress); etAddress.setText("http://m.baidu.com/"); ImageButton ibBrowse = (ImageButton) findViewById(R.id.ibBrowse); ibBrowse.setOnClickListener(this); webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); } }调用WebView的goBack和goFoward方法可以实现网页的后退和前进。使用类URLUtil的静态方法isNetworkUrl(url)可以判断当前Url地址是否是合理的网址。
这里注意我们用setWebViewClient方法重写了参数中WebViewClient的shouldOverrideUrlLoading方法,方法中返回true。这么写是为了能在当前应用中打开网页,如果不这么写,那么WebView在加载URL的时候就会跳转到调用系统自带的浏览器。
之前在将ActionBar的时候讲到了OptionMenu的创建,这里的菜单项我们使用了另一种方法创建。
MenuItem miBack = menu.add(0, 0, 0, "向后"); MenuItem miForward = menu.add(0, 1, 1, "向前"); miBack.setOnMenuItemClickListener(this); miForward.setOnMenuItemClickListener(this);
add方法第一个参数是菜单组的id,第二个是菜单的id,第三个是顺序,第四个是菜单显示内容。
并设置监听,在onMenuItemClick中根据item.getItemId来判断不同的响应。
二 装载HTML代码
方法定义如下:
public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)使用如下:
String html = "<html><body>haha</body></html>"; webView.loadDataWithBaseURL("基地址", html, "text/html", "utf-8", null); // 打开JavaScript功能 webView.getSettings().setJavaScriptEnabled(true); // 设置处理JavaScript的引擎 webView.setWebChromeClient(new WebChromeClient());webView还有一个方法是loadData方法,使用情况和loadDataWithBaseURL差不多,只不过对于双字节的字符支持的不好,如果有中文、韩文等它会显示乱码,所以一般情况下我们还是选择使用loadDataWithBaseURL方法来替代。
三 Java与JavaScript交互
JavaScript可以条用Java方法,互相传递数据,使用方法:
webView.addJavascriptInterface(new Object() { public void move(int x, int y) { } }, "demo");
package cn.eoe.javascript.demo; import java.io.InputStream; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.webkit.WebSettings; import android.webkit.WebView; import android.widget.Button; public class JSActivity extends Activity { private Button button; private WebView webView; private String startRandomMoveJavascript; private String stopRandomMoveJavascript; private Handler moveHandler = new Handler() { @Override public void handleMessage(Message msg) { int x = msg.arg1; int y = msg.arg2; button.layout(x, y, button.getMeasuredWidth() + x, button.getMeasuredHeight() + y); super.handleMessage(msg); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button) findViewById(R.id.button); webView = new WebView(this); WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); webView.addJavascriptInterface(new Object() { public void move(int x, int y) { Message message = new Message(); message.arg1 = x; message.arg2 = y; moveHandler.sendMessage(message); } }, "demo"); // 读取JavaScript代码 InputStream is = getResources() .openRawResource(R.raw.start_random_move); byte[] buffer = new byte[1024]; try { int count = is.read(buffer); startRandomMoveJavascript = new String(buffer, 0, count, "utf-8"); } catch (Exception e) { } is = getResources().openRawResource(R.raw.stop_random_move); buffer = new byte[1024]; try { int count = is.read(buffer); stopRandomMoveJavascript = new String(buffer, 0, count, "utf-8"); } catch (Exception e) { } } public void onClick_Move(View view) { webView.loadDataWithBaseURL(null, startRandomMoveJavascript, "text/html", "utf-8", null); } public void onClick_StopMove(View view) { webView.loadDataWithBaseURL(null, stopRandomMoveJavascript, "text/html", "utf-8", null); } }布局很简单,定义了3个按钮,一个控制滑动按钮的滑动开始,一个控制滑动按钮的滑动结束。我们调用webSetting的addJavascriptInterface方法将JavaScript定义到"demo"中,然后使用文件流从raw文件夹中读取开始和停止的两个JavaScript脚本,存至startRandomMoveJavascript和stopRandomMoveJavascript中。我们在move方法中,使用了Handler,用异步实现的,这是因为在主线程中创建的UI是无法在另一个线程中访问的。
我们来看两个JavaScript代码:
<script language="javascript"> var timer; function startTimer(){ timer= setInterval("randomMoveButton()",2000); } function randomMoveButton() { var x = Math.round(Math.random() * 300); var y = Math.round(100 + Math.random() * 300); window.demo.move(x, y); } startTimer(); </script>
<script language="javascript"> clearInterval(timer); </script>非常简单,定义了用随机数移动的方法,使用window.demo.move调用即可。
源码下载