Android动画 Interpolator

目录


  1. 简介
  2. 简单插值器
    1. AccelerateInterpolator 加速插值器
    2. DecelerateInterpolator 减速插值器
    3. AccelerateDecelerateInterpolator 加速减速插值器
    4. LinearInterpolator 线性插值器
    5. BounceInterpolator 弹跳插值器
    6. AnticipateInterpolator 回荡秋千插值器
    7. AnticipateOvershootInterpolator
    8. CycleInterpolator 正弦周期变化插值器
    9. OvershootInterpolator
  3. 参考链接

简介


interpolator可以翻译成插值器。

Android中interpolator最底层的接口如下:

TimeInterpolator是在Android API11时加入的,之前类就叫Interpolator

现在Interpolatro继承了它。


简单插值器


注意下面的图,对应你脑海中的插值的大小应该是斜率。

1.AccelerateInterpolator 加速插值器

源代码如下:

加速的快慢度由参数fractor决定。

当fractor值为1.0f时,动画加速轨迹相当于一条y=x^2的抛物线。如下图:
AccelerateInterpolator

fractor不为1时,轨迹曲线是y=x^(2*fractor)(0<x<=1)的曲线。

示例:当fractor为4时,插值器的加速轨迹曲线如下图:
AccelerateInterpolator_Fractor_4

如果你在使用AccelerateInterpolator时,想要那种一开始很慢,然后突然就很快的加速的动画效果的话。

就将fractor设置大点。

你可以到这里调试下你想要的抛物线效果:http://www.wolframalpha.com/input/?i=x%5E%282*3%29%280%3Cx%3C%3D1%29

Android提供的一个不同factor的加速插值器:

(1)accelerate_cubic, factor为1.5

2. DecelerateInterpolator 减速插值器

源代码如下:

根据getInterpolationa(float input);方法可以知道。

fractor为1.0f。它减速的轨迹曲线为1-(1-x)^2。如下图:

DecelerateInterpolator

fractor增大到4时,曲线轨迹如下图:
DecelerateInterpolator_Fractor_4

3. AccelerateDecelerateInterpolator 加速减速插值器

源代码如下:

根据getInterpolation()方法可以得出其变化曲线如下:
AccelerateDecelerateInterpolator

4. LinearInterpolator 线性插值器

这可是最简单的插值器:

5. BounceInterpolator 弹跳插值器

源代码如下:

根据getInterpolation()得到以下插值曲线图:
BounceInterpolator

6.AnticipateInterpolator 回荡秋千插值器

这个插值器的值变化过程,可以想像成荡秋千时的一个段过程。(此时秋千已经在比较上面的位置了,一放手就可以荡下来)。你开始用力推向更上面,然后秋千终将荡回下面。

tension值就好比推力的大小。

源代码如下:

根据getInterpolation()方法。
tension为默认值2.0f时,曲线图如下:
AnticipateInterpolator_Tension_2

tension值为4.0f时,曲线图如下:
AnticipateInterpolator_Tension_4

7. AnticipateOvershootInterpolator

源代码如下:

根据getInterpolation()方法,

可以得到当tension为默认值时,曲线图为:

AnticipateOvershootInterpolator

8. CycleInterpolator 正弦周期变化插值器

源代码:

当cycle时为1时,即变化一周时,曲线图如下:
CycleInterpolator

9. OvershootInterpolator

源代码:

tension为默认值2时,曲线图如下:
OvershootInterpolator_Tension_2

tension的值为4时,曲线图如下:
OvershootInterpolator_Tension_4

通过学习了解Android自带的这些Interpolator,我们可以很好的根据自己的使用场景使用这些Interpolator了。也可以很容易的写出我们自己的Interpolator


参考链接


android动画(一)Interpolator

查看Keystore文件的签名信息/检查APK文件中的签名信息

  • 查看 keystore文件的签名信息

  • 检查APK文件中的签名信息

解压出apk中META-INF目录下的CERT.RSA文件,然后用keytool即可查看签名信息:

  • 比对签名是否一致

验证APK的签名是不是我们给定的签名文件的签名。

1.解压出apk中META-INF目录下的CERT.RSA文件.

2.执行如下命令:

Windows:

Linux:

比较两者输出的MD5字符串,是否一致即可。

com.android.dex.DexIndexOverflowException

现象描述


注意,本文描述的方案,仅在Android Studio 1.5,Gradle插件版本1.3.1中测试成立!

同时在工程中引入了多个第三方jar包,导致调用的方法数超过了android设定的65536个(DEX 64K problem),进而导致dex无法生成,也就无法生成APK文件。

