【Android】使用网络技术、WebView的用法、OkHttp的用法、解析XML格式数据(Pull,SAX)、解析JSON格式数据(JSONObject、GSON)

一、WebView的用法

    <WebView
        android:id="@+id/Web_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:layout_editor_absoluteX="165dp"
        tools:layout_editor_absoluteY="58dp" />
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WebView webView = findViewById(R.id.Web_view);
        Button button = findViewById(R.id.button);

        //让WebView支持js脚本
        webView.getSettings().setJavaScriptEnabled(true);
        
        //当需要从一个网页跳转到另一个网页,目标网站仍然在WebView中显示
        webView.setWebChromeClient(new WebChromeClient());


        //点击按钮在应用中打开网页
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //打开的网址内容
                webView.loadUrl("https://www.baidu.com");
                //使得按钮不可见
                button.setVisibility(View.INVISIBLE);
            }
        });
    }
}

二、使用OkHttp

1、ScrollView

由于手机屏幕的空间一般都比较小,有些时候过多的内容一屏是显示不下的,借助ScrollView控件的话,我们就可以以滚动的形式查看屏幕外的那部分内容。

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:layout_editor_absoluteX="88dp"
        tools:layout_editor_absoluteY="118dp">

        <TextView
            android:id="@+id/textinput_suffix_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </ScrollView>

2、runOnUiThread

private void showResponse(String str){
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            TextView textView = findViewById(R.id.textinput_suffix_text);
            textView.setText(str);
        }
    });
}

runOnUiThread是Android中的一个方法,它允许您在非UI线程中更新UI。在Android应用中,UI元素(例如TextView、Button等)只能在主线程(也称为UI线程)上更新。如果您尝试在非UI线程上直接更新UI元素,将会导致异常和崩溃。

3、GET请求

image-20230731103112569

private  void SendRequestWithOkHttp(){
    new Thread(new Runnable() {
        @Override
        public void run() {
            //打开okHttp
            OkHttpClient client = new OkHttpClient();
            //注册请求
            Request request = new Request.Builder().url("https://www.baidu.com").build();

            try {
                //接受向服务器发送请求
                Response response = client.newCall(request).execute();
                //获取报文的数据
                String responseData = response.body().string();
                showResponse(responseData);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
    }).start();
}

4、Post请求

image-20230731103848563

private  void SendRequestWithOkHttp(){
    new Thread(new Runnable() {
        @Override
        public void run() {
            //打开okHttp
            OkHttpClient client = new OkHttpClient();
            //发送构建数据
            RequestBody requestBody = new FormBody.Builder().add("uesr","admain").add("user","asdd").build();

            //将发送数据传递给请求
            Request request = new Request.Builder().url("https://baidu.com").post(requestBody).build();

            try {
                //接受向服务器发送请求
                Response response = client.newCall(request).execute();
                //获取报文的数据
                String  = response.body().string();
                showResponse(responseData);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
    }).start();
}

三、解析XML格式数据

1、Pull解析

private void parseXMlWithPull(String xmlData) {
    try {
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser xmlPullParser = factory.newPullParser();

        //放入xml数据进行解析
        xmlPullParser.setInput(new StringReader(xmlData));

        //获取当前解析事件
        int enventType = xmlPullParser.getEventType();
        String id = "";
        String name = "";
        String version = "";


        while (enventType != xmlPullParser.END_DOCUMENT) {
            String nodeName = xmlPullParser.getName();
            switch (enventType) {
                case START_TAG:
                    if ("id".equals(nodeName)) {
                        id = xmlPullParser.nextText();
                    }
                    if ("name".equals(nodeName)) {
                        name = xmlPullParser.nextText();
                    }
                    if ("version".equals(nodeName)) {
                        version = xmlPullParser.nextText();
                    }
                    break;
                case END_TAG:
                    if ("app".equals(nodeName)){
                        Log.d("YYYSS","id :"+id);
                        Log.d("YYYSS","name :"+name);
                        Log.d("YYYSS","version :"+version);
                    }
                    break;
            }
            //获取下一个解析事件
            enventType = xmlPullParser.next();

        }

    } catch (XmlPullParserException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

待解析数据如下:

image-20230731122123391

首先构造一个XmlPullParserFactory工厂,然后通过这个工厂构建XmlPullParser实例。在将需要解析的数据传入实例。

通过**getEventType()**可以得到当前的解析事件,然后在一个while循环中不断地进行解析,如果当前的解析事件不等于xmlPullParser.END_DOCUMENT(1),说明解析工作还没完成,调用next()方法后可以获取下一个解析事件。

在while循环中,我们通过getName()方法得到当前节点的名字,如果发现节点名等于id、name或version,就调用**nextText()**方法来获取节点内具体的内容,每当解析完一个app节点后就将获取到的内容打印出来。

2、SAX解析

2.1 重写DefaultHandler的五个方法

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

    //开始解析xml时调用
    @Override
    public void startDocument() throws SAXException {
        id = new StringBuilder();
        name = new StringBuilder();
        version = new StringBuilder();
    }

    //结束解析xml时调用
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

    //开始解析某个节点时调用
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        //记录当前节点名
        nodeName = localName;
    }

    //完成解析某个节点时调用
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("id".equals(nodeName)) {
            Log.d("YYYSS", "id :" + id);
            Log.d("YYYSS", "name :" + name);
            Log.d("YYYSS", "version :" + version);
        }
        //清空ShringBuilder
        id.setLength(0);
        name.setLength(0);
        version.setLength(0);
    }

    //获取节点内容时调用
    @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);
        }
    }
}

