Android中的ListView与iOS的UITableView提供了实现类似功能的方法,但在iOS中,表格控件的编辑状态一般都是通过菜单项触发的,而在Android中,则可以使用叫做ActionMode的行为(一般是长按列表项触发)进入表格项编辑状态,然后可以进行一些如多选批量删除之类的操作,方便快捷。进入ActionMode后,需要对列表项的选中状态进行图形上的表示,如加入选中标记,改变选中项背景颜色等,实现此操作需要配合AbsListView.MultiChoiceModeListener的事件通知及ListAdapter的getView操作:
Continue reading…
android
Android NDK中多线程JNI的local reference释放问题
首先声明这个问题是在Android系统中进行JNI调用时发现的,不确定是标准Java行为还是Android的特例,非Android系统仅供参考!
之前在做NDK开发时,自然少不了JNI的Java->C/C++以及C/C++->Java的互相调用过程,如一些常见的GetStringUTFChars,GetObjectClass等等,对VM的Java对象引用计数也略有一些概念,像GetStringUTFChars需要ReleaseStringUTFChars,DeleteLocalRef释放局部引用计数等,不过大部分情况下,没有DeleteLocalRef也没出什么太大的问题,这次在试验NDK的C+11支持时用到了std::thread和lambda表达式创建了native线程,如下:
workerThread = std::thread([this]() { g_pVM->AttachCurrentThread(&mJNIEnv, NULL); ... g_pVM->DetachCurrentThread(); } );
并在线程中进行了Java方法的调用,传递了一些字符串,结果没跑几个循环进程就crash掉了,看了下logcat提示的错误是:
JNI ERROR (app bug): local reference table overflow (max=512)
并打印出了最后200个local reference table中的东西,看了下有传的String有get到的Java class,于是想到了释放引用的问题,不过JNI调用的代码都是copy过来以前写的,也没出现过类似的问题,很是奇怪。
发现一款基于OllyDbg的Android ARM调试工具
最近研究Android平台的原生代码so保护时找到了一款很好用的汇编级调试工具:基于OllyDbg的GikDbg,传送门:http://www.gikir.com/product.php
上学时学习汇编曾经接触过OllyDbg,用起来很是顺手,结合着IDA的静态分析,学到了不少底层的知识。
最开始研究Android原生代码逆向时用的是IDA Pro,明显看到最近的版本中,IDA一直在强化动态调试能力以及对移动平台的支持,不过实际测试时发现,虽然的arm elf可以反汇编以及分析代码,但是动态调试时其自带的android_server远程调试服务器不能很好地支持Android 2.3.3以上的系统,网上搜索看到有人说可以使用gdb server来远程调试,但是试了几次都没有成功。android_server据说在IDA 6.3版以后就可以很好地支持4.0+的系统了,无奈没有资源…
后来很幸运的找到了这个GikDbg,显示抱着试一试的想法,用4.0.3的模拟器测试了一下,发现很好用,Attach,断点等一切正常,就是反应速度稍慢,这应该是gdb远程调试的通病吧…
最开始看官网上的Android版名字叫GikDbg.ART还以为只有开启ART运行时模式才行,后来实测DVM也没有问题,而且连模拟器都能很好的支持,当然物理设备的话需要root,否则push不过去gdbserver。
使用说明在这里:http://gikir.com/blog/?p=115,Android 4.0.3模拟器DVM运行时一次成功!
Android中GLSurfaceView在横竖屏切换时重新创建表面缓冲导致的问题
在做Android的OpenGL ES应用时,经常会遇到接入各种支付SDK等弹出UI导致当前横竖屏状态切换的问题,比如游戏是横屏landscape的,而支付SDK弹出的View是竖屏portrait的,这时如果不插手处理的话,系统会对GL的表面缓冲进行重新创建的处理,比如横屏的800×480会被重新创建为480×800,这样就会导致绘图错误,效果可以参考下面stackoverflow上贴出的图片。
解决这个问题的方法是:
Continue reading…
如何转换Android打包用jks格式keystore证书为Air用pkcs12格式p12证书
由于受到Flash先进的Stage3D技术以及Unreal Epic Citadel演示的诱惑,决定试用一下Flash Builder的跨平台性能,顺利运行Starling 2D框架demo后决定打包上设备一试,遂即发现Air的跨平台导出Android安装包所需的签名证书居然是.p12格式,虽然这种“合体”证书在开发iOS时用到的还是蛮多的,但对Android开发来说还是头一次。
很明显,默认情况下原生Android开发生成的发布证书keystore不是.p12的格式,这时就需要转换一下,好在JDK中的一个叫keytool的工具可以完成此项工作,方法如下:
Continue reading…
[译]Android冰淇淋三明治ICS(4.0+)JNI局部引用的变化
译序:
这篇文章的内容实际是在我发现一个项目bug后寻找解决方案时找到的,当时项目原有target为8(ICS 4.0之前的2.X版本),在4.0+的S3上运行一切正常,而后target升级到14时再在S3上运行时就会出现类似如下的native crash:
05-13 14:07:13.139: E/dalvikvm(22265): JNI ERROR (app bug): attempt to use stale local reference 0x20d00001
05-13 14:07:13.139: E/dalvikvm(22265): VM aborting
05-13 14:07:13.139: A/libc(22265): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 22457 (Thread-1276)
05-13 14:07:13.239: I/DEBUG(1894): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
05-13 14:07:13.249: I/DEBUG(1894): Build fingerprint: ‘samsung/m0zc/m0chn:4.1.2/JZO54K/I9300ZCEMB1:user/release-keys’
05-13 14:07:13.249: I/DEBUG(1894): pid: 22265, tid: 22457, name: Thread-1276 >>> cn.android.app <<<
05-13 14:07:13.249: I/DEBUG(1894): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
05-13 14:07:13.489: I/DEBUG(1894): r0 00000000 r1 00000000 r2 deadd00d r3 00000000
05-13 14:07:13.489: I/DEBUG(1894): r4 408cb1a8 r5 0000020c r6 20d00001 r7 fffff86c
05-13 14:07:13.489: I/DEBUG(1894): r8 5ee308dc r9 00004e58 sl fffff870 fp 5ee307b8
05-13 14:07:13.489: I/DEBUG(1894): ip 00004000 sp 5ee30540 lr 400f7c95 pc 40866e50 cpsr 60000030
05-13 14:07:13.489: I/DEBUG(1894): d0 3ff000003f800000 d1 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d2 0000000000000000 d3 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d4 0000000000000000 d5 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d6 0000000000000000 d7 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d8 0000000000000000 d9 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d10 0000000000000000 d11 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d12 0000000000000000 d13 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d14 0000000000000000 d15 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d16 0000000000000000 d17 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d18 0000000000000000 d19 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d20 0000000000000000 d21 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d22 0000000000000000 d23 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d24 0000000000000000 d25 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d26 0000000000000000 d27 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d28 0000000000000000 d29 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d30 0000000000000000 d31 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): scr 60000010
05-13 14:07:13.499: I/DEBUG(1894): backtrace:
05-13 14:07:13.499: I/DEBUG(1894): #00 pc 00045e50 /system/lib/libdvm.so (dvmAbort+75)
05-13 14:07:13.499: I/DEBUG(1894): #01 pc 00028c3c /system/lib/libdvm.so (IndirectRefTable::get(void*) const+336)
05-13 14:07:13.499: I/DEBUG(1894): #02 pc 00049eeb /system/lib/libdvm.so (dvmDecodeIndirectRef(Thread*, _jobject*)+30)
05-13 14:07:13.499: I/DEBUG(1894): #03 pc 0004ca77 /system/lib/libdvm.so
05-13 14:07:13.499: I/DEBUG(1894): #04 pc 00653480 /data/data/cn.android.app/lib/libgameapp.so (CKSoundManager::LoadBGM(char const*)+56)
…
05-13 14:07:13.509: I/DEBUG(1894): memory map around fault addr deadd00d:
05-13 14:07:13.509: I/DEBUG(1894): be9ae000-be9cf000 [stack]
05-13 14:07:13.509: I/DEBUG(1894): (no map for address)
05-13 14:07:13.509: I/DEBUG(1894): ffff0000-ffff1000 [vectors]
05-13 14:07:13.674: I/DEBUG(1894): !@dumpstate -k -t -z -d -o /data/log/dumpstate_app_native -m 22265
Google Android NDK r8e中的bug修正
发现这个bug是通过clean cocos2d-x项目时出现的,错误信息为make: *** [clean-box2d_static-armeabi] Error 2
而正常build不会出任何问题,问题是由于r8e版的NDK中的build/core/build-binary.mk一处错误导致:
替换49行的:
$(cleantarget): PRIVATE_CLEAN_FILES := ($(my)OBJS)
为:
Dx bad class file magic (cafebabe) or version (0033.0000)
今天在升级一个早期Android项目到新版Eclipse ADT SDK后,编译运行项目后Android Console中出现标题中的错误,特此记下解决方法:
导致这个问题的原因是由于Android项目属性中的Java Compiler设置为1.6版本的,而Eclipse的Preference中的被设置为1.7所致,也换成1.6就不会提示这个错误了!