Android 使用网络技术

  • Android 使用网络技术
  • 使用WebView
  • 使用Http协议访问网络
    • 1 使用HttpURLConnection
    • 2 使用OkHttp
  • 解析xml格式
  • 解析JSON格式
    • 1 使用JSONObject
    • 2 使用GSON

1. 使用WebView

有时候我们会遇到特殊需求,比如说要求在应用程序中展示一些网页.明确指出不允许打开系统浏览器.

WebView webView = (WebView) findViewById(R.id.web_view);
//设置支持JavaScript脚本
webView.getSettings().setJavaScriptEnabled(true);
//设置当需要从一个网页跳转到另一个网页时,任然在该WebView中显示
webView.setWebViewClient(new WebViewClient());
//展示相应网页的内容
webView.loadUrl("http://www.baidu.com");

2. 使用Http协议访问网络

在Android 6.0系统中,HttpClient的功能被完全移除了,标志这此功能被正式弃用.官方建议使用HttpURLConnection.

2.1 使用HttpURLConnection

通常情况下,我们都应该将这些通用的网络操作提取到一个公共的类里,并提供一个静态方法,当想要发起网络请求的时候,只需要简单地调用一下即可.

准备工作

子线程不能通过return返回数据,所以需要利用java的回调机制.将响应数据返回给调用方.先新建一个HttpCallbackListener

public interface HttpCallbackListener{//调用方在这里根据返回的内容执行具体的内容void onFinish(String response);//在这哭对异常情况进行处理void onError(Exception e);
}

GET方式

请求服务器返回数据