2.2 SAX解析的步骤

image-20230731152902875

private void parseXMlWithSAX(String xmlData) throws ParserConfigurationException, SAXException, IOException {
    // 创建SAX工厂,根据工厂获得XMLRead实例
    SAXParserFactory factory = SAXParserFactory.newInstance();
    XMLReader reader = factory.newSAXParser().getXMLReader();

    //将ContenHander的实例设置到XMLReader中
    ContentHander hander = new ContentHander();
    reader.setContentHandler(hander);

    //开始解析
    reader.parse(new InputSource(new StringReader(xmlData)));
}

InputSource是一个用于SAX解析器的输入源类,它提供了不同类型的数据输入源,使得SAX解析器能够从这些源中读取数据并进行解析。

四、解析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"}
]

1、使用JSONObject

private void parseJSONWithJSONobject(String jsonData){
    try {
        //获取具有数据的JSONArray的实例
        JSONArray jsonArray = new JSONArray(jsonData);

        //开始解析
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            Log.d("YHYHY",jsonObject.getString("id"));
            Log.d("YHYHY",jsonObject.getString("name"));
            Log.d("YHYHY",jsonObject.getString("version"));
        }

    } catch (JSONException e) {
        throw new RuntimeException(e);
    }
}

由于我们在服务器中定义的是一个JSON数组,因此这里首先是将服务器返回的数
据传人到了一个JS0NArray对象中。

然后循环遍历这个JSONArray,从中取出的每一个元素都是一个JS0NObject对象,每个JS0NObject对象中又会包含id、name和version这些数据。

接下来只需要调用**getString()**方法将这些数据取出。

2、使用GSON

github地址:GSON

添加依赖:

dependencies {
	implementation 'com.google.code.gson:gson:2.10.1'
}

GSON是非常简单的JSON数据解析方法,他可以将一段JSON数据映射为一个对象。

下代码为解析一个JSON数组:

private void parseJSONWithGSON(String jsonData){
    //获取GSON实例
    Gson gson = new Gson();
    
    //通过GSON实例映射GSON对象的List
    List<APP> appList = gson.fromJson(jsonData,  new TypeToken<List<APP>>(){}.getType());

    for(APP app : appList){
        Log.d("SSXSXS","id:"+app.getId());
        Log.d("SSXSXS","name:"+app.getName());
        Log.d("SSXSXS","id:"+app.getVersion());
    }
}

如果是解析一个JSON数据,可以使用这样的方法:

    APP app = gson.fromJson(jsonData, APP.class);

五、网络编程实践

使用Okhttp的回调方法:

public class HttpUtil {
    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);
    }
}

可以看到,send0kHttpRequest()方法中有一个okhttp3.Callback参数,这个是OkHttp库中自带的一个回调接口、。

然后在client,newCall()之后没有像之前那样一直调用execute()方法,而是调用了一个enqueue()方法,并把okhttp.3.Callback参数传入。

OkHttp在enqueue()方法的内部已经帮我们开好子线程了,然后会在子线程中去执行HTTP请求,并将最终的请求结果回调到okhttp3.Callback当中。

调用sengOkHttpRequest()方法的写法:

String address = "https://baidu.com";
HttpUtil.sendOkHttpRequest(address, new okhttp3.Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        //对异常情况的处理
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        //得到服务器的返回内容
    }
});
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摸鱼小小虫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值