第一行代码学习笔记第九章——使用网络技术
知识点目录
- 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的主要作用就是在自己应用程序中显示网页,借助它我们可以在应用程序中嵌入一个浏览器。
一般使用步骤如下:
在布局中使用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>
实现网页跳转
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"); //转入要跳转的网址}}
添加网络访问权限
<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格式数据的解析方式。
非常感谢您的耐心阅读,希望我的文章对您有帮助。欢迎点评、转发或分享给您的朋友或技术群。
第一行代码学习笔记第九章——使用网络技术相关推荐
- 第一行代码学习笔记第二章——探究活动
知识点目录 2.1 活动是什么 2.2 活动的基本用法 2.2.1 手动创建活动 2.2.2 创建和加载布局 2.2.3 在AndroidManifest文件中注册 2.2.4 在活动中使用Toast ...
- 第一行代码学习笔记第六章——详解持久化技术
知识点目录 6.1 持久化技术简介 6.2 文件存储 * 6.2.1 将数据存储到文件中 * 6.2.2 从文件中读取数据 6.3 SharedPreferences存储 * 6.3.1 将数据存储到 ...
- 第一行代码学习笔记第七章——探究内容提供器
知识点目录 7.1 内容提供器简介 7.2 运行权限 * 7.2.1 Android权限机制详解 * 7.2.2 在程序运行时申请权限 7.3 访问其他程序中的数据 * 7.3.1 ContentRe ...
- 第一行代码学习笔记第五章——详解广播机制
知识点目录 5.1 广播机制 5.2 接收系统广播 * 5.2.1 动态注册监听网络变化 * 5.2.2 静态注册实现开机广播 5.3 发送自定义广播 * 5.3.1 发送标准广播 * 5.3.2 发 ...
- 第一行代码学习笔记第三章——UI开发的点点滴滴
知识点目录 3.1 如何编写程序界面 3.2 常用控件的使用方法 * 3.2.1 TextView * 3.2.2 Button * 3.2.3 EditText * 3.2.4 ImageView ...
- 第一行代码学习笔记第四章——探究碎片
知识点目录 4.1 碎片是什么 4.2 碎片的使用方式 * 4.2.1 碎片的简单用法 * 4.2.2 动态添加碎片 * 4.2.3 在碎片中模拟返回栈 * 4.2.4 碎片和活动之间进行通信 4.3 ...
- 第一行代码学习笔记第八章——运用手机多媒体
知识点目录 8.1 将程序运行到手机上 8.2 使用通知 * 8.2.1 通知的基本使用 * 8.2.2 通知的进阶技巧 * 8.2.3 通知的高级功能 8.3 调用摄像头和相册 * 8.3.1 调用 ...
- 第一行代码学习笔记第十章——探究服务
知识点目录 10.1 服务是什么 10.2 Android多线程编程 * 10.2.1 线程的基本用法 * 10.2.2 在子线程中更新UI * 10.2.3 解析异步消息处理机制 * 10.2.4 ...
- 安卓教程----第一行代码学习笔记
安卓概述 系统架构 Linux内核层,还包括各种底层驱动,如相机驱动.电源驱动等 系统运行库层,包含一些c/c++的库,如浏览器内核webkit.SQLlite.3D绘图openGL.用于java运行 ...
最新文章
- php.ini 中开启短标签
- python socket 通信
- 地摊重现江湖,疫情带给我们的意外收获
- 总结一下嵌入式OLED显示屏显示中文汉字的办法
- ios 边录音边放_关于Android和iOS系统OneNote支持边录音边记笔记的需求和建议
- C++ 学习笔记之——输入和输出
- Java黑皮书课后题第2章:2.3(将英尺转化为米)编写程序,读入英尺数,将其转换为米数并显示结果。1英尺等于0.305米
- .Net Core和Jexus配置HTTPS服务
- Bootstrap3 工具提示插件的方法
- 用Excel教会你PID算法
- SSH远程执行命令环境变量问题
- Mac Automator小教程,简单易懂
- 2022年,消费品牌如何把握新的商业脉络?
- 定时上传文件至ftp服务器,CuteFTP FTP文件的定时上传图文教程
- Excel辅助“校验”
- layui实现动态多级菜单
- cocos creator 使用anysdk接入admod
- R语言使用order函数降序排序向量数据、设置decreasing参数进行降序排序
- 货拉拉Android稳定性治理
- 安装免费360随身wifi一键创建WiFi热点让电脑与手机共享wifi无线网