知识点目录

  • 9.1 WebView的用法
  • 9.2 使用HTTP协议访问网络
    * 9.2.1 使用HttpURLConnection
    * 9.2.2 使用OkHttp
  • 9.3 解析XML格式数据
    * 9.3.1 Pull解析方式
    * 9.3.2 SAX解析方式
  • 9.4 解析JSON格式数据
    * 9.4.1 使用JSONObject
    * 9.4.2 使用GSON
  • 9.5 网络编程的最佳实践
  • 9.6 小结与点评

知识点回顾

9.1 WebView的用法

WebView的主要作用就是在自己应用程序中显示网页,借助它我们可以在应用程序中嵌入一个浏览器。

一般使用步骤如下:

  1. 在布局中使用WebView控件

     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><WebViewandroid:id="@+id/web_view"android:layout_width="match_parent"android:layout_height="match_parent"></WebView></LinearLayout>
    
  2. 实现网页跳转

     public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);WebView webView = (WebView) findViewById(R.id.web_view);webView.getSettings().setJavaScriptEnabled(true); //支持JavaScript//当需要从一个网页跳转到另一个网页时,希望目标网页仍在当前WebView中显示,而不是打开系统浏览器webView.setWebViewClient(new WebViewClient());webView.loadUrl("http://www.baidu.com"); //转入要跳转的网址}}
    
  3. 添加网络访问权限

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

效果图:

在运行程序之前,需要确保手机或者模拟器是连网的。

WebView中已经帮我们做了如下步骤的封装:

  • 发送HTTP请求

  • 接收服务响应

  • 解析返回的数据

  • 页面展示

9.2 使用HTTP协议访问网络

HTTP协议的工作原理:

客户端向服务器发送一条HTTP请求,服务器收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理。

9.2.1 使用HttpURLConnection

Android原生发送HTTP请求的方式有两种:

  • HttpClient

  • HttpURLConnection

但HttpClient存在API数量过多、扩展困难等缺点,Android团队已经不建议我们使用HttpClient。在Android6.0系统中,HttpClient的功能已经被完全移除。

Android官方建议使用HttpURLConnection。

HttpURLConnection一般使用步骤:

1.布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/send_request"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Send Request"android:textAllCaps="false"/><ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/response_text"android:layout_width="match_parent"android:layout_height="wrap_content" /></ScrollView></LinearLayout>

ScrollView可以让用户以滚动的形式查看屏幕外的那部分内容。

2.使用示例代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private TextView mResponseText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button sendRequest = (Button) findViewById(R.id.send_request);mResponseText = (TextView) findViewById(R.id.response_text);sendRequest.setOnClickListener(this);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.send_request) {sendRequestWithHttpURLConnection();}}private void sendRequestWithHttpURLConnection() {//开启线程来发送网络请求new Thread(new Runnable() {@Overridepublic void run() {HttpURLConnection connection = null;BufferedReader reader = null;try {URL url = new URL("https://www.baidu.com");connection = ((HttpURLConnection) url.openConnection());// 设置请求方式,默认为GETconnection.setRequestMethod("GET");// 设置连接超时connection.setConnectTimeout(8000);// 设置读取超时connection.setReadTimeout(8000);// 获取网络的输入流InputStream inputStream = connection.getInputStream();// 读取输入流中的数据reader = new BufferedReader(new InputStreamReader(inputStream));StringBuilder response = new StringBuilder();String line;while ((line = reader.readLine()) != null) {response.append(line);}showResponse(response.toString());} catch (IOException e) {e.printStackTrace();}}}).start();}private void showResponse(final String response) {runOnUiThread(new Runnable() {@Overridepublic void run() {//在这里进行UI操作,将结果显示到界面上mResponseText.setText(response);}});}
}

因为Android是不允许在子线程中进行UI操作的,这里我们通过使用runOnUiThread()方法将线程切换到主线程,然后再更新UI元素。

3.添加权限

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

4.Post请求