编译时候产生如下的异常信息:

 


解决方案


Google给出的解决方案就是使用MultiDexApplication

    • Multidex Apps

      1.在项目的build.gradle文件的dependencies 节中添加分包设置:

      2.通过在defaultConfig节中设置multiDexEnabled标签为true,开启multi-dexing支持.

      3.如果没有创建自己的Application.class,直接在AndroidManifest.xml文件的Application声明中添加:

      如果实现了自己的Application.class,则修改继承的父类为
      android.support.multidex.MultiDex.MultiDexApplication

 

  • Multidex Apps单元测试

    1.在项目的build.gradle文件的dependencies 节中添加分包设置:

    2.通过在defaultConfig节中设置multiDexEnabled标签为true,开启multi-dexing支持.

 


参考链接


  1. Building Apps with Over 65K Methods
  2. Which package for MultiDexTestRunner? android.support.multidex or com.android.test.runner
  3. Android学习笔记----解决“com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536”问题

android-ndk-r10e开启C++11,编译TEMP_FAILURE_RETRY错误

在使用select来操作socket的时候,一般都是会这么写

其中的“TEMP_FAILURE_RETRY”宏在“unistd.h”中的定义如下:

正常情况下,编译是没问题的。但是当在“Application.mk”中增加

之后,发现编译不通过了。报告“error: 'typeof' was not declared in this scope”。

解决方法:


“c++11”和“gnu++11”的差别:

“gnu++11”增加了很多的扩展“c++11”的功能,功能更加多,具体的扩展参考Extensions to the C++ Language

NDK下GCC定义__cplusplus不正确的问题

在C++升级之后,编译会出现“C++11 error: unable to find string literal operator 'operator"”这种错误,按照链接里面操作,在“android-ndk-r10e”上面依旧出现问题。

追踪了一下,才发现,这个是GCC的一个BUG,GCC-4.7,GCC-4.8中定义的__cplusplus 竟然都是 “__cplusplus=1”,这个是明显不正确的,具体的BUG内容查看“__cplusplus defined to 1, should be 199711L”。

尽管这个BUG已经修复了,但是很明显“android-ndk-r10e”使用的GCC版本并没有合并这个补丁。

解决方案

升级GCC到4.9,在”Application.mk“中增加

Android下NDK开发的动态库(.so,shared library)增加版本号信息

在Android下面开发,免不了要涉及到C/C++层的开发,这就会涉及到崩溃异常的处理问题。

随着程序的不断升级,更新,会出现多个版本的动态库同时在线上共存的问题,一旦出现崩溃日志,往往不能方便的知道到底是哪个版本出现的崩溃。

传统的Linux,可以通过编译时候指定版本号来处理,最后生成如“libc.so.6”这种形式的文件名,我们可以根据文件名来获得相应的版本信息。遗憾的是,这种命名方式,在Android上面是不支持的

目前的需求主要有三点:

  1. 不依赖文件名,查询到版本号

    版本号写在文件名中,是一个比较方便的方式,但是带来的问题却是,靠不住!文件名可以随意更改,往往传来传去,文件名中的信息就改得面目全非了。

  2. logcat的崩溃日志中能得到版本号

    系统自带的logcat会在进程崩溃的时候,打印出崩溃栈,但是信息非常的精简,只有当前的线程回退栈帧信息(backtrace)以及几个关键寄存器信息,往往不能准确提供有足够的信息。而如果想在客户的设备上面,拿到完整的core-dump信息,只能是呵呵一下了!

  3. C/C++层的版本号变动,不要改动JAVA层的代码

    一方面,如果我们把版本号写在动态库的名字里面,这样会造成每次动态库的升级,JAVA的调用代码都需要变动,小团队还好,大团队,完全不可想象。另一方面,如果是系统框架层的开发,更加悲催,一个文件名的改动,影响到一片,当然,软链接也是个不错的选择,但是这样,常用的APK开发又要折腾一番,免不了一堆的抱怨。

针对上面的需求,我们逐个来提供解决方案:

  • 不依赖文件名,查询到版本号

在任意的C/C++文件中增加如下代码

在Android.mk文件中增加

编译生成的".so"文件使用如下命令即可查询版本号信息:

解释:
上面的代码的目的,是要求GCC在一个名为".SO_VERSION"的段内,记录我们的版本号信息。“unused”属性用于告诉GCC,不要在编译的时候警告这个变量没有被任何代码引用过。
注意事项:
在定义变量"Version"的时候,不要使用"volatile"来修饰。这个关键字影响到了最后生成的段的"PROGBITS"标记位置,这个标记表明了最后加载到内存中的数据是否可修改(我们当然希望这个位置不可修改,如果可写,可能由于越界导致版本号的不准确)。

