Android学习笔记(十)网络技术

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());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值