这几天在搞基于位置的AR应用,采用了github上两款开源项目:
mixare
android-argument-reality-framework
这两个项目实现机制大致相同,我选取的是android-argument-reality-framework,原因是我认为他的代码结构要清晰很多(纯属个人意见)。这两个项目的demo在运行时都会crash,通过查看控制台,可以看到如下信息:
07-31 14:35:38.685: W/dalvikvm(13686): ReferenceTable overflow (max=1024) 07-31 14:35:38.685: W/dalvikvm(13686): JNI pinned array reference table (0x5fc810) dump: 07-31 14:35:38.685: W/dalvikvm(13686): Last 10 entries (of 1024): 07-31 14:35:38.685: W/dalvikvm(13686): 1023: 0x4130ada8 char[] (29 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 1022: 0x4130a768 char[] (29 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 1021: 0x413ad8d0 char[] (29 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 1020: 0x413aa990 char[] (36 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 1019: 0x40ea2eb0 char[] (5 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 1018: 0x40e262d8 char[] (5 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 1017: 0x40ee8000 char[] (4 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 1016: 0x40e97418 char[] (4 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 1015: 0x413a9e38 char[] (22 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 1014: 0x413a9858 char[] (33 elements) 07-31 14:35:38.685: W/dalvikvm(13686): Summary: 07-31 14:35:38.685: W/dalvikvm(13686): 1 of byte[] (128 elements) 07-31 14:35:38.685: W/dalvikvm(13686): 50 of char[] (4 elements) (2 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 50 of char[] (5 elements) (2 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 25 of char[] (22 elements) (25 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 24 of char[] (23 elements) (24 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 24 of char[] (24 elements) (24 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 24 of char[] (25 elements) (24 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 24 of char[] (27 elements) (24 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 24 of char[] (28 elements) (24 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 508 of char[] (29 elements) (508 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 24 of char[] (31 elements) (24 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 49 of char[] (33 elements) (49 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 25 of char[] (34 elements) (25 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 50 of char[] (36 elements) (50 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 25 of char[] (37 elements) (25 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 49 of char[] (39 elements) (49 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 24 of char[] (44 elements) (24 unique instances) 07-31 14:35:38.685: W/dalvikvm(13686): 24 of char[] (63 elements) (24 unique instances) 07-31 14:35:38.685: E/dalvikvm(13686): Failed adding to JNI pinned array ref table (1024 entries) 07-31 14:35:38.685: I/dalvikvm(13686): "main" prio=5 tid=1 RUNNABLE 07-31 14:35:38.685: I/dalvikvm(13686): | group="main" sCount=0 dsCount=0 obj=0x40a59460 self=0x343830 07-31 14:35:38.685: I/dalvikvm(13686): | sysTid=13686 nice=0 sched=0/0 cgrp=default handle=1074517384 07-31 14:35:38.685: I/dalvikvm(13686): | schedstat=( 23316582697 3886607959 27513 ) utm=2194 stm=137 core=0 07-31 14:35:38.685: I/dalvikvm(13686): at android.graphics.Paint.native_measureText(Native Method) 07-31 14:35:38.685: I/dalvikvm(13686): at android.graphics.Paint.measureText(Paint.java:1288) 07-31 14:35:38.685: I/dalvikvm(13686): at org.mixare.lib.gui.PaintScreen.getTextWidth(PaintScreen.java:153) 07-31 14:35:38.685: I/dalvikvm(13686): at org.mixare.lib.gui.TextObj.prepTxt(TextObj.java:107) 07-31 14:35:38.685: I/dalvikvm(13686): at org.mixare.lib.gui.TextObj.<init>(TextObj.java:65) 07-31 14:35:38.685: I/dalvikvm(13686): at org.mixare.lib.gui.TextObj.<init>(TextObj.java:50) 07-31 14:35:38.685: I/dalvikvm(13686): at org.mixare.marker.ImageMarker.drawTitle(ImageMarker.java:135) 07-31 14:35:38.685: I/dalvikvm(13686): at org.mixare.marker.ImageMarker.draw(ImageMarker.java:120) 07-31 14:35:38.685: I/dalvikvm(13686): at org.mixare.DataView.draw(DataView.java:252) 07-31 14:35:38.685: I/dalvikvm(13686): at org.mixare.AugmentedView.onDraw(MixView.java:1411) 07-31 14:35:38.685: I/dalvikvm(13686): at android.view.View.draw(View.java:10978) 07-31 14:35:38.685: I/dalvikvm(13686): at android.view.ViewGroup.drawChild(ViewGroup.java:2887) 07-31 14:35:38.685: I/dalvikvm(13686): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489) 07-31 14:35:38.685: I/dalvikvm(13686): at android.view.ViewGroup.drawChild(ViewGroup.java:2885) 07-31 14:35:38.685: I/dalvikvm(13686): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489) 07-31 14:35:38.685: I/dalvikvm(13686): at android.view.ViewGroup.drawChild(ViewGroup.java:2885) 07-31 14:35:38.685: I/dalvikvm(13686): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489) 07-31 14:35:38.685: I/dalvikvm(13686): at android.view.View.draw(View.java:10981) 07-31 14:35:38.685: I/dalvikvm(13686): at android.widget.FrameLayout.draw(FrameLayout.java:450) 07-31 14:35:38.685: I/dalvikvm(13686): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2126) 07-31 14:35:38.690: I/dalvikvm(13686): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2026) 07-31 14:35:38.690: I/dalvikvm(13686): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634) 07-31 14:35:38.690: I/dalvikvm(13686): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442) 07-31 14:35:38.690: I/dalvikvm(13686): at android.os.Handler.dispatchMessage(Handler.java:99) 07-31 14:35:38.690: I/dalvikvm(13686): at android.os.Looper.loop(Looper.java:137) 07-31 14:35:38.690: I/dalvikvm(13686): at android.app.ActivityThread.main(ActivityThread.java:4575) 07-31 14:35:38.690: I/dalvikvm(13686): at java.lang.reflect.Method.invokeNative(Native Method) 07-31 14:35:38.690: I/dalvikvm(13686): at java.lang.reflect.Method.invoke(Method.java:511) 07-31 14:35:38.690: I/dalvikvm(13686): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 07-31 14:35:38.690: I/dalvikvm(13686): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 07-31 14:35:38.690: I/dalvikvm(13686): at dalvik.system.NativeStart.main(Native Method) 07-31 14:35:38.690: E/dalvikvm(13686): VM aborting通过 https://code.google.com/p/mixare/issues/detail?id=145和 https://code.google.com/p/android/issues/detail?id=36908大致了解到了原因就是在频繁调用native_measureText可能出现了内存泄露,但是始终没有好的解决方案。
最后经过一番折腾,终于在https://code.google.com/p/android-augment-reality-framework/issues/detail?id=22里找到的解决的,给出的解决方案如下:
http://stackoverflow.com/questions/16813706/android-apps-activity-force-back。
修改android-augment-reality-framework项目的src/com/jwetherell/augmented_reality/ui/objects/PaintableObject.java中的getTextWidth方法为如下代码即可:
/** * Get the width of the text String. * * @param txt * CharSequence to get the width of. * @param start * Start of the text. * @param end * End of the text. * @return float width of the text String. * @throws NullPointerException * if the String param is NULL. */ public float getTextWidth(CharSequence text) { if (text == null) throw new NullPointerException(); TextPaint textPaint = new TextPaint(paint); int widthWrap = 1000; // you may have to change this StaticLayout layout = measure(textPaint, text, widthWrap); return getMaxLineWidth(layout); } private float getMaxLineWidth(StaticLayout layout) { float maxLine = 0.0f; int lineCount = layout.getLineCount(); for (int i = 0; i < lineCount; i++) { if (layout.getLineWidth(0) > maxLine) { maxLine = layout.getLineWidth(0); } } return maxLine; } private StaticLayout measure(TextPaint textPaint, CharSequence text, Integer wrapWidth) { int boundedWidth = Integer.MAX_VALUE; if (wrapWidth != null && wrapWidth > 0) { boundedWidth = wrapWidth; } StaticLayout layout = new StaticLayout(text, textPaint, boundedWidth, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); return layout; }