不知大伙有没有遇到这样的问题 , 使用android应用程序过程中, 一般是在listview或textview加载数据的时候程序突然退出, 并且没有提示任何错误. 到网上搜索, 没有找到任何有效的信息. 没办吧 , 只得自己打印日志一步一步调试程序 . 最后终于发现了一点眉目.
06-05 08:51:00.691: DEBUG/InputReader(202): AP_PROF:AppLaunch_dispatchPtr:Up:357013 06-05 08:51:00.692: DEBUG/InputDispatcher(202): Waiting because touched window Window{407b4788 com.tencent.mm/com.tencent.mm.ui.MainTabUI paused=false} still processing previous input. 06-05 08:51:00.692: DEBUG/PowerManagerService(202): userActivity mLastEventTime=356787 time=357013 mUserActivityAllowed=true mUserState=0x7 mWakeLockState=0x0 mProximitySensorActive=false mProximitySensorEnabed=false timeoutOverride=-1 force=false 06-05 08:51:00.692: DEBUG/PowerManagerService(202): reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff=false 06-05 08:51:00.692: DEBUG/PowerManagerService(202): setPowerState: mPowerState=0x7 newState=0x7 noChangeLights=false reason=2 06-05 08:51:00.692: DEBUG/PowerManagerService(202): setTimeoutLocked now=357013 timeoutOverride=-1 nextState=7 when=363013 06-05 08:51:00.693: DEBUG/InputDispatcher(202): Waiting because touched window Window{407b4788 com.tencent.mm/com.tencent.mm.ui.MainTabUI paused=false} still processing previous input. 06-05 08:51:00.695: DEBUG/InputDispatcher(202): Waiting because touched window Window{407b4788 com.tencent.mm/com.tencent.mm.ui.MainTabUI paused=false} still processing previous input. 06-05 08:51:00.697: VERBOSE/MicroMsg.NetSceneBatchGetHeadImg(900): set writting pause: true, handlerunning: false 06-05 08:51:00.739: ERROR/MicroMsg.AvatarStorage(900): small bm not exsit 06-05 08:51:00.739: DEBUG/MicroMsg.AvatarStorage(900): read from png :false 06-05 08:51:00.740: DEBUG/MicroMsg.AvatarLogic(900): getting head image: www521wy 06-05 08:51:00.740: DEBUG/MicroMsg.AvatarLogic(900): avatar service push :www521wy 06-05 08:51:00.779: ERROR/MicroMsg.AvatarStorage(900): small bm not exsit 06-05 08:51:00.780: DEBUG/MicroMsg.AvatarStorage(900): read from png :false 06-05 08:51:00.780: DEBUG/MicroMsg.AvatarLogic(900): getting head image: huzhenwei2011 06-05 08:51:00.781: DEBUG/MicroMsg.AvatarLogic(900): avatar service push :huzhenwei2011 06-05 08:51:00.807: WARN/System.err(900): java.lang.StringIndexOutOfBoundsException 06-05 08:51:00.811: WARN/System.err(900): at java.lang.String.getChars(String.java:1059) 06-05 08:51:00.813: DEBUG/MicroMsg.HttpMgr(908): onStatusCallback=4 06-05 08:51:00.815: DEBUG/MicroMsg.HttpMgr(908): onStatusCallback=4 06-05 08:51:00.817: WARN/System.err(900): at android.text.SpannableStringInternal.getChars(SpannableStringInternal.java:102) 06-05 08:51:00.819: WARN/System.err(900): at android.text.TextUtils.getChars(TextUtils.java:105) 06-05 08:51:00.819: WARN/System.err(900): at android.text.Layout.processToSupportEmoji(Layout.java:3747) 06-05 08:51:00.822: WARN/System.err(900): at android.text.Layout.supportTabandEmoji(Layout.java:3783) 06-05 08:51:00.824: WARN/System.err(900): at android.text.Layout.measureText2(Layout.java:3141) 06-05 08:51:00.826: WARN/System.err(900): at android.text.Layout.getDesiredWidth2(Layout.java:183) 06-05 08:51:00.828: WARN/System.err(900): at android.text.Layout.getDesiredWidth2(Layout.java:161) 06-05 08:51:00.830: WARN/System.err(900): at android.widget.TextView.onMeasure2(TextView.java:5925) 06-05 08:51:00.830: WARN/System.err(900): at android.widget.TextView.onMeasure(TextView.java:6138) 06-05 08:51:00.831: WARN/System.err(900): at android.view.View.measure(View.java:8363) 06-05 08:51:00.831: WARN/System.err(900): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3169) 06-05 08:51:00.832: WARN/System.err(900): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1048) 06-05 08:51:00.833: WARN/System.err(900): at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:732) 06-05 08:51:00.833: WARN/System.err(900): at android.widget.LinearLayout.onMeasure(LinearLayout.java:342) 06-05 08:51:00.833: WARN/System.err(900): at android.view.View.measure(View.java:8363) 06-05 08:51:00.834: WARN/System.err(900): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3169) 06-05 08:51:00.834: WARN/System.err(900): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1048) 06-05 08:51:00.835: WARN/System.err(900): at android.widget.LinearLayout.measureVertical(LinearLayout.java:417) 06-05 08:51:00.835: WARN/System.err(900): at android.widget.LinearLayout.onMeasure(LinearLayout.java:340) 06-05 08:51:00.835: WARN/System.err(900): at android.view.View.measure(View.java:8363) 06-05 08:51:00.836: WARN/System.err(900): at android.widget.ListView.setupChild(ListView.java:1862) 06-05 08:51:00.836: WARN/System.err(900): at android.widget.ListView.makeAndAddView(ListView.java:1789) 06-05 08:51:00.836: WARN/System.err(900): at android.widget.ListView.fillUp(ListView.java:735) 06-05 08:51:00.838: WARN/System.err(900): at android.widget.ListView.fillGap(ListView.java:681) 06-05 08:51:00.840: WARN/System.err(900): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:3508) 06-05 08:51:00.842: WARN/System.err(900): at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:3002) 06-05 08:51:00.843: WARN/System.err(900): at android.os.Handler.handleCallback(Handler.java:618) 06-05 08:51:00.845: WARN/System.err(900): at android.os.Handler.dispatchMessage(Handler.java:123) 06-05 08:51:00.845: WARN/System.err(900): at android.os.Looper.loop(SourceFile:351) 06-05 08:51:00.846: WARN/System.err(900): at android.app.ActivityThread.main(ActivityThread.java:3814) 06-05 08:51:00.847: WARN/System.err(900): at java.lang.reflect.Method.invokeNative(Native Method) 06-05 08:51:00.847: WARN/System.err(900): at java.lang.reflect.Method.invoke(Method.java:538) 06-05 08:51:00.848: WARN/System.err(900): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901) 06-05 08:51:00.849: WARN/System.err(900): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:659)
06-05 08:51:00.817: WARN/System.err(900): at android.text.SpannableStringInternal.getChars(SpannableStringInternal.java:102) 06-05 08:51:00.819: WARN/System.err(900): at android.text.TextUtils.getChars(TextUtils.java:105) 06-05 08:51:00.819: WARN/System.err(900): at android.text.Layout.processToSupportEmoji(Layout.java:3747) 06-05 08:51:00.822: WARN/System.err(900): at android.text.Layout.supportTabandEmoji(Layout.java:3783) 06-05 08:51:00.824: WARN/System.err(900): at android.text.Layout.measureText2(Layout.java:3141)
public static void getChars(CharSequence s, int start, int end, char[] dest, int destoff) { Class c = s.getClass(); if (c == String.class){ ((String) s).getChars(start, end, dest, destoff); }else if (c == StringBuffer.class){ ((StringBuffer) s).getChars(start, end, dest, destoff); }else if (c == StringBuilder.class){ System.out.println("class type: StringBuilder.class"); ((StringBuilder) s).getChars(start, end, dest, destoff); }else if (s instanceof GetChars){ ((GetChars) s).getChars(start, end, dest, destoff);//此处为105行, 而此处时间调用的是SpannableStringInternal.java的getChars函数. }else { for (int i = start; i < end; i++){ dest[destoff++] = s.charAt(i); } } }
frameworks\base\core\java\android\text\ SpannableStringInternal .java 的getChars函数代码如下:
public final void getChars(int start, int end, char[] dest, int off) { mText.getChars(start, end, dest, off); }
此处的 mText 是一个String对象. 根据异常提示信息, 可以肯定的是 dest 的值过大了. 但是dest是由android系统提供的 , 我们无法控制的呀. 然后返回, 查找dest值的出处. 最后终于在Layout.java的processToSupportEmoji函数处找到:
frameworks\base\core\java\android\text\ Layout.java的processToSupportEmoj 如下:
static CharSequence processToSupportEmoji(CharSequence text,int start, int end) { Spannable spannable = null; boolean containEmoji = false; int length = end - start +1; char[] chs = TextUtils.obtain(length); TextUtils.getChars(text, start, end, chs, 0); for (int i = start ; i < end; i++) { char c = chs[end-start]; if (c >= 0xD800 && c <= 0xDFFF && i + 1 < length) { char[] tmp = TextUtils.obtain(2); TextUtils.getChars(text, i, i+2, tmp, 0); int emoji = Character.codePointAt(tmp, 0); if (emoji >= MIN_EMOJI && emoji <= MAX_EMOJI) { Bitmap bm = EMOJI_FACTORY.getBitmapFromAndroidPua(emoji); if (bm != null) { containEmoji = true; if (spannable == null) { if (!(text instanceof Spannable)) { spannable = new SpannableString(text); } else { spannable = (Spannable)text; } } EmojiReplacementSpan emojiReplaceSpan = new EmojiReplacementSpan(bm); spannable.setSpan(emojiReplaceSpan, i, i+1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } TextUtils.recycle(tmp); i++; } }