Fix ConcurrentModificationException in SliceBackgroundWorker
- Two different threads could call SliceBackgroundWorker.getInstance() at the same time and caused ConcurrentModificationException - Add a new API overloading getInstance for each slice to get a nullable worker since there is no result data then - Only slice provider can create a new worker instance in main thread Test: robotest Change-Id: I560529bb6034ec22263418adeb7f3ccebf879196 Fixes: 121043385
This commit is contained in:
@@ -82,8 +82,8 @@ public class BatteryFixSlice implements CustomSliceable {
|
||||
return buildBatteryGoodSlice(sliceBuilder, true);
|
||||
}
|
||||
|
||||
final List<BatteryTip> batteryTips = SliceBackgroundWorker.getInstance(mContext,
|
||||
this).getResults();
|
||||
final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(getUri());
|
||||
final List<BatteryTip> batteryTips = worker != null ? worker.getResults() : null;
|
||||
|
||||
if (batteryTips == null) {
|
||||
// Because we need wait slice background worker return data
|
||||
|
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.slices;
|
||||
|
||||
import android.annotation.MainThread;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.ArrayMap;
|
||||
@@ -58,20 +59,29 @@ public abstract class SliceBackgroundWorker<E> implements Closeable {
|
||||
mUri = uri;
|
||||
}
|
||||
|
||||
public Uri getUri() {
|
||||
protected Uri getUri() {
|
||||
return mUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link Uri}
|
||||
* if exists
|
||||
*/
|
||||
@Nullable
|
||||
public static SliceBackgroundWorker getInstance(Uri uri) {
|
||||
return LIVE_WORKERS.get(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link
|
||||
* CustomSliceable}
|
||||
*/
|
||||
public static SliceBackgroundWorker getInstance(Context context, CustomSliceable sliceable) {
|
||||
static SliceBackgroundWorker getInstance(Context context, CustomSliceable sliceable) {
|
||||
final Uri uri = sliceable.getUri();
|
||||
SliceBackgroundWorker worker = getInstance(uri);
|
||||
if (worker == null) {
|
||||
final Class<? extends SliceBackgroundWorker> workerClass =
|
||||
sliceable.getBackgroundWorkerClass();
|
||||
SliceBackgroundWorker worker = LIVE_WORKERS.get(uri);
|
||||
if (worker == null) {
|
||||
worker = createInstance(context, uri, workerClass);
|
||||
LIVE_WORKERS.put(uri, worker);
|
||||
}
|
||||
|
@@ -105,8 +105,8 @@ public class WifiSlice implements CustomSliceable {
|
||||
return listBuilder.build();
|
||||
}
|
||||
|
||||
final List<AccessPoint> results =
|
||||
SliceBackgroundWorker.getInstance(mContext, this).getResults();
|
||||
final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(getUri());
|
||||
final List<AccessPoint> results = worker != null ? worker.getResults() : null;
|
||||
|
||||
// Need a loading text when results are not ready.
|
||||
boolean needLoadingRow = results == null;
|
||||
|
Reference in New Issue
Block a user