请求服务器返回数据
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
使用方法
- 编辑
app/build.gradle
,在dependencies
中添加如下内容:
compile ‘com.squareup.okhttp3:okhttp:3.6.0’
- 发送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) {
//在这里对异常情况进行处理
}
});
- 发送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移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
- 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
- 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!**
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
[外链图片转存中…(img-LXPPoA3S-1713733810789)]
最后
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
[外链图片转存中…(img-34IlVk7L-1713733810790)]
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
- 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
- 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!