子路宇晟的博客

love and peace


  • Home

  • Archives

Android SSL pinning

Posted on 2020-05-02 | Edited on 2020-05-10 | Comments: | Views:

我们可以借助Charles通过手机很方便的查看App API数据,但有时候我们API可能会有些敏感数据不太愿意让别人轻易看到;你设计的很精妙(赶工)的API也不太乐意光溜溜暴露给陌生人。有很多方法,这里就说一种比较低成本的方式:CertificatePinner

用法

只要在okhttp Client 里添加一下:

1
2
3
4
5
6
7
8
9
10
    private val jwtHttpClient = OkHttpClient.Builder()
.certificatePinner(
CertificatePinner.Builder().add(
"api.xxxlabs.io",
// "sha256/js3miE89h7ESW6Maw/yxPXAW3n9XzJBP4c------W4"
// "sha256/EzNouO9uXc9NwcZ1652EcCvsv1LKqeIwyhR------wg"
"sha256/++MBgDH5WGvL9Bcn5Be30cRcL0f5O+NyoXuWt-----1aI"
).build()
)
.addInterceptor { chain -> ...}

这个字段可以是后端通过SSL证书的pub key sha256算出来的。也可以随便填一个,直接请求下,错误日志会把正确的Key打印出来,直接贴上去,即可。

·

参考

https://medium.com/@develodroid/android-ssl-pinning-using-okhttp-ca1239065616
https://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html

Read more »

Android packet capture

Posted on 2020-04-19 | Edited on 2020-05-10 | Comments: | Views:

我们在调试时需要分析API请求的返回数据用来定位问题,这时候会需要使用抓包工具。

应用内抓包

App自己把收到的Response打印出来,方便我们检查数据或者用来创建Data Class,可以通过给okhttp Client设置拦截器来把数据打印出来。

1
2
3
4
5
// stethoVersion = '1.5.1'
// okhttpVersion = '3.14.2'
api "com.facebook.stetho:stetho-okhttp3:$rootProject.stethoVersion"
api "com.facebook.stetho:stetho:$rootProject.stethoVersion"
api "com.squareup.okhttp3:logging-interceptor:$rootProject.okhttpVersion"

配置代码

Stetho是Facebook开源的一个Android app调试工具,可以在Chrome上查看App网络数据和应用数据:

用logging-interceptor可以直接在logcat:

应用外抓HTTP/HTTPS

应用内抓包都需要依赖ADB,如果你是测试人员没有开发调试环境,或者运行的是正式版本App,又或者你想研究一下竞对App,这时你可能就会需要更强大的抓包工具了。Charles(青花瓷)和Fiddler是这类工具的代表,用法也比较类似,这里就说下Charles用法吧。

Read more »

Jetpack compose

Posted on 2020-04-12 | Edited on 2020-04-19 | Comments: | Views:

这是Google出品的现代化工具包用来构建Android UI。用它可以更快更简便的进行UI界面开发。这个工具包版本最新只有0.1.0-dev08,离稳定可用应该至少还有半年,所以心情放轻松,来认识一下它吧。

Android编写UI有哪些痛点?

  • 不方便,需要在xml里写布局文件,要精通各种Layout,比如ConstraintLayout会用了吗?
  • 历史包袱,10来个大版本的迭代,现在UI的祖先View类已经3w多行,而绝大部分的UI控件都继承于View。意味你写一个按钮或者一个TextView都会受这个祖先影响。继承了很多没有用到的特性和功能。
  • 性能开销,基类对象内存开销,解析xml的额外开销
  • 预览和Reload不方便,Android的Instant Run起作用的各种Android版本限制和Flutter毫秒级的hot reload完全不能比。
  • 不好测试,xml只能通过集成测试,如果是代码构建通过单元测试就可以覆盖了。

Jetpack Compose 的目标

Less code

用更少的代码做更多的事情,避免继承类的错误,因此代码简单易维护。众所周知,从维护的角度看,组合优于继承。

Intuitive

只需定义你的UI,Jetpack Compose就会处理其余的工作。 随着应用状态的变化,你的用户界面会自动更新

Accelerate Development

与所有现有代码兼容,因此你可以随时随地采用。 通过实时预览和完整的Android Studio工具链支持快速迭代

Read more »

2019

Posted on 2020-04-05 | Edited on 2020-04-14 | Comments: | Views:

今年是大开大合的一年,责任与担当让我成长

工作

离职

五月决定从老东家离职,这是一个艰难而笃定的抉择。随着公司业务转型,移动端已渐渐不再是核心诉求,而公司现状也看不出来能把新业务做到行业头部地位。作为一个技术Leader会有忐忑,Coding的时间少了手容易生,业务不起色,小伙伴们的绩效也很难上去。加上宝宝的到来,意识到自己还是应该再去搏一搏!

新工作

