一:日期问题
在实际的android开发中,经常会遇到对日期的处理,比如当需求需要显示的是某月某日星期几这样的textview文本时,我们可以通过系统提供的api来很容易解决:
DateFormat longFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
2016年5月30日 星期一 中国标准时间00:00:00 华为
2016年5月30日星期一 中国标准时间上午12:00:00 小米
但是通过该方法拿到的日期华为和其他手机不同,最开始我是通过截取的方式,截取小米,三星,oppo都没问题,显示的是“5月30日星期一”。于是app就上线了,悲催的是,这个截取竟然在华为上面发生了崩溃。华为手机在星期的前面多了一个空格。
二:TextView 去除多个连续空格
有这样一个需求,在文章列表的页面,显示标题以及内容,但是内容只显示两行。那么当文章的内容开头如果出现大量空格符号的话,就会显示出来两行空白,这样用户体验并不好。我们可以手动将多个空白符号替换。
String s="怎么 才能 去掉 多个 空格";
s=s.replaceAll("\\s{1,}"," ");
//s就会变成"怎么 才能 去掉 多个 空格"
三:URLDecoder.decode(url,"UTF-8")中的url中包含加号问题
在解码的url内容中,如果包含了"+"号,那么在decode()方法的源码中,就会把"+"号直接替换成空格。可以在url的提交中,将"+"号替换成"2b%"
四:ETag在缓存当中的使用
在http协议中,当ETag字符串未发生改变时,通常会返回304告诉请求者,服务器数据未改变。
在典型用法中,当一个URL被请求,Web服务器会返回资源和其相应的ETag值,它会被放置在HTTP的“ETag”字段中:
ETag: "686897696a7c876b7e"
然后,客户端可以决定是否缓存这个资源和它的ETag。以后,如果客户端想再次请求相同的URL,将会发送一个包含已保存的ETag和“If-None-Match”字段的请求。
If-None-Match: "686897696a7c876b7e"
其中If-None-Match放在header中作为字段发送就可以了。
客户端请求之后,服务器可能会比较客户端的ETag和当前版本资源的ETag。如果ETag值匹配,这就意味着资源没有改变,服务器便会发送回一个极短的响应,包含HTTP “304 未修改”的状态。304状态告诉客户端,它的缓存版本是最新的,并应该使用它。
五:toast多次弹出怎么解决
public static void showToast(Context context,
String content) {
if (toast == null) {
toast = Toast.makeText(context,
content,
Toast.LENGTH_SHORT);
} else {
toast.setText(content);
}
toast.show();
}
这样就可以了,避免了多次弹出toast,哪怕多次触发这个方法,也只会占用一个toast的时间。
六:onCreate 和 onRestoreInstanceState 二者在恢复数据时的区别
restore 是恢复的意思。以前片面理解为再存储,导致对这个方法理解失误。在旋转屏幕,导致资源重新加载,系统内存不足,kill 掉优先级较低的activity(这里的优先级是指,与用户交互的activity优先级最高,可见但不能交互的优先级次之,不可见的activity优先级最低),都会触发onSavedInstanceState
onRestoreInstanceState从时序上看,被调用是在activity重建之后的调用onStart之后,在onResume之前。
Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation.
So for best practice, lay out your view hierarchy in onCreate and restore the previous state in onRestoreInstanceState. If you do that, anyone who subclasses your Activity can chose to override your onRestoreInstanceState to augment or replace your restore state logic. This is a long way of saying onRestoreInstanceState serves as a template method.
从上面的文档中,我们可以看出,best practice 是在onCreate中布局view,在onRestoreInstanceState中保存状态。这样是方便在继承中可以方便增加或者替代onRestoreInstanceState 中的恢复状态逻辑。
二者还有一点小小的区别,就是在onCreate中使用savedInstanceState时,需要判断是否null,而在onRestoreInstanceState中,则无需判断savedInstanceState是否为null。因为onRestoreInstanceState被调用,就意味着savedInstanceState不为null。
引申
1:我们也可以通过
android:screenOrientation="portrait"
来指定activity只能处在横屏或者竖屏。
2:我们也可以通过
android:configChanges="orientation|screenSize|keyboardHidden"
指定activity在旋转屏幕时,不重建activity,而是只调用onConfigurationChanged(Configuration newConfig)这个方法。
七:在使用CMake编译原生库的时候,SHARED的含义。
在android studio2.2之后,我们在创建一个带有c++的原生项目时,系统会默认使用Cmake编译,届时也会自动生成一个CMakeLists.txt的文件,其内容如下:
cmake_minimum_required(VERSION 3.4.1)
add_library(native-lib SHARED src/main/cpp/native-lib.cpp )
find_library( log-lib log )
target_link_libraries(native-lib ${log-lib} )
其中就有这样一个 SHARED。其实我们在编译c++库的时候,可以生成两种库,一种是静态库STATIC,主要以.lib或者.a 后缀组成。一种是动态库SHARED,主要由.so或者.dll后缀组成。
静态库特点:
- 静态库对函数库的链接是放在编译时期完成的。 程序在运行时与函数库再无瓜葛,移植方便。
- 浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
动态库特点:
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。
动态库把对一些库函数的链接载入推迟到程序运行的时期。
可以实现进程之间的资源共享。(因此动态库也称为共享库)
将一些程序升级变得简单。增量更新
甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。
八:android库使用注意事项
- 库中所有资源默认为public。如果需要将资源私有化,必须至少将一个属性定义为public。定义public的位置在res/values/public.xml文件中:
<resources>
<public name="mylib_app_name" type="string"/>
<public name="mylib_public_string" type="string"/>
</resources>
- 工具不支持在库模块中使用原始资源文件(保存在 assets/ 目录中)。应用使用的任何原始资源都必须存储在应用模块自身的 assets/ 目录中。
九:保持屏幕常量 android:keepScreenOn="true"
当我们在某个activity的布局中将该view的属性中添加一个 android:keepScreenOn="true"时,那么这个activity就会一直亮起,直到手动关闭。
android:keepScreenOn="true"
我们也可以通过setKeepScreenOn(boolean keepScreenOn),通过代码动态设置这一属性。
十:LinearLayout 自带添加删除动画开启
最近看代码的时候,猛然发现,原来LinearLayour自带添加删除动画
android:animateLayoutChanges="true"
就是上面这行代码,能够瞬间让你addView()变得高大上起来。