public class HttpUtil {/*** 发送网络请求* 这个需要放在子线程中操作* 子线程不能更新UI*/public static String sendHttpRequest(final String address,final HttpCallbackListener listener){new Thread(new Runnable() {@Overridepublic void run() {Httpconnection connection = null;try {//1. 创建一个URL对象URL url = new URL("https://www.baidu.com");//2. 打开连接  获得Httpconnectionconnection = (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 {//将流转换为Stringpublic 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’

  2. 发送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(){@Overridepublic void onResponse(Call call,Response response) throws IOException {//得到服务器返回的具体内容String responseData = response.body().string();}@Overridepublic 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;@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);}}@Overridepublic 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. 一个数组元素就是一个JSONObjectJSONObject 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

神奇之处在于,它可以将一段JSON格式的字符串自动映射成一个对象,从而不需要我们再手动去编写代码进行解析了.

准备工作:

编辑app/build.gradle文件,在dependencies闭包中添加如下内容

compile 'com.google.code.gson:gson:2.7'

示例

服务端的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"}]

这里首先需要创建一个app实体类

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

然后这样写:

 private void parseJSONWithGSON(String jsonData){Gson gson = new Gson();List<App> appList = gson.fromJson(jsonData,new TypeToken<List<App>>(){}.getType());for (App app : appList) {Log.i(TAG, "parseJSONWithGSON: "+app.getId());Log.i(TAG, "parseJSONWithGSON: "+app.getName());Log.i(TAG, "parseJSONWithGSON: "+app.getVersion());}
}

如果是单独的一个JApp对象,不是一个数组,那么这样写:

App app = json.fromJson(jsonData, App.class);

有时候由于JSON中的一些字段可能不太适合直接作为Java字段来命名,因此这里使用了@SerializedName注解的方式来让JSON字段和java字段之间建立映射关系

类似于下面这样

json结构如下:"basic" :{"city":"苏州","id":"CN101190401","update":{"loc":"2016-08-08 21:58"}}

public class Basic {@SerializedName("city")public String cityName;@SerializedName("id")public int weatherId;public Update update;public class Update {@SerializedName("loc")public String updateTime;}}

5.

Android 使用网络技术相关推荐

  1. Java后端学Android(13)-使用网络技术

    使用WebView WebView可以让在应用程序中展示一些网页,加载和显示网页都是浏览器的任务,但是需求又有明确指出,不允许打开系统的浏览器.所以WebView就是能帮助我们在页面中显示一个网页 a ...

  2. android平台应用技术特点,Android平台应用安全关键技术研究

    摘要: 最近几年来,随着智能手机的普及和移动互联网技术的发展,手机成了人们日常生活中不可缺少的一部分.在众多的智能手机操作系统里面,Android系统以其开源,自由,免费等特点占有着很大的市场占有率. ...

  3. Android热修复技术初探(三):动态加载外部资源

    前面已经介绍了Android平台上的几种ClassLoader,这几种ClassLoader都有各自的使用场景,有了这些基础知识之后,才能更好地理解以及探究Android热修复技术.首先我们来探究怎么 ...

  4. Android --- 5G网络,jetpack库

    连接网络后,要对网络进行检测,判断是否连接了5G网络.Android 11及之后的版本添加了5G API,可以调用此API来检测设备是否连接了5G网络(这是5G设备的检测).若是没有5G设备,也可以使 ...

  5. python android开发月薪_同事逆袭面进阿里P7 年薪60W+,临别留下一张Android开发重点技术路线图…...

    现在 通过职友集 北京 Android 工程师「 而今年因为 如果你在中小型公司,其实 20K 左右,几乎已经是个极限,薪资想继续提升很困难.而在 首先我们先看一下岗位职责: 1.负责 岗位要求: 1 ...

  6. Android热更新技术的研究与实现Sophix

    所以阿里爸爸一直在进步着呢,知道技术存在问题就要去解决问题,这不,从Dexposed-->AndFix-->HotFix-->Sophix,技术是越来越成熟了. Android热更新 ...

  7. Android热修复技术选型参考

    背景 热修复就是通过下发补丁包,让已安装的客户端动态更新,用户不用重新安装APP,就能够修复软件缺陷. 热修复技术对比 1.公司角度 大致可以分为阿里系和腾讯系和其他,如下: 阿里系 Dexposed ...

  8. Android App 开发技术图谱

    Android App 开发技术图谱 转载请注明出处:www.leoyanblog.com 本文出自 LeoYan 的博客 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 LeoYa ...

  9. Android智能手机网络防火墙开发的经验心得

    首届 Google 暑期大学生博客分享大赛--2010 Andriod 篇 Android 智能手机网络防火墙开发的经验心得 这篇博客主要讲述我实现一款Android手机上网防火墙的一个经验心得分享. ...

最新文章

  1. PowerDesigner的数据类型
  2. 快速学会开发微信小程序
  3. 怎样从red hat linux图形登录改成从文本登录
  4. dhh basecamp_使Basecamp的薪酬透明化保留了人才
  5. Android Drawable文件夹对应像素密度
  6. php 自学提升进阶路线,瓶颈
  7. 微信小程序实现微信登录详解(JAVA后台)
  8. C语言程序设计学习总结
  9. Python人脸检测与人脸数据集的生成
  10. 电子厂计算机维修周记,关于电子厂实习周记范文
  11. Python - 面向对象编程 - 类变量、实例变量/类属性、实例属性
  12. Win7 每天定时关机
  13. MS SqlServer海量数据分页存储过程收集
  14. 微信小程序 MinUI 组件库系列之 abnor 异常流组件
  15. Windows10 插入耳机没声音,安装驱动无效问题解决
  16. 从零开始打造一款干净的打卡小程序
  17. Commvault蔡报永:点亮你的暗数据
  18. mall前端项目的安装与部署
  19. Oracle中的触发器(trigger)
  20. 如何用W7100A实现串口转以太网(一)

热门文章

  1. C#+AE 叠加分析
  2. 第一数学归纳法 vs 第二数学归纳法 vs 良序定理
  3. Java基础面试题——IO流
  4. windbg调试 wow64 内核dump
  5. python制作冰花_煎饺不用一滴油!“冰花水煎饺”香酥多汁,一点不油腻
  6. django整合xadmin
  7. 开源 免费 java CMS - FreeCMS1.9 简历管理
  8. 华三交换机ping大包命令_H3C交换机命令大全
  9. 修改手机屏幕刷新率_什么是屏幕刷新率?高刷新率屏幕为手机带来什么
  10. web.config中connectionStrings数据库连接字符串介绍