Android网络技术

来源:互联网 发布:wp软件下载 编辑:程序博客网 时间:2024/05/20 15:11

Android网络技术

一、WebView

webView.getSettings().setJavaScriptEnabled(true);   //使webView支持JavaScript脚本webView.setWebViewClient(new WebViewClient());      //使跳转网页时目标网页仍在WebView中显示,而不打开浏览器webView.loadUrl("http://www.baidu.com");            //加载网页

二、使用HTTP协议访问网络

1、使用HttpURLConnection

(1)获取HttpURLConnection的实例。

URL url = new URL("http://www.baidu.com");HttpURLConnection connection = (HttpURLConnection)url.openConnection();

(2)设置HTTP请求所使用的方法。常用的方法有GET和POST。

connection.setRequestMethod("GET");
  • 向服务器提交用户名和密码:

    connection.setRequestMethod("POST");DataOutputStream out = new DataOutputStream(connection.getOutputStream());out.writeBytes("username=admin&password=123456");

(3)设置连接超时、读取超时的毫秒数、以及服务器希望得到的一些消息头等。这部分根据需求进行编写。

connection.setConnectTimeout(8000);connection.setReadTimeout(8000);

(4)调用getInputStream()方法获取服务器返回的输入流。

InputStream in = connection.getInputStream();

(5)对输入流进行读取

(6)调用disconnect()将这个HTTP连接关闭。

2、使用OkHttp

(1)添加OkHttp库依赖

compile 'com.squareup.okhttp3:okhttp:3.6.0'

(2)创建一个OkHttpClient的实例

OkHttpClient client = new OkHttpClient();
  • 发起一条HTTP请求:

(3)创建一个Request对象(在build()方法之前连缀其他方法来丰富这个request对象)

Request request = new Request.Builder().url("http://www.baidu.com").build();

(4)调用OkHttpClient的newCall()方法来创建一个call对象,并调用它的execute()方法来发送请求并获取服务器返回的数据。

Response response = client.newCall(request).execute();

(5)Response对象就是服务器返回的数据。

String responseData = response.body().string();
  • 发起一条POST请求:

(3)构建一个RequestBody对象来存放待提交的参数

RequestBody requestBody = new FormBody.Builder()        .add("username", "admin")        .add("password", "123456")        .build();

(4)在Request.Builer中调用post()方法,并将RequestBody对象传入

Request request = new Request.Builder()        .url("http://www.baidu.com")        .post(requestBody)        .build();

(5)发送请求并获取服务器返回的数据

Response response = client.newCall(request).execute();String responseData = response.body().string();     

三、解析XML格式数据

1、Pull解析方式

(1)获取XmlPullParserFactory的实例,然后借助这个实例得到XmlPullParser对象。

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();XmlPullParser xmlPullParser = factory.newPullParser();

(2)调用XmlPullParser的setInput()方法将服务器返回的XML数据设置进去。

xmlPullParser.setInput(new StringReader(xmlData));

(3)通过getEventType()得到当前的解析事件

int eventType = xmlPullParser.getEventType();

(4)在while中进行解析。如果当前的解析事件不等于XmlPullParser.END_DOCUMENT,说明解析工作还没完成,该while循环最后调用next()可以获取下一个解析事件。

  在while循环中,通过getName()获取当前节点的名字,如果发现结点名为开始标记,就可以调用nextText()方法获取结点内具体的内容。

代码示例:

private void parseXMLWithPull(String responseData) {    try {        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();        XmlPullParser xmlPullParser = factory.newPullParser();        xmlPullParser.setInput(new StringReader(responseData));        int eventType = xmlPullParser.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解析方式

  新建一个类继承自DefaultHandler,重写父类的5个方法。其中,startDocument()会在开始XML解析时调用;startElement()会在开始解析某个结点的时候调用;characters()会在获取结点中内容时调用;endElement()会在完成解析某个节点时调用;endDocument()会在完成整个XML解析时调用。

ContentHandler.java

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 {        //记录当前节点名        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 ("app".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 {        super.endDocument();    }}

解析过程:

private void parseXMLWithSAX(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();    }}

四、解析JSON格式数据

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 (Exception e) {        e.printStackTrace();    }}

2、使用GSON

(1)添加GSON库依赖

compile 'com.google.code.gson:gson:2.7'

(2)

  • GSON库将一段Json格式的字符串自动映射成一个对象。如一段Json数据:{“name”:”Tom”,”age”:20},解析这一段Json数据,就可以先定义一个Person类,加入name和age两个字段,然后调用如下代码:

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

实例:

新建App.java:

public class App {    private String id;    private String name;    private String version;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getVersion() {        return version;    }    public void setVersion(String version) {        this.version = version;    }}

GSON解析Json:

private void parseJSONWithGSON(String jsonData) {    Gson gson = new Gson();    List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>(){}.getType());    for (App app : appList) {        Log.d("MainActivity", "id is " + app.getId());        Log.d("MainActivity", "name is " + app.getName());        Log.d("MainActivity", "version is " + app.getVersion());    }}

五、Http请求工具类

public class HttpUtils {    public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {        new Thread(new Runnable() {            @Override            public void run() {                HttpURLConnection connection = null;                StringBuilder response = new StringBuilder();                try {                    URL url = new URL(address);                    connection = (HttpURLConnection) url.openConnection();                    connection.setRequestMethod("GET");                    connection.setConnectTimeout(8000);                    connection.setReadTimeout(8000);                    connection.setDoInput(true);                    connection.setDoOutput(true);                    InputStream in = connection.getInputStream();                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));                    String line;                    while ((line = reader.readLine()) != null) {                        response.append(line);                    }                    if (listener != null) {                        //回调onFinish()方法                        listener.onFinish(response.toString());                    }                } catch (Exception e) {                    if (listener != null) {                        //回调onError()方法                        listener.onError(e);                    }                } finally {                    if (connection != null) {                        connection.disconnect();                    }                }            }        }).start();    }    public static void sendOkHttpRequest(String address, Callback callback) {        OkHttpClient client = new OkHttpClient();        Request request = new Request.Builder()                .url(address)                .build();        client.newCall(request).enqueue(callback);    }}

由于如果在以上方法内部不开启子线程可能会造成主线程阻塞,而开启子线程,Http请求方法会在服务器还没来得及响应的时候就执行结束了。所以此处需要利用Java的回调机制。实际使用时代码:

HttpUtils.sendHttpRequest("http://www.baidu.com", new HttpCallbackListener() {    @Override    public void onFinish(String response) {        //在这里根据返回内容执行具体的逻辑        ...    }    @Override    public void onError(Exception e) {        //在这里进行异常处理    }});HttpUtils.sendOkHttpRequest("http://www.baidu.com", new Callback() {    @Override    public void onFailure(Call call, IOException e) {        //在这里进行异常处理    }    @Override    public void onResponse(Call call, Response response) throws IOException {        //得到服务器返回的具体内容        String responseData = response.body().string();    }});
1 0
原创粉丝点击