10.1 WebView的用法
WebView相当于一个嵌入式的浏览器,当程序中需要打开网页,但又不能通过浏览器时,就可以使用该控件。
使用步骤如下:
(1)在布局文件activity_main.xml中加入WebView控件
<?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">
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"></WebView>
</LinearLayout>
(2)在MainActivity中编写代码
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取控件
webView = (WebView) findViewById(R.id.web_view);
//可调用getSettings方法设置浏览器属性,此处为设置WebView支持js脚本
webView.getSettings().setJavaScriptEnabled(true);
//设置该选项表示当需要从一个url跳转到另一个url的时候仍然使用当前的WebView控件,而不是打开浏览器访问
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 根据传入的参数再去加载新的网页
view.loadUrl(url);
// 表示当前WebView可以处理打开新url的请求,而不用借助系统浏览器
return true;
}
});
webView.loadUrl("http://www.baidu.com");
}
}
(3)访问网络需要在AndroidManifest.xml中声明权限
<
uses-permission
android
:name=
"android.permission.INTERNET"
/>
10.2 使用HTTP协议
http协议工作原理非常简单,就是客户端向服务器端发出一条请求,然后服务器对请求进行处理然后返回数据,客户端再进行解析。做java开发的应该很了解这些内容,不再赘述。
Android中发送HTTP请求的方式一般有两种:HttpURLConnection 和 HttpClient。
10.2.1 HttpURLConnection
(1)首先获取HttpURLConnection实例,一般只需new出一个URL对象,并传入目标网络地址,然后调用openConnection()方法。
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
(2)设置请求方式,即GET和POST
connection.setRequestMethod("GET");
//可以使用下面的方式提交数据
connection.setRequestMethod("POST");
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
//每条数据要以键值对的形式存在,并且用 & 符号连接起来
outputStream.writeBytes("user=admin&pwd=123456");
(3)设置其他选项,如连接超时、读取超时等等,根据实际需求设置。
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
(4)获取服务器返回的输入流
InputStream inputStream = connection.getInputStream();
(5)关闭http连接
connection.disconnect();
10.2.2 使用HttpClient
HttpClient是Apache提供的HTTP网络访问接口,从一开始就被引入到了Android中,与HttpURLConnection的使用有较大区别,但效果一致。
特别注意:
Android Studio中现在默认无法使用HttpClient!根据官方说明,Android 6.0 中,Google已经移除了Apache HttpClient相关的类,推荐用HttpURLConnection代替,balabala....如果想继续使用Apache HTTP API,需要在Android Studio Module中的build.gradle里面配置以下内容(具体设置如图所示,看不清就右键图片在新标签中打开):
android {
useLibrary 'org.apache.http.legacy'
}
基本使用:
(1)HttpClient是接口,无法创建它的实例,通常创建一个DefaultHttpClient实例
HttpClient client=new DefaultHttpClient();
(2)发起GET请求或POST请求
①发起GET请求,则创建HttpGet对象,并传入地址
HttpGet httpGet = new HttpGet("http://www.baidu.com");
client.execute(httpGet);
②发起POST请求则稍复杂,如下:
//1.创建一个HttpPost对象
HttpPost httpPost = new HttpPost("http://www.baidu.com");
//2.通过NameValuePair类型的集合来存放参数
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("user", "zhangsan"));
params.add(new BasicNameValuePair("pwd", "123456"));
//3.然后将参数集合传入到一个UrlEncodedFormEntity中
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");
//4.调用setEntity方法将构建好的UrlEncodedFormEntity传入
httpPost.setEntity(entity);
//5.同样调用execute方法
client.execute(httpPost);
(3)执行 execute()方法之后会返回一个 HttpResponse对象,服务器所返回的所有信息都在这里面,并解析
HttpResponse response = client.execute(httpPost);
// 请求码为200,说明请求和响应成功
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity respEntity = response.getEntity();
// 将HttpEntity转换为字符串
String content = EntityUtils.toString(respEntity);
// 注意如果包含中文,则应指定字符集,否则会乱码
// String content=EntityUtils.toString(respEntity, "utf-8");
}
10.3 解析XML格式数据
示例解析以下XML数据:
<?xml version="1.0" encoding="UTF-8"?>
<xml-body>
<apps>
<app>
<id>1</id>
<name>Google Maps</name>
<version>1.0</version>
</app>
<app>
<id>2</id>
<name>Chrome</name>
<version>2.1</version>
</app>
<app>
<id>3</id>
<name>Google Play</name>
<version>2.3</version>
</app>
</apps>
</xml-body>
10.3.1 Pull解析
private void parseXMLByPull(String xmlData) {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlData));
//获得当前的解析事件
int eventType = xmlPullParser.getEventType();
String id = "";
String name = "";
String version = "";
//如果解析事件不等于END_DOCUMENT,说明解析还未完成
while (eventType != xmlPullParser.END_DOCUMENT) {
// 获取当前节点名字
String nodeName = xmlPullParser.getName();
switch (eventType) {
// 开始解析某个节点
case XmlPullParser.START_TAG:
if ("id".equals(nodeName)) {
//使用nextText方法获取节点的具体内容
id = xmlPullParser.nextText();
} else if ("name".equals(nodeName)) {
name = xmlPullParser.nextText();
} else if ("version".equals(nodeName)) {
version = xmlPullParser.nextText();
}
break;
// 完成解析某个结点
case XmlPullParser.END_TAG: {
if ("app".equals(nodeName)) {
Log.d("MainActivity", "id is " + id);
Log.d("MainActivity", "name is " + name);
Log.d("MainActivity", "version is " + version);
}
break;
}
}
//继续进行
eventType = xmlPullParser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
10.3.2 SAX解析
SAX是一种特别常用的解析方式,虽然用法比Pull复杂,但语义清楚。使用时需要创建自定义类,并继承DefaultHandler 实现5个方法:
- startDocument():开始解析XML时调用
- startElement():开始解析某个节点的时候调用
- characters():获取节点内容的时候调用
- endElement():完成解析某个节点的时候调用
- endDocument():完成解析XML文档的时候调用
示例如下,新建ContentHandler类:
public class ContentHandler extends DefaultHandler {
private String nodeName;
private StringBuilder id;
private StringBuilder name;
private StringBuilder version;
@Override
public void startDocument() throws SAXException {
//开始解析时初始化
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//记录当前节点名
this.nodeName = localName;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// 根据当前的结点名判断将内容添加到哪一个StringBuilder对象中
if ("id".equals(nodeName)) {
id.append(ch, start, length);
} else if ("name".equals(nodeName)) {
name.append(ch, start, length);
} else if ("version".equals(nodeName)) {
version.append(ch, start, length);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("apps".equals(localName)) {
Log.d("ContentHandler", "id is " + id.toString().trim());
Log.d("ContentHandler", "name is " + name.toString().trim());
Log.d("ContentHandler", "version is " + version.toString().trim());
// 最后要将StringBuilder清空掉,以免影响下一次读取
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
}
@Override
public void endDocument() throws SAXException {
}
}
MainActivity类:
private void parseXMLBySAX(String xmlData) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
ContentHandler handler = new ContentHandler();
// 将ContentHandler的实例设置到 XMLReader 中
xmlReader.setContentHandler(handler);
// 开始执行解析
xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
e.printStackTrace();
}
}
10.4 解析JSON
示例解析以下json数据:
[{"id":"5","version":"5.5","name":"Angry Birds"},
{"id":"6","version":"7.0","name":"Clash of Clans"},
{"id":"7","version":"3.5","name":"Hey Day"}]
10.4.1 使用JSONObject
private void parseJSONWithJSONObject(String jsonData) {
try {
JSONArray jsonArray = new JSONArray(jsonData);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String version = jsonObject.getString("version");
Log.d("MainActivity", "id is " + id);
Log.d("MainActivity", "name is " + name);
Log.d("MainActivity", "version is " + version);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
10.4.2 使用GSON
GSON是Google提供的开源库,操作更加简单,自动将json解析为对象,不过在Android中并没有集成,需要下载jar包并添加。
(1)解析对象
比如解析{"name":"Tom","age":20},需要创建一个Person类,添加对应字段,并编写:
Gson gson = new Gson();
Person person = gson.fromJson(jsonData, Person.class);
(2)解析数组
需要借助TypeToken
List<Person> people = gson.fromJson(jsonData, new TypeToken<List<Person>>(){}.getType());