HttpURIConnectionとOkHttpを使ってネットワークにアクセスします.

10582 ワード

Network Test
素晴らしい世界を見ます.――ネット技術を使います.
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();
}
OkHttpを使ってネットワークにアクセスします.
  • まずインストールされたApacheサーバのC:/Apache/httdocsディレクトリの下に新しいget_を作成します.data.xmlファイルの内容:
  •     
            
                1
                Google Maps
                1.0
    
            
            2
            Chrome
            2.1
            
    
            3
            Google Play
            2.3
            
        
    
  • 次は訪問のテーマコードです.
  •     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();
        }
    XML形式のデータを解析します.
  • Pullの解析方式
  • SAXの解析方式
  • *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();
            }
        }
    
    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();
            }
        }
    JSON形式のデータを解析します.
  • JSONObjectを使う
  • GSON
  • を使用する.
    JSONObjectを使う
  • まずインストールされたApacheサーバのC:/Apache/httdocsディレクトリの下に新しいget_を作成します.data.jsonファイル、ファイルの内容:
  • [{"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"}]
    以下は具体的な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();
            }
        }
    以下は具体的なGSON解析方式です.
  • まずAppKクラスを新たに作って、id、name、versionのこれらのフィールドに参加して、getterに書き込みます.setter方法
  • 続いて解析の方法です.
    private void parseJSONWithGSON(String jsonData) {
            Gson gson = new Gson();
            List appList = gson.fromJson(jsonData, new TypeToken>()
            {}.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 interface HttpCallbackListener{
        void onFinish(String response);
    
        void onError(Exception e);
    }
    次に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();
        }
    HttpUtil Connectionの書き方は全体的に複雑ですが、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);
        }