实习周记3(sdk接入、Retrofit)

文章目录

    • 本周知识清单
    • 1. SDK接入
      • 1.1 Android library文件库
      • 1.2 自定义Maven仓库
      • 1.3 引入依赖后的工作流程
    • 2 Retrofit网络请求框架
      • 2.1 配置gradle,添加权限
      • 2.2 编写网络请求接口
      • 2.3 创建Retrofit
    • 3.一周问题汇总
      • 3.1 打包apk时65536错误,引入的包达到Android应用构建架构的极限
      • 3.2 更改包名?no,只需要更改build.gradle的applicationId
      • 3.3 打包jar包里面的类可以调用,但在运行过程中nofound?
      • 3.4 keyStore密码被看到了?我来教你如何隐藏自己的keystore密码
      • 3.5 xml文件无法预览?你依赖的com.android.support和你的BuildTools版本不兼容惹的祸
    • 4. 一周小结
    • 参考资料

本周知识清单

  • 关于SDK接入
  • Retrofit网络请求框架
  • 问题汇总
  • 参考资料
  • 一周小结

1. SDK接入

如果我想接入一个library到我的项目中,我只需要在build.gradle中添加

implementation 'com.xxxx.xxx:xxx:0.1.1'

那么Android Studio是从哪里获取这个库的?

1.1 Android library文件库

在Android中有两个标准Android library文件服务器:jcenter和Maven Central

  • jcenter:它是由bintray.com维护的Maven仓库,仓库地址

在project的build.gradle中定义仓库

allprojects {
    repositories {
        jcenter()
    }
}
  • Maven Central:它由sonatype.org维护的Maven仓库,仓库地址
    在project的build.gradle中定义仓库
allprojects {
    repositories {
        mavenCentral()
    }
}

Maven Central的最大问题是对开发者不够友好。上传library异常困难。上传上去的开发者都是某种程度的极客。同时还因为诸如安全方面的其他原因,Android Studio团队决定把默认的仓库替换成jcenter。正如你看到的,一旦使用最新版本的Android Studio创建一个项目,jcenter()自动被定义,而不是mavenCentral()。

有许多将Maven Central替换成jcenter的理由,下面是几个主要的原因。

  • jcenter通过CDN发送library,开发者可以享受到更快的下载体验。

  • jcenter是全世界最大的Java仓库,因此在Maven Central 上有的,在jcenter上也极有可能有。换句话说jcenter是Maven Central的超集。

  • 上传library到仓库很简单,不需要像在 Maven Central上做很多复杂的事情。

  • 友好的用户界面

  • 如果你想把library上传到 Maven Central,你可以在bintray网站上直接点击一个按钮就能实现。

1.2 自定义Maven仓库

像我们公司的library,我们并不会将它放到公共仓库上面,而是放到我们自己的服务器上,这就涉及到自己定义特有的Maven仓库服务器。如果要使用的话就要定义仓库的url

repositories {
    maven {
        url 'https://xxx../xxx'
    }
}

然后在app的build.gradle里面获取相应的library

dependencies {
    implementation 'xxx.xx.xx:xxx:1.2.0'
}

1.3 引入依赖后的工作流程

library的字符串形式主要是3部分

xxxx.xx.xx:xxx:1.1.0

GROUP_ID:ARIFACT_ID:VERSION

GROUP_ID 通常是包名

ARTIFACT_ID是library的真实名称

VERSION

添加完依赖后,Gradle询问Maven仓库服务器该library是否存在,如果存在下载上面的jar和aar文件,然后gradle直接帮你配置好所有东西,非常方便。

2 Retrofit网络请求框架

上周学习了OkHttp的使用,这一周要学的同样是来自Square公司的Retrofit框架,它是基于
OkHttp实现的,运行时使用注解实现功能

2.1 配置gradle,添加权限

到https://github.com/square/retrofit查询最新版本,添加依赖。并且添加网络权限。
在Retorfit的使用中,它只能将Http的body反序列成ResponseBody类型,但你能添加其他库的依赖,转换成自己想要的类型。

  • Gson: com.squareup.retrofit2:converter-gson
  • Jackson: com.squareup.retrofit2:converter-jackson
  • Moshi: com.squareup.retrofit2:converter-moshi
  • Protobuf: com.squareup.retrofit2:converter-protobuf
  • Wire: com.squareup.retrofit2:converter-wire
  • Simple XML: com.squareup.retrofit2:converter-simplexml
  • Scalars (primitives, boxed, and String): - com.squareup.retrofit2:converter-scalars

在https://square.github.io/retrofit/有对这方面的介绍

2.2 编写网络请求接口

MySerivce.java

    @FormUrlEncoded
    @POST("api/update")
    Call<ResponseBean> update(@Header("token")String token,
        @Field("name")String name)/**
     * method:网络请求的方法(区分大小写)
     * path:网络请求地址路径
     * hasBody:是否有请求体
     */
    @HTTP(method = "GET", path = "blog/{id}", hasBody = false)
    Call<ResponseBody> getCall(@Path("id") int id);
    // {id} 表示是一个变量
    // method 的值 retrofit 不会做处理,所以要自行保证准确


如上就是完整的POST请求接口,里面有很多种形式的注解,主要分为三种

  • Http请求方法注解
注解名称 意义
@POST
@GET
@PUT
@DELETE
@HEAD
@PATCH
@OPTION
@HTTP 更多功能的扩展
  • 标记类注解