没有使用"volatile"修饰

使用"volatile"修饰

注意两者的不同,一个属性是"A",一个属性是"WA"。

  • logcat的崩溃日志中能得到版本号,并且C/C++层的版本号变动,不要改动JAVA层的代码

目前对于这个问题的解决方法,是设置代理So。具体操作方式如下(假定我们生成的".so"项目LOCAL_MODULE:=So):

1.修改原来项目中的"JNI_OnLoad","JNI_OnUnLoad"函数,重新命名为 "So_JNI_OnLoad","So_JNI_OnUnLoad" 其他代码不变,并且在"So-jni.h"中对这两个函数进行声明。

2.所有的JNI方法都通过 "JavaVM->RegisterNatives" 方法进行动态注册。

3.建立SoStub-jni.cpp,代码如下:

4.原工程的"LOCAL_MODULE"修改为"LOCAL_MODULE:=So_1_0_3"(版本号根据实际情况调整即可

5.修改Android.mk,增加如下内容

6.修改JAVA层的调用代码

为:

解释:

由于logcat打印的崩溃栈,信息极少,因此我们只能采取这种折中的办法,这样设置之后,崩溃栈中会打印出"libSo_1_0_3.so"这样的字样,我们就可以知道版本号了。

LMbench 3.0移植到Android并测试内存带宽

LMbench是个可移植的,用于评价系统综合性能的多平台开源benchmark,能够测试包括文档读写、内存操作、进程创建销毁开销、网络等性能。通过以下步骤操作,即可将LMbench移植到Android上。

  • 下载LMbench源码

下载地址http://sourceforge.net/projects/lmbench/
也可在本站下载

  • 修改LMbench代码

1.解压缩到指定的目录,保证最终的目录如下:

├── lmbench3/

│        ├── jni/

│            ├── doc/

│            ├── result/

│            ├── scripts/

│            ├── src/

│            ├── ACKNOWLEDGEMENTS

│            ├── CHANGES

│            ├── COPYING

│            ├── COPYING-2

│            ├── hbench-REBUTTAL

│            ├── Makefile

│            ├── README

2.修改“src/bench.h”的38行,40行,注释掉“#include <rpc/rpc.h>”,“#include <rpc/types.h>”,然后添加如下定义

3.添加根目录下面Android.mk,jni/目录下面内容如下:

4.添加根目录下面Android.mk,jni/src目录下面内容如下:

  • 编译LMbench代码

编译完成后的文件存放在“lmbench3\libs\armeabi”目录下面。

  • 测试内存带宽

更详细的命令参数,参考bw_mem

  • 参考链接
  1. andlmbench
  2. lmbench
  3. Performance Measurement on ARM

Windows下android-ndk-r10e执行ndk-gdb.py报告“ERROR: Non-debuggable application installed on the target device.”

Windows下android-ndk-r10e执行ndk-gdb.py报告“ERROR: Non-debuggable application installed on the target device.”

使用命令:

具体信息如下所示。android-ndk-r10e-ndk-gdb-py

使用apk-tool反编译了一下APK包,AndroidManifest.xml中的“android:debuggable="true"”已经设置了,lib\armeabi目录下面也已经存在gdb.setup,gdbserver。奇怪了!使用pyScripter跟踪ndk-gdb.py,在684行附近发现,脚本找错目录了。ndk-gdb-py-684

解决方法比较简单,拷贝一份“android-ndk-r10e\prebuilt\android-arm”,并且重新命名成为 “android-ndk-r10e\prebuilt\android-armeabi”即可。

Android 5.0 模拟器休眠唤醒(黑屏)

Android 5.0 模拟器默认在一分钟之内没有操作,就会关闭屏幕,出现黑屏的情况,如下图所示.android_simulator_black_screen

注意,这不是死掉了,只是休眠了而已。解除休眠的方式是按“ESC”或者“F7”按键即可。如果需要测试休眠的话,“F7”按键是个不错的选择。

NDK 链接第三方静态库的方法

将NDK编译的第三方静态拷贝到JNI目录下,在Android.mk中添加如下代码

以openssl静态库(libcrypto-static.a)为例

第一种链接方法:LOCAL_LDFLAGS := libcrypto-static.a(不推荐,有编译警告

第二种链接方法:LOCAL_LDLIBS := libcrypto-static.a(不推荐,有编译警告

第三种链接方法:(推荐