Android uses network technology

Keywords: network JSON OkHttp Android

Android uses network technology

1. Use WebView

Sometimes we encounter special requirements, such as requiring some web pages to be displayed in the application. Make it clear that system browsers are not allowed to open.

WebView webView = (WebView) findViewById(R.id.web_view);
//Set up support for JavaScript scripts
webView.getSettings().setJavaScriptEnabled(true);
//Set up to display in the WebView when you need to jump from one page to another
webView.setWebViewClient(new WebViewClient());
//Show the content of the corresponding web page
webView.loadUrl("http://www.baidu.com");

2. Use the Http protocol to access the network

In Android 6.0, the HttpClient feature has been completely removed, indicating that it has been officially deprecated. The official recommendation is to use the HttpURLConnection.

2.1 Use HttpURLConnection

Normally, we should extract these common network operations into a common class and provide a static method that can be called simply when a network request is made.

Dead work

Subthreads cannot return data by returning, so they need to take advantage of java's callback mechanism. Return the response data to the caller. Create a new HttpCallbackListener first

public interface HttpCallbackListener{
    //Here the caller executes the specific content based on what is returned
    void onFinish(String response);
    //Handle the anomaly by crying here
    void onError(Exception e);
}

GET method

Request server to return data

public class HttpUtil {

    /**
     * Send network requests
     * This needs to be operated on in a child thread
     * Subthreads cannot update UI
     */
    public static String sendHttpRequest(final String address,final HttpCallbackListener listener){

        new Thread(new Runnable() {
            @Override
            public void run() {
                Httpconnection connection = null;
                try {
                    //1. Create a URL object
                    URL url = new URL("https://www.baidu.com");
                    //2. Open connection to get Httpconnection
                    connection = (Httpconnection) url.openConnection();
                    //3. Set the way HTTP requests are requested
                    connection.setRequestMethod("GET");
                    //4. Set some parameters Connection timeout Read timeout
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    //5. The response code needs to be determined before obtaining the data requested by the url, 200: Success, 206: Access to partial data is successful
                    // 300: Jump or redirect 400: Error 500: Server exception
                    int responseCode = connection.getResponseCode();
                    if (responseCode == 200) {
                        //6. Get the input stream returned by the server
                        InputStream inputStream = connection.getInputStream();
                        //7. Resolve the input
                        String result = StreamUtils.streamToString(inputStream);

                        if(listener != null){
                            //Callback onFinish() method
                            listener.onFinish(result);
                        }
                    }
                } catch (Exception e) {
                    if(listener != null){
                        //Callback onError() method
                        listener.onError(e);
                    }
                    e.printStackTrace();
                } finally {
                    //9. Finally remember to disconnect
                    if (connection != null){
                        connection.disconnect();//Close http connection
                    }
                }
            }
        }).start();

    }

}

Here's the StreamUtils code:

public class StreamUtils {

    //Convert Stream to String
    public static String streamToString(InputStream inputStream) {
        StringBuilder sb = new StringBuilder();
        String line = "";
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
            while( (line=bufferedReader.readLine()) != null ){
                sb.append(line);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bufferedReader != null){
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();
    }
}

POST mode

Submit data to the server, change the way HTTP requests are made to POST, and write out the data to be submitted before getting the input stream.
Data exists as key-value pairs separated by a symbol.

    //3. Set the way HTTP requests are requested
    urlConnection.setRequestMethod("POST");

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

2.2 Use OkHttp

Open source libraries, network communication. There are many excellent network communication libraries that can replace the native HttpURLConnection, of which OkHttp is undoubtedly
Do the best.

It is now the preferred network communication library for Android developers.

OkHttp's project home page address is https://github.com/square/okhttp

Usage method

  1. Edit app/build.gradle and add the following to dependencies:

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

  2. Send GET Request

    //1. First create the OkHttpClient object
    OkHttpClient client = new OkHttpClient();
    //2. Create Request Object
    Request request = new Request.Builder()
            .url("http://www.baidu.com ") //Set target address URL
            .build();
    //3. Getting the data returned by the server is this Response object
    Response response = client.newCall(request).execute();
    //4. Get the data out
    String responseData = response.body().string();
    //5. Update UI through Handler
    Message msg = Message.obtain();
    msg.obj = responseData;
    handler.sendMessage(msg);
    

Usually used in development as follows

public class HttpUtil {