从0开始写了一个类似米家的智能家居App,有以下收获:

  • 拓宽视野,后端Go是CTO现学现上的,良好的设计和测试覆盖使后端非常健壮,也让我意识到技术人员应该活到老学到老
  • NDK开发,需求上有许多和硬件交互的功能,所以上手了NDK开发,C语言真是不会过时的语言
  • 音视频编解码,FFmpeg,H264也算入了门
  • 更新了一些技能点:ConstraintLayout,ViewModel,LiveData,MQTT
  • App在google play 上架

这半年可能写了前两年的代码量,感觉即紧张又刺激!连续几天写1000+代码那是很充实的时光,缺点就是比较容易掉头发。

生活

生活就是经历一些事和人。

Read more »

Sentry android

Posted on 2020-02-28 | Edited on 2020-04-14 | Comments: | Views:

软件出Bug是不可避免的,但要有办法追踪这些Bug。这样才能不断迭代完善软件。Android app bug追踪我用过友盟,Bugly,Sentry。综合对比,Sentry具有接入更方便,UI简洁专业,可以私有化部署的优点。

集成

集成SDK依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Top-level build file 
// ADD JCENTER REPOSITORY
dependencies {
classpath 'io.sentry:sentry-android-gradle-plugin:1.7.33'
}
repositories {
jcenter()
}


// modules build files
// ADD COMPATIBILITY OPTIONS TO BE COMPATIBLE WITH JAVA 1.8
apply plugin: 'io.sentry.android.gradle'
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}


// ADD SENTRY ANDROID AS A DEPENDENCY
dependencies {
implementation "io.sentry:sentry-android:2.0.2"
}

链接SDK到Sentry(自动)

1
2
3
<application>
<meta-data android:name="io.sentry.dsn" android:value="https://[email protected]/1704083" />
</application>

链接SDK到Sentry(手动)

1
2
3
4
5
6
7
8
// 一般在application里init
SentryAndroid.init(context) {
it.dsn = sentryUrl
it.environment = environment
it.release = releaseVersion
it.addInAppExclude("java.")
it.addInAppInclude("io.sentry")
}

小项目直接用自动配置就可以,手动配置可以控制dsn,并且在初始化时传一些自定义字段。

测试

Read more »

Testing in android

Posted on 2020-02-16 | Edited on 2020-04-14 | Comments: | Views:

给app编写测试用例,很多时候我们只是听说过,没写的原因有很多:

  • 没时间,业务功能都写不完
  • 没心思,Bug都还没修完
  • 不知测试用例有啥用
  • 不会写App测试用例
  • 领导没这个要求

这篇文章我会从测试用例是什么,为什么要写,怎么写来描述一下这些概念

什么是测试用例

测试用例也是代码,业务代码用来实现功能需求;而测试用例用来验证业务代码逻辑是否正确,边缘情况是否考虑周全,新的代码有没有引入Bug,已修复的Bug会不会因为新加的逻辑又复现了。

一般写测试会遵循Given, When, Then三步

  • Given: 创建测试需要的环境和状态,以及要测的任务列表.
  • When: 运行测试用例,这会运行需要被覆盖的代码.
  • Then: 和预期结果比对测试的返回,输出是通过还是失败.

测试用例的好处

Google提倡写测试用例,认为这应该是应用开发过程中必要的一部分。通过持续对应用运行测试,可以在发布应用之前验证其正确性、功能行为和易用性。

测试还会为带来以下好处:

Read more »

λ

Posted on 2019-11-01 | Edited on 2020-04-05 | Comments: | Views:

关于λ经常会听到λ演算和λ表达式这两名词,其实分别对应的是理论和应用两个维度。它们的关系可以类比于质能方程和原子弹。

λ演算

数学家阿隆佐-邱奇在20世纪30年代提出λ演算,作为数学基础研究的一部分。那个年代,数学界有个领袖,叫希尔伯特(一人之力将葛根廷大学建设为当时数的世界中心)。他提出将数学定理机械化,这样机器就可以通过形式语言推理出大量新定理(AI的味道?)。比他小几岁的图灵和邱奇都受到他这一思潮影响,并从不同的角度解决了这同一个问题。理论上,图灵机和λ演算,都可以模拟出我们今天所有的程序。

λ演算是一种形式系统(formal system),什么是形式系统呢?大家知道,数学语言是是可以脱离现实而存在的——大家把数学想成了一种符号游戏,脱离生活常识,从公理开始,进行大量的推导和证明——最终产生一个系统,里面有公理、定理、推论、猜想…上述这种自成体系,有公理又有推理证明方法的体系,称为形式系统。而形式系统需要语言去描绘,这种语言就是形式语言(formal language)。邱奇希望用λ演算来表达有关数学的一切,比如用一系列函数来表达自然数,符号,定理等。

本质上图灵机和λ演算是做同一件事情,也是可以互相转换的。

Lambda表达式

