Android 4.3 Monkey自动化测试工具被killed的原因分析

来源:互联网 发布:电气常用数据手册 编辑:程序博客网 时间:2024/05/22 17:47


原创链接:http://blog.csdn.net/zhao_3546/article/details/19193277

测试组使用Monkey在Android上想对APK进行自动化测试,但在启动Monkey测试工具时,一直无法正常启动,

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. shell@android:/ $ monkey -p com.android.calculator2 -v 100  
  2. monkey -p com.android.calculator2 -v 100  
  3. :Monkey: seed=1393356259515 count=100  
  4. :AllowPackage: com.android.calculator2  
  5. :IncludeCategory: android.intent.category.LAUNCHER  
  6. :IncludeCategory: android.intent.category.MONKEY  
  7. Killed  

一执行就会被killed,无意间测试说起这个问题,说是因为这个系统我们定制过,应该是定制的原因导致的问题。

我较真了,怎么可能是我们定制的原因呢?一般的APK在这个系统上都是可以正常运行的,并且也没有出过问题,所以我对定制这个说法完全不认同。

让相关人员重新执行后,让他同时提供相应的logcat的日志。

 

日志如下: 

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. 02-13 10:02:24.604 D/AndroidRuntime(14430): Calling main entry com.android.commands.monkey.Monkey  
  2. 02-13 10:02:24.614 D/dalvikvm(14430): Note: class Landroid/app/ActivityManagerNative; has 168 unimplemented (abstract) methods  
  3. 02-13 10:02:24.614 D/AndroidRuntime(14430): Shutting down VM  
  4. 02-13 10:02:24.614 W/dalvikvm(14430): threadid=1: thread exiting with uncaught exception (group=0x416a5700)  
  5. 02-13 10:02:24.614 E/ActivityManager(  605): Activity Manager Crash  
  6. 02-13 10:02:24.614 E/ActivityManager(  605): java.lang.NullPointerException  
  7. 02-13 10:02:24.614 E/ActivityManager(  605):     at com.android.server.am.ActivityManagerService.registerReceiver(ActivityManagerService.java:11867)  
  8. 02-13 10:02:24.614 E/ActivityManager(  605):     at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:308)  
  9. 02-13 10:02:24.614 E/ActivityManager(  605):     at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:1809)  
  10. 02-13 10:02:24.614 E/ActivityManager(  605):     at android.os.Binder.execTransact(Binder.java:388)  
  11. 02-13 10:02:24.614 E/ActivityManager(  605):     at dalvik.system.NativeStart.run(Native Method)  
  12. 02-13 10:02:24.624 E/JavaBinder(14430): Unknown binder error code. 0xfffffff7  
  13. 02-13 10:02:24.624 I/Process (14430): Sending signal. PID: 14430 SIG: 9  
  14. 02-13 10:02:24.624 E/AndroidRuntime(14430): *** FATAL EXCEPTION IN SYSTEM PROCESS: main  
  15. 02-13 10:02:24.624 E/AndroidRuntime(14430): java.lang.NullPointerException  
  16. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.os.Parcel.readException(Parcel.java:1437)  
  17. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.os.Parcel.readException(Parcel.java:1385)  
  18. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.app.ActivityManagerProxy.registerReceiver(ActivityManagerNative.java:2237)  
  19. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.commands.monkey.MonkeyNetworkMonitor.register(MonkeyNetworkMonitor.java:88)  
  20. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.commands.monkey.Monkey.getSystemInterfaces(Monkey.java:979)  
  21. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.commands.monkey.Monkey.run(Monkey.java:586)  
  22. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.commands.monkey.Monkey.main(Monkey.java:509)  
  23. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)  
  24. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:235)  
  25. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at dalvik.system.NativeStart.main(Native Method)  
  26. 02-13 10:02:24.624 E/AndroidRuntime(14430): Error reporting crash  
  27. 02-13 10:02:24.624 E/AndroidRuntime(14430): android.os.RemoteException: Unknown binder error code. 0xfffffff7  
  28. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.os.BinderProxy.transact(Native Method)  
  29. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:3525)  
  30. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:76)  
  31. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)  
  32. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)  
  33. 02-13 10:02:24.624 E/AndroidRuntime(14430):     at dalvik.system.NativeStart.main(Native Method)  

我了个去,这个程序一运行,居然把 Activity Manager 给搞挂了,从现象来看,应该是Framework层的bug,即使应用有问题,ActivityManger也不应该挂。

分析了一下代码,看看 com.android.server.am.ActivityManagerService.registerReceiver 的实现:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. public Intent registerReceiver(IApplicationThread caller, String callerPackage,  
  2.         IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {  
  3.     ...  
  4.     synchronized(this) {  
  5.         ProcessRecord callerApp = null;  
  6.         if (caller != null) {  
  7.             callerApp = getRecordForAppLocked(caller);  
  8.             if (callerApp == null) {  
  9.                 throw new SecurityException(  
  10.                         "Unable to find app for caller " + caller  
  11.                         + " (pid=" + Binder.getCallingPid()  
  12.                         + ") when registering receiver " + receiver);  
  13.             }  
  14.             ...  
  15.             callingUid = callerApp.info.uid;  
  16.             callingPid = callerApp.pid;  
  17.         } else {  
  18.             callerPackage = null;  
  19.             callingUid = Binder.getCallingUid();  
  20.             callingPid = Binder.getCallingPid();  
  21.         }  
  22.   
  23.         ...  
  24.   
  25.         BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,   // 日志显示,挂在这里  
  26.                 permission, callingUid, userId, callerApp.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0);  
  27.         ...  
  28. }  

从代码上看,出现空指针异常的这个点,确实是有缺陷的,如果 caller 为null,则 callerApp 就是 null。

Google发布的代码,也会有bug,是人写的代码,就有缺陷啊。

修改成为如下:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,  
  2.         permission, callingUid, userId,   
  3.         (callerApp != null && (callerApp.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0));  

重新编译出相应的 services.jar,替换 /system/framework/ 下的同名文件,再让测试重新验证,问题解决。

 其实在测试给我说了Monkey的作用后,我就在想Monkey的实现原理,如下纯粹个人猜想,未进一步找资料验证。

集成Android开发SDK的Eclipse中,提供了DDMS的功能,通过点击如下“红框”圈住的按钮,就可以得到右边的视图,即当前手机屏幕上显示的内容,以及View对象树,

我个人分析Monkey也是使用类似的原理,通过DDMS获取当前屏幕上显示的View对象视图,有了这个,其实也就有了哪个区域可以被点击,再通过脚本来控制相应的点击区域即可。

我经常想起我之前PL在我给他解释某问题的可能原因时他经常问我的一句话,为什么是这个原因 你有证据吗?你有重现吗?

跟着他,我也学会时常问自己或别人为什么,为什么这样,为什么那样,通过多问为什么,也让我会去不断思考一些更深层次的东西,好的习惯给我带来的帮助真的难以估量。


0 0
原创粉丝点击