Android第一行代码——第九章使用网络技术

WebView的用法

 控件,借助它我们可以在自己的应用程序中嵌入一个浏览器
  1.创建WebView控件

<WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webView"/>

  2.获取WebView对象,设置相关属性

 WebView webView = (WebView)findViewById(R.id.webView);
 //webView.getSettings()方法可设置一些浏览器的属性
 webView.getSettings().setJavaScriptEnabled(true);       
 //设置WebView支持JavaScript脚本
 webView.setWebViewClient(new WebViewClient());
 //当需要从一个网页跳转到另一个网页时,我们希望目标网页在当前WebView中显示,而不是打开系统浏览器
 webView.loadUrl("http://www.baidu.com");	//传入要打开的网址

  3.添加权限

<uses-permission android:name="android.permission.INTERNET"/>

此时运行发现打不开网页,需要设置android:usesCleartextTraffic=“true”

<application
    ...
    android:usesCleartextTraffic="true"
    ...
</application>

由于这里要使用明文网络流量所以要设置成true
android:usesCleartextTraffic
       指示应用程序是否打算使用明文网络流量,例如明文HTTP。目标API级别为27或更低的应用程序的默认值为“ true”。面向API级别28或更高级别的应用默认为“ false”。
       当属性设置为“ false”时,平台组件(例如,HTTP和FTP堆栈,DownloadManager和MediaPlayer)将拒绝应用程序使用明文流量的请求。
      强烈建议第三方库也采用此设置。避免明文通信的主要原因是缺乏机密性,真实性和防篡改保护;网络攻击者可以窃听所传输的数据,并且还可以对其进行修改而不会被检测到

使用HTTP协议访问网络

HttpURLConnection

从服务器获取数据

  1. 获取HttpURLConnection实例

    这里是借助URL对象获取

URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
  1. 设置请求所用的方法
    GET:从服务器获取数据
    POST:提交数据给服务器
 connection.setRequestMethod("GET"); 
  1. 获取服务器的返回流,读取数据
    完整代码如下:
 private void sendRequestWithHttpURLConnection() {
    
    
        //网络请求是费时操作,所以要开启线程来发起网络请求
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                HttpURLConnection connection  = null;
                BufferedReader bufferedReader = null;
                try {
    
    
                    URL url = new URL("http://www.baidu.com");
                    connection =(HttpURLConnection)url.openConnection();
                    connection.setRequestMethod("GET");     //设置HTTP请求所用的方法
                    connection.setConnectTimeout(8000);     //设置连接超时的毫秒数
                    connection.setReadTimeout(8000);        //设置读取超时的毫秒数
                    InputStream in = connection.getInputStream();      //获取到服务器返回的输入流
                    //对输入流进行读取
                    bufferedReader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder stringBuilder = new StringBuilder();
                    String Line;
                    while ( (Line = bufferedReader.readLine()) != null){
    
    
                        stringBuilder.append(Line);
                    }
                    //shouResponse(stringBuilder.toString());	
                }catch (Exception e){
    
    
                    e.printStackTrace();
                }finally {
    
    
                    if(connection != null)
                        connection.disconnect();
                    if(bufferedReader != null){
    
    
                        try {
    
    
                            bufferedReader.close();
                        } catch (IOException e) {
    
    
                            e.printStackTrace();
                        }
                    }
                }

            }
        }).start();
    }

提交数据给服务器

方法和上面一样,只是把GET改为POST

private void acceptRequestWithHttpURLConnection() {
    
    
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                HttpURLConnection connection = null;
                BufferedWriter writer = null;
                try {
    
    
                    URL url = new URL("http://www.baidu.com");
                    connection =(HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("STOP");
                    //获取输出流用于输出数据
                    OutputStream os = connection.getOutputStream();
                    DataOutputStream dataOutputStream = new DataOutputStream(os);
                    dataOutputStream.writeBytes("username=admin&password=123456");
                    /*
                    String st = textView.getText().toString();
                    writer = new BufferedWriter(new OutputStreamWriter(os));
                    writer.write(st);

                     */
                } catch (Exception e) {
    
    
                    e.printStackTrace();
                }

            }
        }).start();

    }

当然别忘了申请网络权限

<uses-permission android:name="android.permission.INTERNET"/>

使用OkHttp

OkHttp是Square公司开发的一款出色的开源库GitHub地址

添加依赖,可通过上面的网址获取最新的

implementation("com.squareup.okhttp3:okhttp:4.9.0")