    /**
     * Send network requests using OkHttp GET
     * sendRequestWithOkHttp()Method has an okhttp3.Callback parameter, which is a callback interface that comes with the OkHttp Library
     * OkHttp The enqueue() method has helped us open the subthread, then execute the HTTP request in the subthread and call back the final request result to
     * okhttp3.Callback Among.
     */
    public static void sendRequestWithOkHttp(String address,okhttp3.Callback callback){

        //1. First create the OkHttpClient object
        OkHttpClient client = new OkHttpClient();
        //2. Create Request Object
        Request request = new Request.Builder()
                .url(address)   //Set target address URL
                .build();
        //3. Get the data returned by the server    
        client.newCall(request).enqueue(callback);
    }

}

Of course, if this is written into the HttpUtil class, the caller needs to write as follows:

HttpUtil.sendOkHttpRequest("http://www.baidu.com",new okhttp3.Callback(){
    @Override
    public void onResponse(Call call,Response response) throws IOException {
        //Get the specific content returned by the server
        String responseData = response.body().string();
    }

    @Override
    public void onFailure(Call call, IOException e) {
        //Handle exceptions here
    }

});
  1. Send POST Request

We need to first construct a RequestBody object to hold the parameters to be submitted

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

Then call the post() method in Request.Builder and pass in the RequestBody object

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

3. Parse xml format

Pull parsing

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) {
                // Start parsing a node
                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;
                }
                // Finish parsing a node
                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();
    }
}

SAX parsing

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 {
        // Record current node name
        nodeName = localName;
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // Determine which StringBuilder object to add content to based on the current node name
        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());
            // Finally, empty StringBuilder
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

}

Then?

private void parseXMLWithSAX(String xmlData) {
    try {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        XMLReader xmlReader = factory.newSAXParser().getXMLReader();
        ContentHandler handler = new ContentHandler();
        // Setting instances of ContentHandler into XMLReader
        xmlReader.setContentHandler(handler);
        // Start parsing
        xmlReader.parse(new InputSource(new StringReader(xmlData)));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

4. Parse JSON format

For example, XML, the main advantage of JSON is its small size, which can save traffic when transmitted over the network. However, the disadvantage is that it has poor semantics and does not seem as intuitive as xml.

There are many ways to parse JSON data. You can use either the officially provided JSONObject or Google's open source library GSON. In addition, some third-party open source libraries such as Jackson and FastJSON are also great.

4.1 Using JSONObject

private void parseJSONWithJSONObject(String jsonData){
    /**
     * Client data is
     * [{"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"}
     ]
     */
    try {
        //1. Create JSONArray with arrays inside
        JSONArray jsonArray = new JSONArray(jsonData);
        //2. Parse every data in the array
        for (int i=0; i<jsonArray.length(); i++){
            //3. An array element is a JSONObject
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            //4. Get the corresponding value based on the key
            String id = jsonObject.getString("id");
            String version = jsonObject.getString("version");
            String name = jsonObject.getString("name");

            Log.i(TAG, "parseJSONWithJSONObject: id"+id);
            Log.i(TAG, "parseJSONWithJSONObject: version"+version);
            Log.i(TAG, "parseJSONWithJSONObject: name"+name);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

4.2 Use GSON

The magic is that it automatically maps a JSON-formatted string to an object, eliminating the need to manually write code to parse it.

Dead work:

Edit the app/build.gradle file to add the following to the dependencies closure

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

Example

The server-side json data is

    [{"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"}
     ]

First you need to create an app entity class

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;
    }
}

Then write as follows:

 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.i(TAG, "parseJSONWithGSON: "+app.getId());
        Log.i(TAG, "parseJSONWithGSON: "+app.getName());
        Log.i(TAG, "parseJSONWithGSON: "+app.getVersion());
    }
}

If it's a separate JApp object, not an array, write this:

App app = json.fromJson(jsonData, App.class);

Sometimes because some fields in JSON may not be suitable for naming directly as Java fields, the @SerializedName annotation is used here to establish a mapping relationship between JSON fields and Java fields.

Like this

The json structure is as follows:
  "basic" :{
      "city": "Suzhou".
      "id":"CN101190401",
      "update":{
          "loc":"2016-08-08 21:58"
      }
  }
public class Basic {

    @SerializedName("city")
    public String cityName;

    @SerializedName("id")
    public int weatherId;

    public Update update;

    public class Update {
        @SerializedName("loc")
        public String updateTime;
    }

}

5.

Posted by zavin on Fri, 05 Jul 2019 10:07:39 -0700