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
-
Edit app/build.gradle and add the following to dependencies:
compile 'com.squareup.okhttp3:okhttp:3.6.0'
-
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 } });
- 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; } }