关于网络请求
在开发v1.3.2.1版本时,新增了这样一个需求:在某些节日,应用需要从服务端下载对应的启动页(Splash)图片并在特定的时间内显示。具体分到给我的任务是:如果有新图片需要下载的时候,下载下来保存到本地。由于我们的项目网络请求时采用async-http-client开源框架,这个功能自然也会继续沿用这个框架。如果单纯用这个框架进行开发,是很容易实现的,但是我们对于发起的请求加了签名校验这一步骤,不过由于此前版本做图片上传功能时已经做过类似的签名校验,这一部分也没有耽误什么时间。准备工作都做完之后,测试的时候,发现发起请求成功,服务端也有数据返回(这里使用Charles这个神器来进行数据抓包的),但是程序就是没法解析出数据。
下面写出来的是我思考和解决问题的步骤(最终感谢同事的指点):
重写
async-http-client中response handler的生命周期方法,目的是看在生命周期的哪个方法里出现问题(因为有数据返回,但是没有接收到,说明是在response handler处理的过程中出现的问题):onStartonSuccessonFailureonFinish
打出Log发现,
response handler里的onFailure方法执行了,并且statusCode是444- 正在我疑惑的时候,去问了后端的同事,他说我这边是不会返回
444这个码的,那这个码到底时哪里来的呢?他突然说到之前做过服务端返回数据后,再进行一次签名校验的功能,是不是那里的问题,一打断点,发现还真是这个问题:因为使用了自己封装过的response handler,在服务端返回数据后,又进行了一次签名校验,如果校验不通过,则直接调用onFailure并且返回444状态码 - 采用
async-http-client自带的JsonHttpResponseHandler作为response handler来对返回的json数据进行解析,问题解决
在解决这个问题的过程中,有以下几个关键节点(按开发步骤来):
- 发起的网络请求需不需要
签名校验 - 发起的请求服务端有没有接收到
- 服务端有没有数据返回
- 客户端接收数据时需不需要
签名校验 async-http-client的response handler有4个生命周期,可以用来判断接收的时候在哪里出现问题async-http-client的设置是:statusCode大于300时,直接报错(执行onFailure方法)
关于动画
自定义propertyName
在拍照完的照片预览页中有这样一句代码ObjectAnimator.ofFloat(mAnimatingImageView, "animationProgress", 0.0f, 1.0f),这里的propertyName是animationProgress,不是一般的alpha、rotation等,在查看了Android文档后(Animating with ObjectAnimator部分),发现如果要自定义propertyName,则类里必须要有set和get方法,在这句代码里对应的就是setAnimationProgress和getAnimationProgress方法。
透明度、缩放动画后
如果进行了透明度、缩放等动画后,没有相反的动画过程,下次再查看相关控件时,会呈现动画结束时的状态,此时如果alpha值是0,虽然控件设置了View.VISIBLE,但还是不可见的,要重新设置alpha值为1.0f。在v1.3.3.0开发过程中,相机页面显示照片数量的角标动画就是一个例子,进入预览页前有一个exit,最后的情况是让该控件alpha值为0,如果此时删除完全部照片,则回到相机页面时不会进入enter动画,这时会导致显示照片数量这个控件不可见,需要设置setAlpha(1.0f)、setScaleX(1.0f)、setScaleY(1.0f)让其正常显示。
View初始状态是“gone”
如果一个view的初始状态是gone,执行view.animate().alpha(1.0f).scaleX(1.0f).scaleY(1.0f).setDuration(200),发现动画不会出现,要使用view.startAnimation(AnimationUtils.loadAnimation(this, R.anim.xxx))动画才会有效果,具体原因还不清楚,等以后搞清楚了再回头来看。
是否一个Activity不可见了就一定会调用onStop?
在刚开始接触Android开发时,对于一个Activity的onPause和onStop方法什么时候调用,有以下两个认知:
- 当前Activity部分不可见时,
onPause会调用,例如一个dialog弹出 - 当前Activity完全不可见时,
onPause和onStop会分别调用,例如一个Activity跳转到下一个Activity的场景
在v1.3.2.1版本开发过程中,遇到一个情况,推倒了之前的认知,当Acitivity完全不可见时,onStop不一定调用,这个例外就是:如果跳转过去的Activity主题属性是透明(WindowIsTranslucent=true),则系统会认为一个类似于dialog的控件附在跳转之前的Activity上,此时虽然前一个Activity不可见了,但只会调用onPause,而不会调用onStop。
照片Exif信息丢失
在对拍照后的图片进行压缩保存时,发现保存后图片的Exif信息丢失,这样就会导致在有些机型上,拍照的图片被翻转了,这时候就算读取Exif信息也没用,因为翻转角度信息已经损坏。对于这种情况,有以下两个解决方案:
- 图片不压缩进行保存
- 如果图片一定要进行压缩保存,则在写入文件之前,读取Exif信息,如果有翻转角度信息的,对bitmap翻转之后再进行保存