文章出处:http://blog.youkuaiyun.com/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调用即可。