mixare的measureText方法在频繁调用时抛出“referencetable overflow max 1024”的解决方式

这几天在搞基于位置的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

通过

id=145">https://code.google.com/p/mixare/issues/detail?id=145

id=36908">https://code.google.com/p/android/issues/detail?id=36908大致了解到了原因就是在频繁调用native_measureText可能出现了内存泄露,可是始终没有好的解决方式。

最后经过一番折腾,最终在

id=22">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;
	}
时间: 2024-10-26 06:18:07

mixare的measureText方法在频繁调用时抛出“referencetable overflow max 1024”的解决方式的相关文章

在android中调用jni,出现ReferenceTable overflow (max=1024)

转:http://m.blog.csdn.net/blog/redouba/20624631 最近在做android监控方面的项目,在调用.so库解码的时候,运行时间长了就会报出 ReferenceTable overflow (max=1024)的错误.然后再网上搜啊搜,大致的结果就是没有释放资源种种.. 参考资料: 问题来源: 写了一个较为复杂的Native so库,里面使用了链表,从链表中取出数据,装载到Java LinkedList中. 当测试数据较小的时候还没有问题,当测试数据达到一定

【Servlet+Struts2】文件下载时抛出java.lang.IllegalStateException异常的解决方法

java.lang.IllegalStateException这种异常,不代表文件不能下载,不代表程序写错,它在Tomcat抛出完异常之后依然能够正常运行的.只是看着不爽而已,每次下载都要在Tomcat抛出一大堆异常. java.lang.IllegalStateException主要是用了后台把文件丢进respond的缓冲区,然后respond再把下载的文件扔回JSP的情况所造成的.Servlet与Struts2反正是JSP都有可能存在.其主要原因JSP在对缓冲区读,后台JAVA在对缓冲写所导

java异常处理:建立exception包,建立Bank类,类中有变量double balance表示存款,Bank类的构造方法能增加存款,Bank类中有取款的发方法withDrawal(double dAmount),当取款的数额大于存款时,抛出InsufficientFundsException,取款数额为负数,抛出NagativeFundsException,如new Bank(100),

建立exception包,建立Bank类,类中有变量double  balance表示存款,Bank类的构造方法能增加存款,Bank类中有取款的发方法withDrawal(double dAmount),当取款的数额大于存款时,抛出InsufficientFundsException,取款数额为负数,抛出NagativeFundsException,如new Bank(100),表示存入银行100元,当用方法withdrawal(150),withdrawal(-15)时会抛出自定义异常. pa

Android中调用WebService抛出Connection reset by peer异常

最近在做的项目中用到了WebService,因为Android中没有提供直接调用WebService的Api,我就使用了 ksoap,但是在使用过程中遇到了一个奇怪的BUG: 请求一次WebService之后,什么都不做,静待1分钟之后,再次请求这个WebService时就会抛出以下异常: 06-17 15:11:07.869: W/System.err(10915): java.net.SocketException: sendto failed: ECONNRESET (Connection

AES加密时抛出java.security.InvalidKeyException:&#160;Illegal&#160;key&#160;size&#160;or&#160;def

原文:AES加密时抛出java.security.InvalidKeyException: Illegal key size or def 使用AES加密时,当密钥大于128时,代码会抛出 java.security.InvalidKeyException: Illegal key size or default parameters Illegal key size or default parameters是指密钥长度是受限制的,java运行时环境读到的是受限的policy文件.文件位于${

FtpClient 调用storeFile 抛出 java.net.SocketException异常

在使用换了commons-net 的 FTPClient 调用storeFile方法时报错, 调用 res = ftp.storeFile(remoteFileName, inputStream);后返回true,并且文件能正常上传,但是抛出java.net.SocketException: Socket closed异常. 解决: 更新commons-net  jar包,从3.0升到3.4 该问题消失了. 原文地址:https://www.cnblogs.com/Allen-win/p/106

AES加密时抛出java.security.InvalidKeyException: Illegal key size or default parametersIllegal key size or default parameters

使用AES加密时,当密钥大于128时,代码会抛出java.security.InvalidKeyException: Illegal key size or default parameters Illegal key size or default parameters是指密钥长度是受限制的,java运行时环境读到的是受限的policy文件.文件位于${java_home}/jre/lib/security 这种限制是因为美国对软件出口的控制. 解决办法: 去掉这种限制需要下载Java Cry

AES加密时抛出 Illegal key size or default parameters

使用AES加密时,当密钥大于128时,代码会抛出java.security.InvalidKeyException: Illegal key size or default parameters Illegal key size or default parameters是指密钥长度是受限制的,java运行时环境读到的是受限的policy文件.文件位于${java_home}/jre/lib/security 这种限制是因为美国对软件出口的控制. 解决办法: 去掉这种限制需要下载Java Cry

2.建立exception包,建立Bank类,类中有变量double balance表示存款,Bank类的构造方法能增加存款,Bank类中有取款的发方法withDrawal(double dAmount),当取款的数额大于存款时,抛出InsufficientFundsException,取款数额为负数,抛出NagativeFundsException,

public class Bank { Double qian=0.0; double newBank(double a) { qian=qian+a; return qian; } double withDrawal(double dAmount) throws Exception { if(dAmount>qian) { throw new Exception("InsufficientFundsException"); } if(dAmount<0) { throw