学习笔记(十二)使用网络技术

来源:互联网 发布:知乎 鹅妈妈童谣 编辑:程序博客网 时间:2024/04/29 07:29

一. WebView的简单用法

代码:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        WebView webView = (WebView) findViewById(R.id.web_view);        webView.getSettings().setJavaScriptEnabled(true);        //当网页跳转时,目标网页仍在WebView中显示,而不是打开浏览器        webView.setWebViewClient(new WebViewClient());        webView.loadUrl("http://www.baidu.com");    }}

访问网络需要权限

<uses-permission android:name="android.permission.INTERNET"/>

二. 使用 HTTP 协议访问网络

HTTP 协议工作原理,客户端向服务器发出一条 HTTP 请求,服务器收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理。

在 Android 上发送 HTTP 请求方式一般有两种,HttpURLConnection 和 HttpClient。

由于 HttpClient 在 Android 6.0 之后被谷歌废弃取消使用了,官方文档上说用 HttpURLConnection 代替,在 Android Studio v2.1 上面也没有 HttpClient,所以 HttpClient 的用法就没看了。

http://developer.android.com/intl/zh-cn/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client

Apache HTTP Client Removal

Android 6.0 release removes support for the Apache HTTP client. If your app is using this client and targets Android 2.3 (API level 9) or higher, use the HttpURLConnection class instead. This API is more efficient because it reduces network use through transparent compression and response caching, and minimizes power consumption. To continue using the Apache HTTP APIs, you must first declare the following compile-time dependency in your build.gradle file:

android {
useLibrary ‘org.apache.http.legacy’
}

HttpURLConnection

  • 从服务器获取数据:

这里写图片描述

public class MainActivity extends AppCompatActivity implements OnClickListener {    public static final int SHOW_RESPONSE = 0;    private Button sendRequest;    private TextView responseText;    private Handler handler = new Handler() {        public void handleMessage(Message msg) {            switch (msg.what) {                case SHOW_RESPONSE:                    String response = (String) msg.obj;                    //在这里进行UI操作,将结果显示在界面上                    responseText.setText(response);            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        sendRequest = (Button) findViewById(R.id.send_request);        responseText = (TextView) findViewById(R.id.response_text);        sendRequest.setOnClickListener(this);    }    @Override    public void onClick(View v) {        if (v.getId() == R.id.send_request) {            sendRequestWithHttpURLConnection();        }    }    private void sendRequestWithHttpURLConnection() {        //开启线程来发起网络请求        new Thread(new Runnable() {            @Override            public void run() {                HttpURLConnection connection = null;                try {                    //首先new出一个URL对象,并传入目标网络地址                    URL url = new URL("http://www.baidu.com");                    //调用openConnection()获取实例                    connection = (HttpURLConnection) url.openConnection();                    //设置HTTP请求所使用的方法,"GET"从服务器获取数据 和 "POST"向服务器提交数据                    connection.setRequestMethod("GET");                    connection.setConnectTimeout(8000);                    connection.setReadTimeout(8000);                    //调用getInputStream()获取服务器返回的输入流                    InputStream in = connection.getInputStream();                    //下面对获取到的输入流进行读取                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));                    StringBuilder response = new StringBuilder();                    String line;                    while ((line = reader.readLine()) != null) {                        response.append(line);                    }                    Message message = new Message();                    message.what = SHOW_RESPONSE;                    //将服务器返回的结果存放到Message中                    message.obj = response.toString();                    handler.sendMessage(message);                } catch (Exception e) {                    e.printStackTrace();                } finally {                    if (connection != null) {                        connection.disconnect();//关闭HTTP连接                    }                }            }        }).start();    }}
  • 向服务器提交数据:
    首先,将 HTTP 请求方法改为 POST;
    然后,打开输出流。
    之后,将数据以键值对方式输出,数据之间用&隔开。
connection.setRequestMethod("POST");OutputStream outputStream = connection.getOutputStream();DataOutputStream dataOutputStream = new DataOutputStream(outputStream);dataOutputStream.writeBytes("username=admin&password=123456");

三. 解析 XML 格式数据

1. Pull 解析

  • PULL 的工作原理:
    XML Pull 提供了开始元素和结束元素。当某个元素开始时,可以调用 parser.nextText() 从 XML 文档中提取所有字符数据。当解析到一个文档结束时,自动生成 EndDocument 事件。

  • Pull 解析器的运行方式和SAX类似,都是基于事件的模式。

