我遇到以下异常:
java.lang.ArrayIndexOutOfBoundsException:length = 6;索引= 6
03-26 10:52:09.729:E / AndroidRuntime(19956):at java.util.Collections.sort(Collections.java:1909)
03-26 10:52:09.729:E / AndroidRuntime(19956):位于com.mycompany.widget.AlertItemRemoteViewsService $ a.onDataSetChanged(SourceFile:53)
03-26 10:52:09.729:E / AndroidRuntime(19956):位于android.widget.RemoteViewsService $ RemoteViewsFactoryAdapter.onDataSetChanged(RemoteViewsService.java:142)
03-26 10:52:09.729:E / AndroidRuntime(19956):在com.android.internal.widget.IRemoteViewsFactory $ Stub.onTransact(IRemoteViewsFactory.java:49)
03-26 10:52:09.729:E / AndroidRuntime(19956):at
这不容易重现。
发生这种情况的代码如下:
public class AlertItemRemoteViewsService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new AlertItemRemoteViewsFactory(this.getApplicationContext(), intent);
}
class AlertItemRemoteViewsFactory implements RemoteViewsFactory {
private List<AlertItem> mItems;
private Context mContext;
private final Intent mIntent;
public AlertItemRemoteViewsFactory(final Context context, final Intent intent) {
mContext = context;
mItems = new LinkedList<>();
mIntent = intent;
}
@Override
public void onCreate() {
}
@Override
public void onDataSetChanged() {
mItems.clear();
if (new EulaRequirement().isAccepted(mContext)) {
List<AlertItem> items = AlertManager.getInstance().getAllAlerts(mContext);
for (AlertItem item : items) {
if (!item.getShouldBeIgnored()) {
mItems.add(item);
}
}
Collections.sort(mItems, new AlertsListAdapter.ItemComparatorByAlertCategory(mContext));
}
}
@Override
public void onDestroy() {
mItems = null;
mContext = null;
}
@Override
public int getCount() {
return mItems.size();
}
...
}
它发生在“ Collections.sort”行上。从RemoteViewsFactory的文档开始: “注意:昂贵的任务可以在此方法中安全地同步执行。在此期间,旧数据将显示在小部件内。”
因此,该调用似乎不需要任何同步,那么,这种异常怎么会发生,有什么想法?
更新:这是比较器:
public static class ItemComparatorByAlertCategory implements Comparator<AlertItem>, Serializable {
private static final long serialVersionUID = 1L;
private final Context mContext;
public ItemComparatorByAlertCategory(final Context context) {
mContext = context;
}
@Override
public int compare(final AlertItem alertItem1, final AlertItem alertItem2) {
int result = alertItem1.getEAlertItem().getAlertCategory().compareTo(alertItem2.getEAlertItem().getAlertCategory());
// If they are not from the same category we return the result, otherwise we compare also the icons (the source of the alert, like Scanner, L&T and so on.)
if (result != 0) {
return result;
} else {
return Integer.compare(
alertItem1.getEAlertItem().getHandlerFactory().newInstance(mContext).getDrawableId(),
alertItem2.getEAlertItem().getHandlerFactory().newInstance(mContext).getDrawableId());
}
}
}