Android 使用网络技术(1)

请求服务器返回数据

public class HttpUtil {

/**

  • 发送网络请求

  • 这个需要放在子线程中操作

  • 子线程不能更新UI

*/

public static String sendHttpRequest(final String address,final HttpCallbackListener listener){

new Thread(new Runnable() {

@Override

public void run() {

Httpconnection connection = null;

try {

//1. 创建一个URL对象

URL url = new URL(“https://www.baidu.com”);

//2. 打开连接 获得Httpconnection

connection = (Httpconnection) url.openConnection();

//3. 设置HTTP请求的方式

connection.setRequestMethod(“GET”);

//4. 设置一些参数 连接超时时间 读取超时时间

connection.setConnectTimeout(8000);

connection.setReadTimeout(8000);

//5. 在获取url请求的数据前需要判断响应码,200 :成功,206:访问部分数据成功

// 300:跳转或重定向 400:错误 500:服务器异常

int responseCode = connection.getResponseCode();

if (responseCode == 200) {

//6. 获取服务器返回的输入流

InputStream inputStream = connection.getInputStream();

//7. 将输入量解析出来

String result = StreamUtils.streamToString(inputStream);

if(listener != null){

//回调onFinish()方法

listener.onFinish(result);

}

}

} catch (Exception e) {

if(listener != null){

//回调onError()方法

listener.onError(e);

}

e.printStackTrace();

} finally {

//9. 最后记得断开连接

if (connection != null){

connection.disconnect();//关闭http连接

}

}

}

}).start();

}

}

这其中StreamUtils代码如下:

public class StreamUtils {

//将流转换为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方式

提交数据给服务器,把HTTP请求的方式改成POST,并在获取输入流之前把要提交的数据写出即可.注意每条

数据都要以键值对的形式存在,数据与数据之间用&符号隔开.

//3. 设置HTTP请求的方式

urlConnection.setRequestMethod(“POST”);

connection.setRequestMethod(“POST”);

DataOutPutStream out = new DataOutputStream(connection.getOutputStream());

out.writeBytes(“username=admin&passwod=123456”);

2.2 使用OkHttp


开源库,网络通信.有许多出色的网络通信库都可以替代原生的HttpURLConnection,而其中OkHttp无疑是

做得最出色的一个.

现在已经成了广大Android开发者首选的网络通信库.

OkHttp的项目主页地址是https://github.com/square/okhttp

使用方法

  1. 编辑app/build.gradle,在dependencies中添加如下内容:

compile ‘com.squareup.okhttp3:okhttp:3.6.0’

  1. 发送GET请求

//1. 首先创建OkHttpClient对象

OkHttpClient client = new OkHttpClient();

//2. 创建Request对象

Request request = new Request.Builder()

.url(“http://www.baidu.com”) //设置目标地址URL

.build();

//3.获取服务器返回的数据 就是这个Response对象

Response response = client.newCall(request).execute();

//4. 将数据弄出来

String responseData = response.body().string();

//5 . 通过Handler更新UI

Message msg = Message.obtain();

msg.obj = responseData;

handler.sendMessage(msg);

在开发中一般是像下面这样用的

public class HttpUtil {

/**

  • 发送网络请求 用OkHttp GET方式

  • sendRequestWithOkHttp()方法中有一个okhttp3.Callback参数,这个是OkHttp库中自带的一个回调接口

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

  • okhttp3.Callback当中.

*/

public static void sendRequestWithOkHttp(String address,okhttp3.Callback callback){

//1. 首先创建OkHttpClient对象

OkHttpClient client = new OkHttpClient();

//2. 创建Request对象

Request request = new Request.Builder()

.url(address) //设置目标地址URL

.build();

//3.获取服务器返回的数据

client.newCall(request).enqueue(callback);

}

}

当然这样写到HttpUtil类里面的话,调用方需要这样写:

HttpUtil.sendOkHttpRequest(“http://www.baidu.com”,new okhttp3.Callback(){

@Override

public void onResponse(Call call,Response response) throws IOException {

//得到服务器返回的具体内容

String responseData = response.body().string();

}

@Override

public void onFailure(Call call, IOException e) {

//在这里对异常情况进行处理

}

});

  1. 发送POST请求

我们需要先构造出一个RequestBody对象来存放待提交的参数

RequestBody requestBody = new FormBody.Builder()

.add(“username”,“admin”)

.add(“password”,“123”)

.build();

然后在Request.Builder中调用post()方法,并将RequestBody对象传入

Request request = new Request.Builder()

.url(“http://www.baidu.com”)

.post(requestBody)

.build();

3. 解析xml格式

===========

Pull解析方式

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) {

// 开始解析某个结点

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();

}

}

SAX解析方式

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 {

// 记录当前结点名

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());

// 最后要将StringBuilder清空掉

id.setLength(0);

name.setLength(0);

version.setLength(0);

}

}

@Override

public void endDocument() throws SAXException {

super.endDocument();

}

}

然后

private void parseXMLWithSAX(String xmlData) {

try {

SAXParserFactory factory = SAXParserFactory.newInstance();

XMLReader xmlReader = factory.newSAXParser().getXMLReader();

ContentHandler handler = new ContentHandler();

// 将ContentHandler的实例设置到XMLReader中

xmlReader.setContentHandler(handler);

// 开始执行解析

xmlReader.parse(new InputSource(new StringReader(xmlData)));

} catch (Exception e) {

e.printStackTrace();

}

}

4. 解析JSON格式

============

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

解析JSON数据有很多方法.可以使用官方提供的JSONObject,也可以使用谷歌的开源库GSON.另外,一些第三方的开源库如Jackson,FastJSON等也非常不错.

4.1 使用JSONObject


private void parseJSONWithJSONObject(String jsonData){

/**

  • 客户端数据为

  • [{“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. 创建JSONArray 里面是数组

JSONArray jsonArray = new JSONArray(jsonData);

//2. 解析数组里面的每一个数据

for (int i=0; i<jsonArray.length(); i++){

//3. 一个数组元素就是一个JSONObject

JSONObject jsonObject = jsonArray.getJSONObject(i);

//4. 根据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 使用GSON


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

相信它会给大家带来很多收获:

img

当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

  • 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
  • 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。

当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

[外链图片转存中…(img-LXPPoA3S-1713733810789)]

最后

这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

相信它会给大家带来很多收获:

[外链图片转存中…(img-34IlVk7L-1713733810790)]

当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

  • 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
  • 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。

当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值