  • 不同的是,在 Pull 解析过程中返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像 SAX 那样由处理器触发一种事件的方法,执行我们的代码:
    读取到 XML 的声明返回 START_DOCUMENT; 结束返回 END_DOCUMENT; 开始标签返回 START_TAG;结束标签返回 END_TAG; 文本返回 TEXT。
    private void parseXMLWithPull(String xmlData){        try{            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();//获取实例factory            XmlPullParser xmlPullParser = factory.newPullParser();//利用factory获取XmlPullParser的实例            xmlPullParser.setInput(new StringReader(xmlData));//调用setInput()将服务器返回的XML数据设置进去            int eventType = xmlPullParser.getEventType();//调用getEventType()得到当前的解析时间            String id = "";            String name = "";            String version = "";            while(eventType != XmlPullParser.END_DOCUMENT){                String nodeName = xmlPullParser.getName();//获取当前结点的名字                switch(eventType){                    //开始解析某个结点                    case XmlPullParser.START_TAG:                        if("id".equals(nodeName)){                            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;                    default:                        break;                }                eventType = xmlPullParser.next();//获取下一个解析事件            }        }catch(Exception e){            e.printStackTrace();        }    }

2. SAX 解析

  • 其实SAX跟pull差不多,就是把解析具体结点的操作封装成一个DefaultHandler类。需要构建一个自己的 MyHandler 类去解析 XML 。
public class MyHandler extends DefaultHandler {    @Override    public void startDocument() throws SAXException {        //开始XML解析的时候调用        super.startDocument();    }    @Override    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {        //开始解析某个结点的时候调用。        super.startElement(uri, localName, qName, attributes);    }    @Override    public void characters(char[] ch, int start, int length) throws SAXException {        //获取结点内容时调用        super.characters(ch, start, length);    }    @Override    public void endElement(String uri, String localName, String qName) throws SAXException {        //完成解析某个结点的时候调用        super.endElement(uri, localName, qName);    }    @Override    public void endDocument() throws SAXException {        //完成整个XML解析的时候调用        super.endDocument();    }}

四. 解析 JSON 格式数据

解析 JSON 数据有很多方法,比如官方提供的 JSONObject, 也可以使用 Google 的开源库 GSON。

  • JSON:

    • JavaScript Object Notation 是一种轻量级的数据交换格式。它基于 ECMAScript 的一个子集。 JSON 采用完全独立于语言的文本格式,但是也使用了类似于 C 语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。
  • JSON Vs XML

    • JSON 和 XML 的数据可读性基本相同
    • JSON 和 XML 同样拥有丰富的解析手段
    • JSON 相对于 XML 来讲,数据的体积小
    • JSON 与 JavaScript 的交互更加方便
    • JSON 对数据的描述性比 XML 较差
    • JSON 的速度要远远快于 XML
  • JSON数据只有两种格式:

    • 一种是对象:一个大括号包裹的内容就是一个对象,里面是无数个逗号相间隔的键值对
      { “firstName”: “Brett”, “lastName”:”McLaughlin”, “email”: “aaaa” }
    • 一种是数组:一个方括号包裹的内容就是一个数组,里面是无数个逗号相间隔的 JSON 对象

1. JSONObject

编辑 get_data.json 文件:

[{"id":"5","name":"SORA_FC","version":"4.4"},{"id":"6","name":"SORA_SC","version":"6.6"},{"id":"7","name":"SORA_3RD","version":"7.7"}]
private void parseJASONWithJSONObject(String jsonData){        try {            //把jsonData转化成JSONArray            JSONArray jsonArray=new JSONArray(jsonData);            for(int i=0;i<jsonArray.length();i++){                //从JSONArray取出JSONObject                JSONObject jsonObject=jsonArray.getJSONObject(i);                //从JSONObject中取出字段                String id=jsonObject.getString("id");                String name=jsonObject.getString("name");                String version=jsonObject.getString("version");            }        } catch (Exception e) {            e.printStackTrace();        }    }

2. GSON

GSON 库神奇的地方:GSON 可以将一段 JSON 格式的字符串自动映射成一个对象,从而不需要我们再手动去编写代码进行解析。

比如一段 JSON 格式数据如下:

{"name":"Tom","age":"22"}

定义一个 Person 类,加入 name 和 age 这两个字段,利用 GSON 可以将上面的 JSON 格式直接映射为一个对象。 fromJson() 接收两个参数: JSON 数据和需要映射的类。

Gson gson = new Gson();Person person = gson.fromJson(jsonData,Person.class);

如果需要解析一段 JSON 数组, 需要用 TypeToken 将期望解析的数据传入到 fromJson() 中。

list<Person> people = gson.fromJson(jsonData,new TypeToken<list<Person>>(){}.getType()); 

参考:
《第一行代码–Android》读书笔记之网络编程
http://blog.csdn.net/TellH/article/details/49991259

Android解析XML(PULL方式)和JSON 工作原理和实现过程:
http://blog.csdn.net/onlyonecoder/article/details/8489170

android Json解析详解(详细代码) :
http://blog.csdn.net/onlyonecoder/article/details/8490924

Gson解析json数据:
http://blog.csdn.net/itachi85/article/details/45172205

0 0