最近一直在面试Android(从广州开始决定转行,到今天也有两个月了),与以往在广州和普通的技术岗面试不同,这次进入到的初创公司的面试题是使用SDK实现获得本机号码进行免密登录的功能实现。
涉及到了很多新的知识点,也证明了自己之前做独立产品时在Bug上面花费的时间较长,以及了解到互联网技术岗面试,不仅是做笔试题、问理论,还实现一个真正的业务需求。
同时反映出自己自学的时候仅是项目与兴趣驱动,而忽略了整体的学习大纲,有时间还得做一下自己的全部自学历程,以飨读者。
本篇文章复盘今日入门闪验SDK过程,从技术与项目实践而不失面试的心理进行解读以及做"第三方库"类型的面试题,需要注意的地方。
由于时间原因,将原本计划的全部代码缩减到想展示需说明问题的代码以及心理动态,所以本文不仅仅说技术,同时也说自己做面试题时的心理,也非常欢迎有使用过闪验SDK的朋友甚至是官方在本文下方留言评论。
知识点
Android开发
SDK引入:Android配置文件权限增加、不同运营商授权页面Activity注册
小知识点:配置BuildConfig方法(注册APP_ID、APP_KEY)
Java接口和回调、参数传递
混淆配置
测试:软件闪退、栈跟踪、异常捕获(Demo)
发布:realase、debug、包名和包签名、Keystore方法
能力
SDK文档阅读(能力)、对照Demo能力
开始
页面设计
面试官简述了需求后,开始写最熟悉的页面。
由于看到面试官手机里的Demo,将授权页从RelativeLayout更改到了ConstraintLayout,可能这也是一个考点吧——了解对布局的熟练程度,又或许完全是我想多了并且以实现功能为主,再次更改到了RelativeLayout。
自己总共设计了首页(非闪屏)以及授权页,但后续发现授权页则是SDK自带但可定制,参照Demo的是几乎复杂了一倍:
模式选择页面、产品介绍页面、加载页面、免密登录页面(授权页面)、沉浸模式、结果页面,画删除线的,是我没设计的页面。
撰写本文时才得知面试官的Demo就是沉浸式页面,其实是SDK自带的。
参照文档的方法
闪验的SDK文档刚开始读,觉得有些难。
方法原型与示例代码
仅根据方法原型写,当然不能直接运用到代码中。而示例代码,则在程序中可以完全使用,可能是碰运气,也有可能是从demo中提取出来的代码,是不是和我之前做的地图的伪代码[1]一样,也不得而知了。
并没有类文档
在自己之前引入百度地图SDK时,百度有一份类的网站专门用于解释相应的类以及作用,似乎是产品形态和服务类别的原因,或者短信SDK对于开发者来说过于简单或者人手等原因,仅仅有一份使用文档。
百度的类文档地址:百度地图API->Android SDK->类参考
所以自己就在这里自己随手写了。
有了方法,但返回什么?
在示例Demo中,作者使用了Dialog以及机型来进行返回,开发间隙询问了做后台的面试官[2],得知不需要获得机型,我也可以不显示。
后续我也使用了Toast[3]进行代码的返回,否则我的代码中便是只有示例代码的方法,没有返回值,不便于获得错误代码,更不便于展现我对Android以及Java方法、接口与回调层面的理解。
依赖
第三方库的形式,除了在app目录下的build.gradle中
dependencies { implementation xxx
之外,闪验和百度/高德地图一样,需创建libs文件夹,以及根据项目需要拷贝jnilibs中的so包。
配置所需权限与所需权限
AndroidMainfest.xml
除规定的此处更新的权限外,实际测试中因为机型或自己未核实的原因,提示:得到移动状态出错
故有提示错误,参照网站还需要核对缺失的权限[3:1]。
有时文档写的可能不全面,此时作为demo,就可以(或者说必须)增加一些不是那么必要的权限确保程序可以运行起来,当然在真正的产品中,这一点必定会被广大用户所厌恶,或者使用AppOps进行控制。
SDK问题
这里在设置AndroidManifest文件时,出现了SDK的问题。
本文中所有出现的问题和参考链接,请查看文末"参考"段落的说明。
运行时权限
因为闪验SDK的获取本机号码需要权限多次进行读写,此时回想起了《第一行代码》中的if else运行时权限章节,打开了自己的笔记。
不过在这里由于需求和时间原因,根据Demo,选择一样的库以及一样的写法[4]:
AndPermission.with(this)
.permission(permissions)
.onGranted(new Action() {
@Override
public void onAction(List<String> permissions) {
OneKeyLoginManager.getInstance().getPhoneInfo(new GetPhoneInfoListener() {
@Override
public void getPhoneInfoStatus(int code, String result) {
Toast.makeText(MainActivity.this,"code=" + code + "result=" + result,Toast.LENGTH_SHORT).show();
}
});
}
})
.onDenied(new Action() {
@Override
public void onAction(List<String> permissions) {
//此处填写用户拒绝逻辑
}
})
.start(); //开始向用户授权
可能是对知识点掌握的不熟练,可能是在自己的项目中,权限这块也是觉得参照第一行代码写的很冗长,准备使用EasyPermisson进行封装但一直没开始的缘故,所以并没有使用第一行代码里的写法。
步骤
初始化
有过百度地图的经验,看到初始化就总想到百度地图的SDK初始化[5],总要在setContentView或者onCreate方法之前。由于两种服务类型不同,本文并不相比较。
闪验的初始化则是在onCreate() 方法中:
APP_ID与APP_KEY
Buildconfig
此处涉及到BuildConfig的更改,后得知需在build.gradle中增加buildConfigField
字段:
buildTypes {
release {
......
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField('String', 'EXAMPLE_MANE', '"......') //example
buildConfigField('String', 'APP_ID', '"*******"')
buildConfigField('String', 'APP_KEY', '"*******"')
}
debug {
......
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField('String', 'SERVER_URL', '"http://............./"')
buildConfigField('String', 'APP_ID', '"*******"') //闪验平台上申请的appid
buildConfigField('String', 'APP_KEY', '"*******"') //闪验平台上申请的appkey
}
之后同步,相应BuildConfig即会自动显示。
值得注意的是,ID与KEY这里需要写真实的,因为BuildConfig无法修改。
此处省略号内容在文末"包名、包签名校验"段提及:
minifyEnabled false
signingConfig signingConfigs.release
zipAlignEnabled true
预取号
此处需要网络请求,准备第二天看看retrofit2的源码。
OneKeyLoginManager.getInstance().getPhoneInfo(new GetPhoneInfoListener() { @Override
public void getPhoneInfoStatus(int code, String result) {
} });
授权页
拉起
参考Demo,拉起可选从产品宣传页面开始拉起或模式选择页面(可选)。
定制
关于授权页的定制,自己觉得有一个"模板",即定制的授权页面:ConfigUtils。
OneKeyLoginManager.getInstance().setAuthThemeConfig(ConfigUtils.getUiConfig(getApplicationContext())); OneKeyLoginManager.getInstance().setAuthThemeConfig(ConfigUtils.getCJSConfig(getApplicationContext()));
若时间足够,当然会在这里定制一番。此为免密登录界面的请求权限代码。
之前在这里设计了个页面,现在看真的是多余的。
混淆
算是新接触的知识点,即使之前在群里很多人都在讨论反编译以及AAPT相关技术。[6]
- 将build.gradle的minifyEnabled设置为true。
android {
...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
- proguard-rules.pro粘贴混淆。
小总结
总体得知,闪验的操作以及方法主要是一键登录管理类进行的方法:
OneKeyLoginManager.getInstance().set...
测试
闪退
应用白屏与闪退问题,通常根据栈跟踪进行查看,错误码进行Google。
包名、包签名校验
包名、包签名校验不一致的问题于今天下午花费较长的时间,算是第一天的遗留问题。
由于之前仅仅是在百度地图中接触过Keystore,所以有些印象。
不通过
包名校验不通过,仅仅是需要将build.gradle处applicationID处修改一下即可(此处有待辩证)。
包签名校验不通过,则需要singleconfig。
SingleConfig
可能有两种方法
- 根据Demo与链接,build.gradle增加了如下字段,但相应字段也许需要改成相应文件地址以及名称。
signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
- 根据Demo,相应路径写在了gradle.praperties中,build.gradle为上述代码。
一些发现
阅读文档
在阅读文档的时候于是发现(准确的说是在写本次复盘文章的时候)看到自己在上午查了"闪验"aar包名的keywords,以此可以引申出,撰写文档的职业文档工程师,更需要考虑到每个人的阅读水平以及阅读理解能力:
aar包名:aar的包名,还是aar之后增加包应用的名称?
这可能是该文档工程师值得思考的,也是即将从事文档工程师一职的工程师们思考的。
学习Demo
有的时候不知道有什么库好用,可以通过阅读开源软件中可以发现,更有甚者还可以通过SDK的Demo进行发现。
正是从闪验SDK的Demo中,我了解到了yanzhenjie/AndPermission,以及
平台
网站的工具以及人为地利用
StarkOverFlow>掘金>CSDN>简书 >知乎
以下链接仅仅是关于闪验的简介,而非编程开发相关:
知乎:一键登录闪验配置说明
从学习第三方SDK行为中查看人类行为
这个话题扯的有点远了,也从侧面反映出人类为了探究真相而做出的不懈努力。
从一个文档中不清晰的point,到打开官方网站,再到搜索引擎,再到分发出的个人博客以及各个知识点的详细不同说明。
和上述话题一样,人们可以在知乎和掘金上仅仅宣传自己的产品,而不发相关编程内容,即使是"编程界的标题党"。
参考
文中提到的所有错误,都将会集中在我制作的Android报错集合中,
相应知识点以及参考链接也会尽快增加在我的Android开发学习与Android开发实践中。
之前撰写的关于SDK的博客文章分类目录:Android SDK
若我做的这几个笔记对你有帮助,欢迎宣传以及给我在文末给稻谷,这里可以打赏给我。
后记
如果是之前,我还会进行截图制作,现在看来时间很紧要,毕竟实现了功能,才可以进入公司。
今天才这家公司面试的第一天。
上述文中实现了我的大部分复盘以及我的心里活动,剩下的忘记的,也只能先不管了,毕竟自己的之前工作中的笔记都还没有添加进去。
有时间还是多敲代码吧。复盘大致大致就够了。
我很讨厌伪代码,说白了就是不能直接用做业务。社会什么都是假的已经够荒唐了。 ↩︎
这个面试官还比我小1岁,真想不到。 ↩︎
此处原先以为是文档的权限不全,撰写本文时发现还是自己的问题。相关问题错误合集链接:java.lang.SecurityException-C ↩︎ ↩︎
所以文中减少了相应的截图拼凑、注释对比等截图,例如"运行时权限"中和"库一样的写法"。 ↩︎
百度地图的初始化:在SDK各功能组件使用之前都需要调用“SDKInitializer.initialize(getApplicationContext())” ↩︎
不禁想到很久之前自己经常下载AndroidApp之后改名成Zip,在里面寻宝,大概是高中时候的事了。 ↩︎