StringBuilder中的奇怪ANR

时间:2012-08-04 08:22:12

标签: android string android-anr-dialog

来自Android Developer Console的

ANR堆栈:

DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
"main" prio=5 tid=1 SUSPENDED
  | group="main" sCount=1 dsCount=0 obj=0x40022198 self=0xcec8
  | sysTid=15809 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=-1345006496
  | schedstat=( 105169616659 16803131154 25724 )
  at java.lang.String._getChars(String.java:~1041)
  at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:89)
  at java.lang.StringBuilder.<init>(StringBuilder.java:96)
  at org.nkuznetsov.onlineradio.FavoriteList.save(FavoriteList.java:37)
  at org.nkuznetsov.onlineradio.FavoriteList.add(FavoriteList.java:60)
  at org.nkuznetsov.onlineradio.RadioActivity$OnFavoriteChangeListener.onCheckedChanged(RadioActivity.java:289)
  at android.widget.CompoundButton.setChecked(CompoundButton.java:124)
  at android.widget.CompoundButton.toggle(CompoundButton.java:86)
  at android.widget.CompoundButton.performClick(CompoundButton.java:98)
  at android.view.View$PerformClick.run(View.java:9080)
  at android.os.Handler.handleCallback(Handler.java:587)
  at android.os.Handler.dispatchMessage(Handler.java:92)
  at android.os.Looper.loop(Looper.java:130)
  at android.app.ActivityThread.main(ActivityThread.java:3687)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:507)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
  at dalvik.system.NativeStart.main(Native Method)

"Binder Thread #3" prio=5 tid=9 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x40526f60 self=0x194808
  | sysTid=15817 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1788936
  | schedstat=( 2014164 15899659 17 )
  at dalvik.system.NativeStart.run(Native Method)

"AsyncTask #1" prio=5 tid=8 WAIT
  | group="main" sCount=1 dsCount=0 obj=0x40524388 self=0x19d380
  | sysTid=15816 nice=10 sched=0/0 cgrp=[fopen-error:2] handle=1693616
  | schedstat=( 1090911877 313018788 393 )
  at java.lang.Object.wait(Native Method)
  - waiting on <0x40524560> (a java.lang.VMThread)
  at java.lang.Thread.parkFor(Thread.java:1424)
  at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
  at sun.misc.Unsafe.park(Unsafe.java:337)
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2016)
  at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:411)
  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1021)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
  at java.lang.Thread.run(Thread.java:1019)

"Binder Thread #2" prio=5 tid=7 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x405150e0 self=0x15eed8
  | sysTid=15815 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1413168
  | schedstat=( 2929685 26489259 22 )
  at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #1" prio=5 tid=6 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x40514aa8 self=0x16bad8
  | sysTid=15814 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1159936
  | schedstat=( 5920410 23956299 25 )
  at dalvik.system.NativeStart.run(Native Method)

"Compiler" daemon prio=5 tid=5 VMWAIT
  | group="system" sCount=1 dsCount=0 obj=0x405110a0 self=0x16b9a0
  | sysTid=15813 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1239400
  | schedstat=( 207977297 25329589 821 )
  at dalvik.system.NativeStart.run(Native Method)

"Signal Catcher" daemon prio=5 tid=4 RUNNABLE
  | group="system" sCount=0 dsCount=0 obj=0x40510fe0 self=0x12e7a8
  | sysTid=15812 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1238888
  | schedstat=( 5798340 8666992 14 )
  at dalvik.system.NativeStart.run(Native Method)

"GC" daemon prio=5 tid=3 VMWAIT
  | group="system" sCount=1 dsCount=0 obj=0x40510f38 self=0x178360
  | sysTid=15811 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1413104
  | schedstat=( 139343257 133178717 75 )
  at dalvik.system.NativeStart.run(Native Method)

"HeapWorker" daemon prio=5 tid=2 SUSPENDED
  | group="system" sCount=1 dsCount=0 obj=0x40510e80 self=0x178228
  | sysTid=15810 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=1160864
  | schedstat=( 612121568 1730712888 15455 )
  at dalvik.system.NativeStart.run(Native Method)

据我所知,org.nkuznetsov.onlineradio.FavoriteList.save(FavoriteList.java:37)方法主线程中存在问题。

在FavoriteList.save()中,我只是从字符串集合中串联字符串并将ti写入共享首选项。

FavoriteList类的来源是:https://code.google.com/p/android-online-radio/source/browse/trunk/src/org/nkuznetsov/onlineradio/FavoriteList.java

为什么ANR出现一段时间?

1 个答案:

答案 0 :(得分:1)

如果它给你一个ANR并且这是一个你不等待完成的方法在另一个线程上执行:

 private static void save(final Vector<String> favorites)
    {

         new Thread()
            public void run(){
              String tmpFav = new String();

              if (favorites.size() > 0)
              {
                    tmpFav = String.valueOf(favorites.get(0));

                    for (int i = 1; i < favorites.size(); i++)
                    {
                            tmpFav += FAVORITES_SEPARATOR;
                            tmpFav += favorites.get(i);
                    }
              }

              SharedPreferences.Editor editor = preferences.edit();

              if (tmpFav.equals(new String())) editor.remove(FAVORITES_KEY);
              else editor.putString(FAVORITES_KEY, tmpFav);

              editor.commit();
           }
        }.start();
    }

您只需记住下次访问其他方法时可能尚未完成保存。

如果它是一个字符串向量,则不需要请求字符串值:

    tmpFav = favorites.get(0);

同样检查String是否为空更加清晰:

    if ("".equals(tmpFav)) editor.remove(FAVORITES_KEY)

我也会使用StringBuilder而不是连接。

    StringBuilder b = new StringBuilder();
    b.append(FAVOURITES_SEPARATOR);
    b.append(favorites.get(i);
    String tmpFav = b.toString();

如果您选择线程选项时要小心,您可能需要查看Java Synchonized methods