网络编程

HTTP协议

我们做android开发的,做的就是程序方面的,用术语说就是应用层,给用户用的东西,那么应用层就需要受到http协议的控制,下面我们看看http协议的主要特点

  • 支持c/s模式
  • 简单快速:只需要传送请求方法和路径,请求方法常用的有:GET、HEAD、POST等
  • 灵活:允许传输任意类型的数据对象,用Content-Type进行标记
  • 无连接: 限制每次连接只处理一个请求
  • 无状态:对书屋处理没有记忆功能

HTTP的URL格式

  • http://host[:port][/path]
  • http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用默认端口88;path指定请求资源的URI;

常见的状态码的意思如下

200 OK:客户端请求成功
403 Forbidden:服务器收到请求,但是拒绝提供服务
404 Not Found:服务器无法根据客户端的请求找到资源
500 Internal Server Error:服务器发生不可预期的错误

http网络请求的问题(https是没有问题的)

  • 更改网络安全配置
    • 在res新增xml目录,创建
network_security_config.xml请求
<network-security-config>
    <base-config cleartextTrafficPermitted="true"/>
</network-security-config>
  • 在AndroidManifest.xml中的application标签增加一下属性
android:networkSecurityConfig="@xml/network_security_config">

Android常用的网络编程框架

  • OkHttp(已经代替了HttpURLConnection)
  • 配置
    • OkHttp支持Android2.3及其以上版本,java要求JDK1.7以上
    • 添加依赖:implementation 'com.squareup.okhttp3:okhttp:4.2.1'
    • 添加权限: <uses-permission android:name="android.permission.INTERNET" />

OkHttp开发基本思路

  • OkHttp的每次网络请求是一个Request,提供Request必要的参数url、header等,基于Request构造处一个call对象,再调用它的execute()方法,就能取得web Server回复的数据
  • 如果同步调用,需要在独立的线程中运行,使用异步调用,则采用回调的方式执行,在内部封装了一个请求队列
  • 基本步骤
    • 新建一个OkHttpClient对象
    • 通过Request.Builder对象新建一个Request对象
    • 通过Request对象构造Call对象,调用enqueue()以异步的方式将call加入调度堆列,等待request执行完成
    • 通过Call对象的Callback对象返回执行结果

GET请求

 private void get(String url){
        Request request=new Request.Builder().url(url)
               //设置和添加Header
                .header("user-agent",
                        "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36" +
                                "(KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36")
                .addHeader("Accept","application/json")
                .get()
                .method("GET",null)
                .build();

        //发送请求,并处理回调
        OkHttpClient client=HttpsUtil.handleSSLHandshakeByOkHttp();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {

            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if(response.isSuccessful()){
                    //获得响应主体的json字符串
                    String json=response.body().string();
                    //使用FastJson库解析json字符串
                    final Ip ip= JSON.parseObject(json,Ip.class);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //根据返回的code判断过去是否成功
                            if(ip.getCode()!=0){
                                tvResult.setText("未获得数据");

                            }
                            else {
                                //解析数据
                                IpData data=ip.getData();
                                //显示出来的只是放进去的值,别的那么多数据,显示不出来
                                tvResult.setText(data.getIp()+","+data.getArea());
                            }
                        }
                    });
                }
            }
        });
    }

Http Header的读写

  • 当写到请求头的时候,使用header(name,value)可以设置唯一的name、value.如果已经优质,旧的将被移除,然后添加新的
  • 使用addHeader(name、value)可以添加多值(添加,不移除已有的)

post异步请求

  • 通过RequestBody构建请求数据
        FormBody.Builder builder=new FormBody.Builder();
        for (String key:params.keySet()){
        //构建要post到Server的数据
            builder.add(key,params.get(key));
        }
        return builder.build();
    }

post异步请求JSON数据

 public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown;charset=utf-8");
 private void post(String url,Map<String,String> params){
        RequestBody body=setRequestBody(params);
        Request request=new Request.Builder().url(url).post(body)

post方式提交Multipart文件

 public static MediaType MEDIA_TYPE_PNG=MediaType.parse("img/png");
    private void uploadImage(String url,String fileName){
        //1.创建请求主体RequestBody
        RequestBody fileBody=RequestBody.create(new File(fileName),MEDIA_TYPE_PNG);
        RequestBody body=new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("title","头像")
                .addFormDataPart("file",fileName,fileBody)
                .build();
        //2.创建请求
        Request request=new Request.Builder()
                .url(url)
                .post(body)
                .build();

Post异步下载文件

 @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if(response.isSuccessful()){
                    //1.获取下载文件的后缀名
                    String ext=url.substring(url.lastIndexOf(".")+1);
                    //2.根据当前时间创建文件名,避免重名冲突
                    final String fileName=System.currentTimeMillis()+"."+ext;
                    //3.获得响应字体的字节流
                    InputStream is=response.body().byteStream();
                    //4.将文件写入path目录
                    writeFile(is,path,fileName);
                    //5.在界面上给出提示信息
                    tvResult.post(new Runnable() {
                        @Override
                        public void run() {
                            tvResult.setText(fileName+"下载成功,存放在"+path);
                        }
                    });
                }

图片加载框架Glide

  • 添加依赖:
   implementation 'com.github.bumptech.glide:glide:4.10.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
    //https图片处理
  implementation 'com.github.bumptech.glide:okhttp3-integration:4.10.0'
  • 添加网络权限
    <uses-permission android:name="android.permission.INTERNET" />
  • 使用
    Glide.with(this).load("http://goo.gl/gegYUd"),into (imgeView);

Glide 加载https图片

 public static OkHttpClient handleSSLHandshakeByOkHttp() {
        X509TrustManager trustManager = (X509TrustManager) getTrustManager()[0];

        return new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                //支持HTTPS请求,跳过证书验证
                .sslSocketFactory(getSSLSocketFactory(), trustManager)
                .hostnameVerifier(new TrustAllHostnameVerifier())
                .build();
    }
  • 创建继承AppGlideModule类的自定义类,重写registerComponents()方法


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,501评论 6 544
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,673评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,610评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,939评论 1 318
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,668评论 6 412
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,004评论 1 329
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,001评论 3 449
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,173评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,705评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,426评论 3 359
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,656评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,139评论 5 364
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,833评论 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,247评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,580评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,371评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,621评论 2 380

推荐阅读更多精彩内容

  • 前言 在Android开发中,网络请求是非常常用的,因此我们需要对Android开发的网络请求有大致的了解;包括应...
    weiinter105阅读 1,846评论 0 0
  • iOS网络编程读书笔记 Facade Tester客户端门面模式的实例(被动版本化) 被动版本化,所以硬编码URL...
    melouverrr阅读 1,619评论 3 7
  • OSI七层模型 OSI七层协议模型主要是: 应用层(Application) 表示层(Presentation) ...
    门心叼龙阅读 309评论 0 0
  • 我曾有一只闺蜜,暂且唤她米米吧。 【一】 我跟她大一相识,那时我俩同在一个社团,社团每个星期开次例会,我们都是那种...
    皎夜阅读 557评论 0 4
  • 结束了十几天的假期,返回上海上班。经历了大半天的折腾,到达上海是晚上十一点,下了车,拖着行李箱上了开往住处的地铁。...
    li李琳阅读 227评论 2 1