区别于λ演算中的λ表达式,编程中提到的Lambda表达式,一般就指一个匿名函数。为什么要用匿名函数,对于一个只用一次的函数,匿名使用当然更简洁方便。eg,给view一个点击事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
// java 8以前
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("click","-----");
}
});

// java 8用上Lambda的匿名函数
view.setOnClickListener(v -> Log.d("click","-----"));

// kotlin 版本
view.setOnClickListener { Log.d("click", "-----") }

那种写法更好一目了然,对吧。

所以在编程中使用Lambda表达式,可以让代码更符合直觉,写法清晰简练自然也带来更好的维护性。

Read more »

ClipToPadding & ClipChildren

Posted on 2019-10-19 | Edited on 2020-04-05 | Comments: | Views:

clipToPadding和clipChidren可以用来改变子视图的样式和行为

clipToPadding

字面意思是根据padding来裁剪视图,如padding_top = 20dp,那么子视图从上边距20dp开始绘制。既然是padding相关,所以一般用在viewGroup里,尤其是可以滚动的recyclerView,scrollView等控制上下边距。

1,clipToPadding=”true”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="400dp"
android:paddingTop="16dp"
android:clipToPadding="true"
android:background="@android:color/holo_blue_bright"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<Button
android:layout_width="match_parent"
android:layout_height="300dp"
android:text="button1"/>

<Button
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginTop="16dp"
android:text="button2"/>
</LinearLayout>

</ScrollView>

s

2,clipToPadding=”false”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="400dp"
android:paddingTop="16dp"
android:clipToPadding="false"
android:background="@android:color/holo_blue_bright"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<Button
android:layout_width="match_parent"
android:layout_height="300dp"
android:text="button1"/>

<Button
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginTop="16dp"
android:text="button2"/>
</LinearLayout>

</ScrollView>

s

clipChildren

Read more »

HashMap

Posted on 2019-09-16 | Edited on 2020-04-06 | Comments: | Views:

HashMap在Java里是很常用的一种数据结构,今天来白话一下

定义

HashMap 在Java中用来存放Key-Value,作用类比Python的dictionary和Javascript的object。它的特点就是块,查询和插入的复杂度都是O(1),内存开销也是稳定的。

用法

1
2
3
Map map = new HashMap<String, Activity>(4);
map.put("a", AnimationActivity());
map.get("a");

哈希和散列

这俩个词是啥关系?emmmr,好比西红柿和番茄吧。一个是hash的音译一个是意译。所以听到什么哈希表和散列表不要奇怪,它们都在说同一个东西,哈希表叫法的最早来源可能是hashmap里的 Node<K,V>[] table.没错哈希表是一个数组,这是它curd操作复杂度O(1)的基石。

取模&取余

正数没有差别,区别在于负数向0取余,远离0取模

1
2
3
4
7 mod 4 = 3(商 = 1 或 2,1<2,取商=1)
-7 mod 4 = 1(商 = -1 或 -2,-2<-1,取商=-2)
7 mod -4 = -1(商 = -1或-2,-2<-1,取商=-2)
-7 mod -4 = -3(商 = 1或2,1<2,取商=1)
Read more »

ConstraintLayout IN Jetpack

Posted on 2019-09-02 | Edited on 2020-04-06 | Comments: | Views:

曾经Android布局就一把梭,RelativeLayout+LinearLayout,直到用ConstraintLayout写了几个页面后发现是真的香,现在任何布局第一选择都是它。

ConstraintLayout是什么?

  • 它属于Android JetPack,当前版本implementation 'com.android.support.constraint:constraint-layout:1.1.3'
  • 作用是可以减少视图布局层级,很复杂的页面一般也就是两个层级能搞定
  • 响应式布局代码更健壮,轻松适配不同分辨率
  • 更好的可视化操作,通过Android Studio的Layout Editor就可以实时拖动编辑并预览布局效果

基本用法

问:布局基本三要素是什么?

答:位置,对齐,大小。

1,位置,View放在哪里

ConstraintLayout的做法和RelativeLayout是差不多的,实际使用起来Constraint Layout的字段语义更符合直觉。

Relative Layout Constraint Layout
垂直居中 android:layout_centerVertical=”true” app:layout_constraintBottom_toBottomOf=”parent” app:layout_constraintTop_toTopOf=”parent”
居下 android:layout_below=”@id/view” app:layout_constraintTop_toBottomOf=”@id/view”
居右 android:layout_toEndOf=”@id/view” app:layout_constraintStart_toEndOf=”@id/view”

2,对齐,整整齐齐还是错落有致,当然是都要

Read more »
12…4<i class="fa fa-angle-right" aria-label="Next page"></i>
子路宇晟

子路宇晟

二次元爱好者,非专业视觉体验师

32 posts
9 tags
GitHub E-Mail
© 2020 子路宇晟
Powered by Hexo v4.2.0
|
Theme – NexT.Gemini v6.5.0