如果我想接入一个library到我的项目中,我只需要在build.gradle中添加
implementation 'com.xxxx.xxx:xxx:0.1.1'
那么Android Studio是从哪里获取这个库的?
在Android中有两个标准Android library文件服务器:jcenter和Maven Central
在project的build.gradle中定义仓库
allprojects {
repositories {
jcenter()
}
}
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网站上直接点击一个按钮就能实现。
像我们公司的library,我们并不会将它放到公共仓库上面,而是放到我们自己的服务器上,这就涉及到自己定义特有的Maven仓库服务器。如果要使用的话就要定义仓库的url
repositories {
maven {
url 'https://xxx../xxx'
}
}
然后在app的build.gradle里面获取相应的library
dependencies {
implementation 'xxx.xx.xx:xxx:1.2.0'
}
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直接帮你配置好所有东西,非常方便。
上周学习了OkHttp的使用,这一周要学的同样是来自Square公司的Retrofit框架,它是基于
OkHttp实现的,运行时使用注解实现功能
到https://github.com/square/retrofit查询最新版本,添加依赖。并且添加网络权限。
在Retorfit的使用中,它只能将Http的body反序列成ResponseBody类型,但你能添加其他库的依赖,转换成自己想要的类型。
在https://square.github.io/retrofit/有对这方面的介绍
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请求接口,里面有很多种形式的注解,主要分为三种
注解名称 | 意义 |
---|---|
@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 | 同上 |
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的结合使用,想必这个组合这么火也是没有道理的。
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 引用限制”。
解决办法
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 25
multiDexEnabled true
}
包名我们都知道是识别应用的一个标识,那一开始建立项目的时候随便起的包名到最后需要特定的包名的时候,我们是不是需要直接修改文件里面的文件结构呢?其实并不需要。
在AndroidManifest中对应的package是用于映射R资源的一个路径,也就是要和我们的文件结构一致。而作为识别应用标识的包名可以在build.gradle(Module:app)中的applicationId才是针对签名的一个包名。
这一题还是包名的问题,在打包的时候注意不要直接打包最里面的类,要保证包的完整性,否则在编译的时候根据包名找不到对应的类就抛出nofound的错误了
以前对apk进行签名的时候都是直接吧keystore的密码写到build.gradle中
signingConfigs {
release {
storeFile file('../xxxkey.jks')
keyAlias 'xxxx'
keyPassword 'xxxxx'
storePassword 'xxxxxx'
}
}
buildTypes {
release {
signingConfig signingConfigd.release
}
}
上面这样写的话很容易被别人获取签名信息,接下来就是对它的改进了。
STORE_FILE=../config/xxxxxxx.jks
STORE_PASSWORD=xxxxxx
KEY_ALIAS=xxxxxx
KEY_PASSWORD=xxxxxxxx
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
}
}
查看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了。
这个星期研究新东西也算很多,大多数时间是在尝试的写一个Demo接上公司的sdk,碰到的问题也是挺多的。很大概率的原因还是对这方面的不熟悉吧。像海外的一些接口和平时自己接的一些接口还是有点区别的。通过一周的学习,开始对这方面有所了解,希望接下来的时间还是充满着干劲去迎接新知识。
[1]如何使用Android Studio把自己的Android library分享到jCenter和Maven Central