使用:

  1. 获取服务器返回的数据
 private void sendOKHttp() {
    
    
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                OkHttpClient client = new OkHttpClient();   //第一步:创建一个OkHttpClient的实例

                Request request = new Request.Builder()     //第二步:创建一个Request对象
                        .url("http://www.baidu.com")
                        .build();
                    Response response = client.newCall(request).execute();
                    //第三步:调用OkHttpClient的newCall方法创建Call对象,并调用他的execute()方法来发送请求并获取服务器返回的数据
                    //返回的数据可从Response对象中得到
                    String data = response.body().string();
                    shouResponse(data);
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
        }).start();
  1. 提交数据到服务器
private void acceptOkHttp() {
    
    
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                //第一步:构建一个RequestBody对象来存储待提交的数据
                RequestBody requestBody = new FormBody.Builder()
                        .add("username","admin")
                        .add("password","123456")
                        .build();
                //第二步:创建一个OkHttpClient的实例
                OkHttpClient client = new OkHttpClient();
                //第三步:创建一个Request对象
                Request request = new Request.Builder()
                        .url("http://www.baidu.com")
                        .post(requestBody)
                        .build();
                try {
    
    
                //第四步:发送请求
                    Response response = client.newCall(request).execute();      
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
        }).start();

    }

解析XML格式数据

Pull解析方式

 private void parseXMLWithPUll(String st) {
    
    
 /*PuLL解析XML格式数据
   第一步:获取XmlPullParserFactory对象
   第二步: 通过第一步获取的XmlPullParserFactory获取XmlPullParser对象
   第三步:通过setInput()设置要解析的XML数据
   第四步:执行解析逻辑
        
 */
        try {
    
    
            //获取XmlPullParserFactory实例
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            //获取XmlPullParser对象
            XmlPullParser xmlPullParser = factory.newPullParser();
            //设置要解析的XML数据
            xmlPullParser.setInput(new StringReader(st));
            //执行解析逻辑
            int eventType = xmlPullParser.getEventType();
            String id = "";
            String name = "";
            while(eventType!=xmlPullParser.END_DOCUMENT){
    
    
                String getName = xmlPullParser.getName();
                switch (eventType){
    
    
                    //开始解析某个节点
                    case XmlPullParser.START_TAG:
                        if("id".equals(getName))
                            id = xmlPullParser.nextText();
                        else if("name".equals(getName))
                            name = xmlPullParser.getName();
                        break;
                     //完成解析某个节点
                    case XmlPullParser.END_TAG :
                        //执行拿出数据后的操作,比如打印等
                        break;
                }
                eventType = xmlPullParser.next();
            }
        }catch (Exception e){
    
    
            e.printStackTrace();
        }

    }

SAX解析方式

新建一个类继承自DefaultHandler,并重写父类的5个方法

package com.example.networktest;

import android.util.Log;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ContentHandler extends DefaultHandler {
    
    
    private String nodeName;
    private StringBuilder id;
    private StringBuilder name;
    private StringBuilder version;

    @Override
    public void startDocument() throws SAXException {
    
    
    //开始XML解析时调用
        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());
            id.setLength(0);                                //清空
            name.setLength(0);
            version.setLength(0);
        }

    }

    @Override
    public void endDocument() throws SAXException {
    
    
    //完成整个XML解析时调用
        super.endDocument();

    }
}