注解名称 意义
@FormUrlEncoded 请求体是一个Form表单
@Multipart 支持文件上传的Form表单
@Streaming 返回的数据以流的形式返回
  • 参数类注解
注解名称 意义
@Header 添加不固定值的Header
@Headers 添加请求头
@Body 非表单请求体
@Path URL缺省值
@Field 传入键值对
@FieldMap 传入键值对
@Part 用于表单字段;适用于有文件上传的情况
@PartMap 同上
@Query 数据接在URL上
@QueryMap 同上

2.3 创建Retrofit

String url = "http://www.xxx.com/V1/";
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(url)
    .addConverterFactory(GsonConverterFactory.create()) //类型转换
    .build();
MySerivce myServce = retrofit.create(MySerivce.class);
Call<ResponseBean> call = myServce.update(token,name);    
call.enqueue(new Callback<ResponseBean>() {
    @Override
    public void onResponse(Call<ResponseBean> call,
        Response<ResponseBean> Response) {

    }

    @Override
    public void onFailure(Call<ResponseBean> call, Throwable t) {

    }
});

写到这里就可以正常地访问网络了。可以看出,使用Retrofit后,无须为不同的请求去实例化不同的请求方法,很好地做到了代码的简化和复用。 下一周有时间再尝试一下RxJava+Retrofit的结合使用,想必这个组合这么火也是没有道理的。

3.一周问题汇总

3.1 打包apk时65536错误,引入的包达到Android应用构建架构的极限

trouble writing output:
Too many field references: 131000; max is 65536.
You may try using --multi-dex option.

64k引用限制
Android 应用 (APK) 文件包含 Dalvik Executable (DEX) 文件形式的可执行字节码文件,其中包含用来运行您的应用的已编译代码。Dalvik Executable 规范将可在单个 DEX 文件内可引用的方法总数限制在 65,536,其中包括 Android 框架方法、库方法以及您自己代码中的方法。在计算机科学领域内,术语千(简称 K)表示 1024(或 2^10)。由于 65,536 等于 64 X 1024,因此这一限制也称为“64K 引用限制”。

解决办法

  • 模块级 build.gradle 文件中将 multiDexEnabled 设置为 true
    defaultConfig {
        ...
        minSdkVersion 21 
        targetSdkVersion 25
        multiDexEnabled true
    }

3.2 更改包名?no,只需要更改build.gradle的applicationId

包名我们都知道是识别应用的一个标识,那一开始建立项目的时候随便起的包名到最后需要特定的包名的时候,我们是不是需要直接修改文件里面的文件结构呢?其实并不需要。
在AndroidManifest中对应的package是用于映射R资源的一个路径,也就是要和我们的文件结构一致。而作为识别应用标识的包名可以在build.gradle(Module:app)中的applicationId才是针对签名的一个包名。

3.3 打包jar包里面的类可以调用,但在运行过程中nofound?

这一题还是包名的问题,在打包的时候注意不要直接打包最里面的类,要保证包的完整性,否则在编译的时候根据包名找不到对应的类就抛出nofound的错误了

3.4 keyStore密码被看到了?我来教你如何隐藏自己的keystore密码

以前对apk进行签名的时候都是直接吧keystore的密码写到build.gradle中

signingConfigs {
    release {
        storeFile file('../xxxkey.jks')
        keyAlias 'xxxx'
        keyPassword 'xxxxx'
        storePassword 'xxxxxx'
    }
}

buildTypes {
    release {
        signingConfig signingConfigd.release
    }
}

上面这样写的话很容易被别人获取签名信息,接下来就是对它的改进了。

  • 第一步:在根目录中创建config文件夹,并把签名文件放进去
  • 第二步:在config文件夹中新建signing.properties文件,里面填写签名信息
STORE_FILE=../config/xxxxxxx.jks
STORE_PASSWORD=xxxxxx
KEY_ALIAS=xxxxxx
KEY_PASSWORD=xxxxxxxx
  • 第三步:在build.gradle中引用签名信息
    signingConfigs {
        release {
            File propFile = file('../config/signing.properties')
            if (propFile.exists()) {
                def Properties props = new Properties()
                props.load(new FileInputStream(propFile))
                if (props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&
                        props.containsKey('KEY_ALIAS') &&
                        props.containsKey('KEY_PASSWORD')) {
                    storeFile file(props['STORE_FILE'])
                    storePassword props['STORE_PASSWORD']
                    keyAlias props['KEY_ALIAS']
                    keyPassword props['KEY_PASSWORD']
                }
            }
        }
    }

    buildTypes {
        release {
            //签名
            signingConfig signingConfigs.release
        }
    }


3.5 xml文件无法预览?你依赖的com.android.support和你的BuildTools版本不兼容惹的祸

查看Project Struture -> app ->properties中的Build Tools Version,如显示27.0.3,然而你build.gradle中

implementation ‘com.android.support:appcompat-v7:28.0.2’

那可不行,应该改成appcompat-v7:27.+这样就Ok了。

4. 一周小结

这个星期研究新东西也算很多,大多数时间是在尝试的写一个Demo接上公司的sdk,碰到的问题也是挺多的。很大概率的原因还是对这方面的不熟悉吧。像海外的一些接口和平时自己接的一些接口还是有点区别的。通过一周的学习,开始对这方面有所了解,希望接下来的时间还是充满着干劲去迎接新知识。

参考资料

[1]如何使用Android Studio把自己的Android library分享到jCenter和Maven Central

你可能感兴趣的:(实习随笔)