1

私のテストでは、ActivityManagerService の updateOomAdjLocked() で次の例外が表示されます。

// java.lang.IndexOutOfBoundsException: Invalid index 27, size is 27
//  at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
//  at java.util.ArrayList.get(ArrayList.java:304)
//  at com.android.server.am.ActivityManagerService.updateOomAdjLocked(ActivityManagerService.java:13880)
//  at com.android.server.am.ActivityManagerService.updateLruProcessLocked(ActivityManagerService.java:1904)
//  at com.android.server.am.ActivityStack.realStartActivityLocked(ActivityStack.java:647)
//  at com.android.server.am.ActivityStack.startSpecificActivityLocked(ActivityStack.java:803)

問題のあるコードは次のようです (Android 4.2.2 r1.2 の行 13850):

final ArrayList<ProcessRecord> mLruProcesses
    = new ArrayList<ProcessRecord>();
{...}

final void updateOomAdjLocked() {
    {...}
    final int N = mLruProcesses.size();
    for (i=0; i<N; i++) {
        ProcessRecord app = mLruProcesses.get(i);
        {...}
    }

ループ内で mLruProcesses.remove が呼び出された場合、i=N の mLruProcesses.get(i) が存在しないインデックスにアクセスし、例外がトリガーされました。

これまでのところ、Android サービスについてほとんど知らないので、私の質問は、おそらく操作の一部をスレッドセーフにすることによって、このコードを再入力可能にする必要があるかどうかです。

4

1 に答える 1

2

のサイズがまだループ内でmLruProcess.size()等しいことを確認できます。N

final boolean updateOomAdjLocked() {
   {...}
   final int N = mLruProcess.size();
   for(int i = 0; i < N; i++) {
       if(N != mLruProcess.size()) {
           //Do something accordingly, in this case return false
           return false;
       }

       ProcessRecord app = mLruProcess.get(i);
       {...}
   }

   {...}       

   return true;
}

この関数を呼び出す場所にいくつかのロジックを追加します。false が返された場合は、関数を再度呼び出すようにしてください。mLruProcessそれ以外の場合は、ブロックを入れることができSynchronizedます。つまり、1 つの同時スレッドでのみアクセスできます。キーワードはブロッキングです。Synchronizedつまり、別のスレッドでアクセスしようとするコードはmLruProcess、現在のスレッドが mLruProcess で完了するまでブロックされます。

ブロッキング コードを使用したくない、または使用できない場合は、次のように を使用してみてAtomicBooleanください。

Java で同期を使用する場合

AtomicBooleanに格納されているオブジェクトを変更するたびに を設定し、 に格納されているオブジェクトにアクセスする必要があるすべての場所をmLruProcess確認します。AtomicBooleanmLruProcess

于 2013-07-09T18:25:55.643 に答える