调用,解析

 private void parseXMLWithSAX(String respondata) {
    
               //SAX解析

        try {
    
    
            //第一步:创建SAXParserFactory实例
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //第二步:获取XMLReader对象
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();
            //第三步:获取DefaultHandler子类对象,传给XMLReader对象
            ContentHandler handler = new ContentHandler();
            xmlReader.setContentHandler(handler);
            //第四步传入数据,开始执行解析
            xmlReader.parse(new InputSource(new StringReader(respondata)));
        } catch (SAXException e) {
    
    
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

    }

解析JSON格式数据

JSONObject解析

 private void parseJSONWithJSONObject(String data) {
    
    
        //使用JSONObject解析json类型数据
        try {
    
    
			// 第一步获取JSONArray数组
            JSONArray jsonArray = new JSONArray(data);
            //第二步:遍历,拿到对应的数据
            for(int i = 0; i < jsonArray.length(); i++){
    
    
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String get1 = jsonObject.getString("name1");
                String get2 = jsonObject.getString("name2");
                String get3 = jsonObject.getString("name3");

            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

    }

GSON解析

GSON是谷歌提供的开源库,让解析更简单。可以将一段JSON格式的字符串自动映射成一个对象。GitHub地址

  1. 添加依赖库
implementation 'com.google.code.gson:gson:2.8.6'
  1. 定义一个类,把要解析的设置成字段,提供get,set方法
package com.example.revise_9_2;

public class App {
    
    
    private String get1;
    private String get2;
    private String get3;

    public String getGet1() {
    
    
        return get1;
    }

    public void setGet1(String get1) {
    
    
        this.get1 = get1;
    }

    public String getGet2() {
    
    
        return get2;
    }

    public void setGet2(String get2) {
    
    
        this.get2 = get2;
    }

    public String getGet3() {
    
    
        return get3;
    }

    public void setGet3(String get3) {
    
    
        this.get3 = get3;
    }
}

3.将JSON数据解析成类对象
       如果JSON格式数据是这种:{“name”:“Tom”,“age”:20}解析方式如下:

 Gson gson = new Gson();
App app = gson.fromJson(data,App.class);

       之后就可通过类对象去得到数据
       如果JSON格式数据是数组解析方式如下:

Gson gson = new Gson();      
List<App> appList = gson.fromJson(data,new TypeToken<List<App>>(){
    
    }.getType());

       之后可通过遍历数组得到每一个类对象,拿到数据
完整如下

 private void parseJSONWithGSON(String data) {
    
    
        Gson gson = new Gson();

        List<App> appList = gson.fromJson(data,new TypeToken<List<App>>(){
    
    }.getType());
        for(App app : appList){
    
    
            String s1 = app.getGet1();
            String s2 = app.getGet2();
            String s3 = app.getGet3();
        }

    }

把HTTP请求封装成工具类

       我们可以把HTTP的GET请求封装在类里,方便调用
对于HttpURLConnection我们要写一个接口使用回调的方法返回数据,而对于OkHttp它内部吧开启线程回调都处理好了,可直接使用。
接口:

package com.example.revise_9_1;

public interface HttpCallbcakListener {
    
    
    void onFinish(String response);
    void onError(Exception e);
}

工具类:

package com.example.revise_9_1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import okhttp3.OkHttpClient;
import okhttp3.Request;

public class HttpUtil {
    
    
    public static void sendHttpRequest(final String address, final HttpCallbcakListener listener){
    
    
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                HttpURLConnection httpURLConnection = null;
                BufferedReader bufferedReader = null;
                try {
    
    
                    URL url = new URL(address);
                    httpURLConnection = (HttpURLConnection) url.openConnection();
                    httpURLConnection.setRequestMethod("GET");
                    httpURLConnection.setReadTimeout(8000);     //设置读取超时
                    httpURLConnection.setConnectTimeout(8000);  //读取连接超时
                    httpURLConnection.setDoOutput(true);
                    httpURLConnection.setDoInput(true);
                    InputStream inputStream = httpURLConnection.getInputStream();
                    bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                    StringBuilder stringBuilder = new StringBuilder();
                    String Line;
                    while((Line=bufferedReader.readLine())!= null){
    
    
                        stringBuilder.append(Line);
                    }
                    if(listener!=null)
                    	//吧得到的数据通过接口返回
                        listener.onFinish(stringBuilder.toString());
                } catch (Exception e) {
    
    
                    if(listener!=null)
                    	//如果发生错误,返回对应的错误类型
                        listener.onError(e);
                    e.printStackTrace();
                }finally {
    
    
                    if(httpURLConnection!=null)
                        httpURLConnection.disconnect();
                    if(bufferedReader!=null) {
    
    
                        try {
    
    
                            bufferedReader.close();
                        } catch (IOException e) {
    
    
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }
    public static void sendOkHttpRequest(String address,okhttp3.Callback callback){
    
    
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address)
                .build();
        //OkHtt在enqueue()方法的内部已经帮我们开好子线程了,它会在子线程中去执行HTTP请求,并将结果回调到okhttp3.Callback中
        client.newCall(request).enqueue(callback);
    }
}

调用:

 String adress = "http://www.baidu.com";
                HttpUtil.sendHttpRequest(adress, new HttpCallbcakListener() {
    
    
                    @Override
                    public void onFinish(final String response) {
    
    
                    //处理数据
                        runOnUiThread(new Runnable() {
    
    
                            @Override
                            public void run() {
    
    
                                textView.setText(response);
                            }
                        });

                    }

                    @Override
                    public void onError(Exception e) {
    
    
                        e.printStackTrace();
                    }
                });
 String adress1 = "http://www.baidu.com";
                HttpUtil.sendOkHttpRequest(adress1, new Callback() {
    
    
                    @Override
                    public void onFailure(@NotNull Call call, @NotNull IOException e) {
    
    

                    }

                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
    
    
                        final String st = response.body().string();
                        runOnUiThread(new Runnable() {
    
    
                            @Override
                            public void run() {
    
    
                                textView.setText(st);
                            }
                        });


                    }
                });

猜你喜欢

转载自blog.csdn.net/haazzz/article/details/108716934