开发技巧Android网络请求开源库Android开发

使用HttpURIConnection和OkHttp访问网络

2018-02-25  本文已影响24人  亚欧沙龙

NetworkTest

看精彩的世界——————使用网络技术

使用HttpURIConnection访问网络

 private void sendRequestWithHttpURIConnection() {
//        开启线程发起网络请求
    new Thread(new Runnable() {
        @Override
        public void run() {
            HttpURLConnection connection = null;
            BufferedReader reader = null;
            try{

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

        //GET表示希望从服务器哪里获取数据
                connection.setRequestMethod("GET");

        //设置连接超时,读取超时的毫秒数
                connection.setConnectTimeout(8000);
                connection.setReadTimeout(8000);

        //调用getInputStream()方法就可以得到服务器返回的输入流了
                InputStream in = connection.getInputStream();
//                    下面对获取到的输入流进行读取
                reader = new BufferedReader(new InputStreamReader(in));
                StringBuilder response = new StringBuilder();
        //下面是设置行的个数,以便显示所有数据
                String line;
                while ((line = reader.readLine()) != null){
                    response.append(line);
                }
                showResponse(response.toString());
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if (reader != null){
                    try{
                        reader.close();
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }
                if (connection != null){
                    connection.disconnect();
                }
            }
        }
    }).start();
}</pre>

使用OkHttp 访问网络

    <apps>
        <app>
            <id>1</id>
            <name>Google Maps</name>
            <version>1.0</version&gt
        </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>
    private void sendRequestWithOkhttp() {
            new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
//                            访问地址为baidu的地址
//                            .url("http://www.baidu.com")
//                            指定访问的服务器地址是电脑本机
                            .url("http://10.0.0.2/get_data.xml")
                            .build();
                    Response response = client.newCall(request).execute();
                    String responseData = response.body().string();

//                    showResponse(responseData);

//                    Pull的解析方式
//                    parseXMLWithPull(responseData);
//
//                    SAX的解析方式
                    parseXMLWithSAX(responseData);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();
    }</pre>

解析XML格式的数据

* Pull的解析方式

 private void parseXMLWithPull(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 = "";
            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 id " + id);
                            Log.d("MainActivity","name is " + name);
                            Log.d("MainActivity","version is " + version);
                        }
                        break;
                    }
                    default:
                        break;
                }
                eventType = xmlPullParser.next();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
</pre>

SAX的解析方式

首先需要建立一个类继承DefaulyHander,并重写父类的5个方法

public class ContentHander extends DefaultHandler{

}

public void startDocument() throws SAXException {

}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

}

public void characters(char[] ch, int start, int length) throws SAXException {

}

public void endElement(String uri, String localName, String qName) throws SAXException {

}

public void endDocument() throws SAXException {

}

再在MainActivity里面做如下修改:

private void parseXMLWithSAX(String xmlData) {

        try{
            SAXParserFactory factory = SAXParserFactory.newInstance();
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();
            ContentHander hander = new ContentHander();
//            将ContentHander的实例设置到XMLReader中
            xmlReader.setContentHandler(hander);
//            开始执行解析
            xmlReader.parse(new InputSource(new StringReader(xmlData)));
        }catch (Exception e){
            e.printStackTrace();
        }
    }</pre>

解析JSON格式的数据

使用JSONObject

[{"id":"5","version":"5.5","name":"Clash of Clans"},
{"id":"6","version":"7.0","name":"Boom Beach"},
{"id":"7","version":"3.5","name":"Clash Royale"}]</pre>

下面是具体的JSONObject解析方式

    ////         JSONObject的解析方式
    private void parseJSONObject(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 id " + id);
                Log.d("MainActivity","name is" + name);
                Log.d("MainActivity","version is " + version);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }</pre>

下面是具体的GSON解析方式

接着就是解析的方法了:

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());
        }
    }</pre>

当然,以上的方法是有问题的,如果我们每次都去编写一变发送HTTP请求的代码,这显然是费劲的,我们可以把这些通用的网络操作提到一个公共类中,但是不能每次都调用都写一个线程,因为方法会在服务器还没来得及响应的时候就执行结束了,因此我们

需要先定义一个接口

public interface HttpCallbackListener{
    void onFinish(String response);

    void onError(Exception e);
}</pre>

j接着写HttpUtil类中的添加方法:

public static void sendHttpRequest(final String address,final HttpCallbackListener listener){
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                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));
                    StringBuilder respond = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null){
                        respond.append(line);
                    }
                    if (listener != null){
//                        调回onFinish()方法
                        listener.onFinish(respond.toString());
                    }
                }catch (Exception e){
                    if (listener != null){
//                        回调onError()方法
                        listener.onFinish(e);
                    }
                }finally {
                    if (connection != null){
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }</pre>

HttpUtilConnection的写法总体上来说比较复杂,那么使用OkHttp会变简单吗,答案是肯定的

public static void sendOkHttpRequest(String address,okhttp3.Callback callback){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address)
                .build();
        client.newCall(request).enqueue(callback);
    }</pre>
上一篇下一篇

猜你喜欢

热点阅读