如果想要给服务器提交数据,只需要将HTTP请求方法改为POST,并在获取输入流之前把要提交的数据写出即可。每条数据之间以键值对的形式存在,数据与数据之间用&符号隔开。如下所示:

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

效果图:

9.2.2 使用OkHttp

OkHttp是Square公司开发的一个开源盛行的网络通信开源库。

OkHttp的项目主页地址是:

https://github.com/square/okhttp

可以在主页看到当前最新的版本。

在使用OkHttp之前,需要先在app/build.gradle文件的dependencies闭包中添加如下内容:

dependencies {implementation("com.squareup.okhttp3:okhttp:4.2.2")
}

OkHttp具体用法如下:

get请求:

new Thread(new Runnable() {@Overridepublic void run() {try {//创建一个OkHttpClient实例OkHttpClient client = new OkHttpClient();//创建一个Request对象Request request = new Request.Builder().url("http://www.baidu.com").build();//创建Call对象,并调用它的execute()方法发送请求并获取服务器返回的数据Response response = client.newCall(request).execute();String responseData = response.body().string();showResponse(responseData);} catch (IOException e) {e.printStackTrace();}}
}).start();

POST请求:

new Thread(new Runnable() {@Overridepublic void run() {try {OkHttpClient client = new OkHttpClient();RequestBody body = new FormBody.Builder().add("username", "admin").add("password", "123456").build();Request request = new Request.Builder().url("http://www.baidu.com").post(body).build();// 创建Call对象,并调用它的execute()方法发送请求并获取服务器返回的数据Response response = client.newCall(request).execute();String responseData = response.body().string();} catch (Exception e) {e.printStackTrace();}}
}).start();

上面只对OkHttp的get和post进行简单的使用,更多的使用还需要到具体项目中去体验。

9.3 解析XML格式数据

解析XML格式的数据有很多种,我们这里主要学习下Pull解析和SAX解析。

9.3.1 Pull解析方式

具体用法如下:

private void parseXMLWithPull(String xmlData) {try {//获取一个XmlPullParserFactory实例对象XmlPullParserFactory factory = XmlPullParserFactory.newInstance();//通过XmlPullParserFactory实例对象获得一个XmlPullParser对象XmlPullParser xmlPullParser = factory.newPullParser();//将XML数据设置进去xmlPullParser.setInput(new StringReader(xmlData));//通过getEventType()得到当前的解析事件int eventType = xmlPullParser.getEventType();String id = "";String name = "";String version = "";//开始解析,如果当前的解析事件不等于XmlPullParser.END_DOCUMENT,则表示解析还没完成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 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();}
}
9.3.2 SAX解析方式

SAX解析比Pull解析复杂一些,但在语义方面会更加清楚。

具体用法如下:

第一步:新建一个类继承自DefaultHandler

public class ContentHandler extends DefaultHandler {private String nodeName;private StringBuilder id;private StringBuilder name;private StringBuilder version;//开始XML解析时调用@Overridepublic void startDocument() throws SAXException {id = new StringBuilder();name = new StringBuilder();version = new StringBuilder();}//开始解析某个节点时调用@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {// 记录当前节点nodeName = localName;}//获取去节点中内容的时候调用@Overridepublic 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);}}//完成解析某个节点的时候调用@Overridepublic 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());// 最后要将StringBuilder清空掉id.setLength(0);name.setLength(0);version.setLength(0);}}//完成整个XML解析时调用@Overridepublic void endDocument() throws SAXException {super.endDocument();}
}

第二步:开始解析

private void parseXMLWithSAX(String xmlData) {try {//获取一个SAXParserFactory对象SAXParserFactory factory = SAXParserFactory.newInstance();//获取一个XMLReader对象XMLReader xmlReader = factory.newSAXParser().getXMLReader();//new一个ContentHandler对象ContentHandler handler = new ContentHandler();//将ContentHandler的实例设置到XMLReader中xmlReader.setContentHandler(handler);//开始执行解析xmlReader.parse(new InputSource(new StringReader(xmlData)));} catch (Exception e) {e.printStackTrace();}
}

9.4 解析JSON格式数据

相比于XML,JSON数据的主要优势是体积更小,在网上传输的时候可以更省流量。但缺点在于,JSON语义性较差,看起来不如XML直观。

解析JSON数据的方法有很多种,我们主要学习官方提供的JSONObject和谷歌开源库GSON。

9.4.1 使用JSONObject

具体用法如下:

private void parseJSONWithJSONObject(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 is " + id);Log.d("MainActivity", "name is " + name);Log.d("MainActivity", "version is " + version);}} catch (Exception e) {e.printStackTrace();}
}
9.4.2 使用GSON

第一步:添加GSON库的依赖

在app/build.gradle文件的dependencies闭包中添加如下内容:

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

第二步:编写json数据的实例类

public class App {private String id;private String name;private String version;public void setId(String id) {this.id = id;}public void setName(String name) {this.name = name;}public void setVersion(String version) {this.version = version;}public String getId() {return id;}public String getName() {return name;}public String getVersion() {return version;}
}

当然这一步可以使用GsonFormat这个插件去完成!!!

第三步:具体解析

private void parseJSONWithGSON(String jsonData) {Gson gson = new Gson();//JSON数据是对象型App app = gson.fromJson(jsonData, App.class);//JSON数据是数组型List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>(){}.getType());
}

这里根据JSON数据的不同类型,解析方式稍微有点不同。

9.5 网络编程的最佳实践

使用HttpURLConnection网络请求的工具类。

第一步:定义个接口

public interface HttpCallbackListener {/*** 当服务器成功相应我们的请求时调用* @param response 服务器返回的数据*/void onFinish(String response);/***当网络操作出现错误的时候调用* @param e 记录着错误的详细信息*/void onError(Exception e);
}

第二步:编写工具类

public class HttpUtil {public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {new Thread(new Runnable() {@Overridepublic 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 response = new StringBuilder();String line;while ((line = reader.readLine()) != null) {response.append(line);}if (listener != null) {//回调onFinish()方法listener.onFinish(response.toString());}} catch (Exception e) {e.printStackTrace();if (listener != null) {//回调onError()方法listener.onError(e);}} finally {if (connection != null) {connection.disconnect();}}}}).start();}
}

第三步:使用工具类

HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {@Overridepublic void onFinish(String response) {// 在这里根据返回内容执行具体的逻辑}@Overridepublic void onError(Exception e) {// 在这里对异常情况进行处理}
});

使用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);}
}

这里newCall()后面调用的是enqueue()方法,enqueue()方法内部已经帮我们开启了子线程。

第二步:使用工具类

HttpUtil.sendOkHttpRequest("address", new okhttp3.Callback() {@Overridepublic void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {//得到服务器返回的具体内容String responseData = response.body().string();}@Overridepublic void onFailure(@NotNull Call call, @NotNull IOException e) {//在这里对异常情况进行处理}
});

9.6 小结与点评

本章主要学习了在Android中使用HTTP协议来进行网络交互。使用HttpURLConnection和OkHttp来发送HTTP请求。然后学习了XML和JSON格式数据的解析方式。

非常感谢您的耐心阅读,希望我的文章对您有帮助。欢迎点评、转发或分享给您的朋友或技术群。

第一行代码学习笔记第九章——使用网络技术相关推荐

  1. 第一行代码学习笔记第二章——探究活动

    知识点目录 2.1 活动是什么 2.2 活动的基本用法 2.2.1 手动创建活动 2.2.2 创建和加载布局 2.2.3 在AndroidManifest文件中注册 2.2.4 在活动中使用Toast ...

  2. 第一行代码学习笔记第六章——详解持久化技术

    知识点目录 6.1 持久化技术简介 6.2 文件存储 * 6.2.1 将数据存储到文件中 * 6.2.2 从文件中读取数据 6.3 SharedPreferences存储 * 6.3.1 将数据存储到 ...

  3. 第一行代码学习笔记第七章——探究内容提供器

    知识点目录 7.1 内容提供器简介 7.2 运行权限 * 7.2.1 Android权限机制详解 * 7.2.2 在程序运行时申请权限 7.3 访问其他程序中的数据 * 7.3.1 ContentRe ...

  4. 第一行代码学习笔记第五章——详解广播机制

    知识点目录 5.1 广播机制 5.2 接收系统广播 * 5.2.1 动态注册监听网络变化 * 5.2.2 静态注册实现开机广播 5.3 发送自定义广播 * 5.3.1 发送标准广播 * 5.3.2 发 ...

  5. 第一行代码学习笔记第三章——UI开发的点点滴滴

    知识点目录 3.1 如何编写程序界面 3.2 常用控件的使用方法 * 3.2.1 TextView * 3.2.2 Button * 3.2.3 EditText * 3.2.4 ImageView ...

  6. 第一行代码学习笔记第四章——探究碎片

    知识点目录 4.1 碎片是什么 4.2 碎片的使用方式 * 4.2.1 碎片的简单用法 * 4.2.2 动态添加碎片 * 4.2.3 在碎片中模拟返回栈 * 4.2.4 碎片和活动之间进行通信 4.3 ...

  7. 第一行代码学习笔记第八章——运用手机多媒体

    知识点目录 8.1 将程序运行到手机上 8.2 使用通知 * 8.2.1 通知的基本使用 * 8.2.2 通知的进阶技巧 * 8.2.3 通知的高级功能 8.3 调用摄像头和相册 * 8.3.1 调用 ...

  8. 第一行代码学习笔记第十章——探究服务

    知识点目录 10.1 服务是什么 10.2 Android多线程编程 * 10.2.1 线程的基本用法 * 10.2.2 在子线程中更新UI * 10.2.3 解析异步消息处理机制 * 10.2.4 ...

  9. 安卓教程----第一行代码学习笔记

    安卓概述 系统架构 Linux内核层,还包括各种底层驱动,如相机驱动.电源驱动等 系统运行库层,包含一些c/c++的库,如浏览器内核webkit.SQLlite.3D绘图openGL.用于java运行 ...

最新文章

  1. php.ini 中开启短标签
  2. python socket 通信
  3. 地摊重现江湖,疫情带给我们的意外收获
  4. 总结一下嵌入式OLED显示屏显示中文汉字的办法
  5. ios 边录音边放_关于Android和iOS系统OneNote支持边录音边记笔记的需求和建议
  6. C++ 学习笔记之——输入和输出
  7. Java黑皮书课后题第2章:2.3(将英尺转化为米)编写程序,读入英尺数,将其转换为米数并显示结果。1英尺等于0.305米
  8. .Net Core和Jexus配置HTTPS服务
  9. Bootstrap3 工具提示插件的方法
  10. 用Excel教会你PID算法
  11. SSH远程执行命令环境变量问题
  12. Mac Automator小教程,简单易懂
  13. 2022年,消费品牌如何把握新的商业脉络?
  14. 定时上传文件至ftp服务器,CuteFTP FTP文件的定时上传图文教程
  15. Excel辅助“校验”
  16. layui实现动态多级菜单
  17. cocos creator 使用anysdk接入admod
  18. R语言使用order函数降序排序向量数据、设置decreasing参数进行降序排序
  19. 货拉拉Android稳定性治理
  20. 安装免费360随身wifi一键创建WiFi热点让电脑与手机共享wifi无线网

热门文章

  1. 入坑推荐系统,从Google这篇开始
  2. 最强的Attention函数诞生啦,带给你意想不到的巨大提升!
  3. 网易云信集成视频教程(三):如何通过SDK实现自定义消息?
  4. 互联网1分钟 |1217
  5. 操作系统期末复习知识点
  6. 使用gulp和vsc构建高效的typescript开发环境
  7. 关于css3的自定义字体
  8. PHP实例——产生随机字符串
  9. Processing--鼠标响应(1)
  10. mysql 平均月份_Mysql按月份统计和按时段统计SQL