我正在将 Actionbarsherlock 添加到我的应用程序以更新 Android 2.2/2.3 用户的 UI。ABS 运行良好,但我发现旧设备存在问题,即重启后打开应用程序后 ListView 会挂起。该应用程序列出了所有具有 Internet 权限的应用程序,然后添加了一些特殊应用程序(该应用程序是防火墙),并且在尝试显示信息时会挂起。
最初,代码在使用标准数组构建列表后缓存了应用程序。我想将应用程序从缓存中移开,因为我认为这是一些挂起的重要原因。所以我一直在将所有东西从数组转移到 ArrayLists 以便于使用。我遇到了一个 IndexOutofBounds 但纠正了那个但这个完全难倒我。这是我获取应用程序和排序代码的代码。
任何帮助将不胜感激,如果需要任何其他代码,请询问!提前致谢!
应用列表代码:
int count = 0;
try {
final PackageManager pkgmanager = ctx.getPackageManager();
final List<ApplicationInfo> installed = pkgmanager
.getInstalledApplications(PackageManager.GET_META_DATA);
final HashMap<Integer, DroidApp> map = new HashMap<Integer, DroidApp>();
final Editor edit = prefs.edit();
boolean changed = false;
String name = null;
String cachekey = null;
final String cacheLabel = "cache.label.";
DroidApp app = null;
for (final ApplicationInfo apinfo : installed) {
count = count + 1;
if(applist != null){
applist.doProgress(count);
}
boolean firstseen = false;
app = map.get(apinfo.uid);
// filter applications which are not allowed to access the
// Internet
if (app == null
&& PackageManager.PERMISSION_GRANTED != pkgmanager
.checkPermission(Manifest.permission.INTERNET,
apinfo.packageName)) {
continue;
}
// try to get the application label from our cache -
// getApplicationLabel() is horribly slow!!!!
cachekey = cacheLabel + apinfo.packageName;
name = prefs.getString(cachekey, "");
if (name.length() == 0) {
// get label and put on cache
name = pkgmanager.getApplicationLabel(apinfo).toString();
edit.putString(cachekey, name);
changed = true;
firstseen = true;
}
if (app == null) {
app = new DroidApp();
app.uid = apinfo.uid;
app.names = new ArrayList<String>();
app.names.add(name);
app.appinfo = apinfo;
map.put(apinfo.uid, app);
} else {
app.names.add(name);
}
app.firstseen = firstseen;
// check if this application is selected
if (!app.selected_wifi
&& Arrays.binarySearch(selected_wifi, app.uid) >= 0) {
app.selected_wifi = true;
}
if (!app.selected_3g
&& Arrays.binarySearch(selected_3g, app.uid) >= 0) {
app.selected_3g = true;
}
if (!app.selected_roaming
&& Arrays.binarySearch(selected_roaming, app.uid) >= 0) {
app.selected_roaming = true;
}
if (!app.selected_vpn
&& Arrays.binarySearch(selected_vpn, app.uid) >= 0) {
app.selected_vpn = true;
}
}
if (changed) {
edit.commit();
}
/* add special applications to the list */
List<DroidApp> special = new ArrayList<DroidApp>();
special.add(new DroidApp(
SPECIAL_UID_ANY,
"(Any application) - Same as selecting all applications", false, false, false, false));
special.add(new DroidApp(SPECIAL_UID_KERNEL, "(Kernel) - Linux kernel", false, false, false, false));
special.add(new DroidApp(android.os.Process.getUidForName("root"), "(root) - Applications running as root", false, false, false, false));
special.add(new DroidApp(android.os.Process.getUidForName("media"),"Media server", false, false, false, false));
special.add(new DroidApp(android.os.Process.getUidForName("vpn"), "VPN networking", false, false, false, false));
special.add(new DroidApp(android.os.Process.getUidForName("shell"), "Linux shell", false, false, false, false));
special.add(new DroidApp(android.os.Process.getUidForName("gps"), "GPS", false, false, false, false));
for (int i = 0; i < special.size(); i++) {
app = special.get(i);
if (app.uid != -1 && !map.containsKey(app.uid)) {
// check if this application is allowed
if (Arrays.binarySearch(selected_wifi, app.uid) >= 0) {
app.selected_wifi = true;
}
if (Arrays.binarySearch(selected_3g, app.uid) >= 0) {
app.selected_3g = true;
}
if (Arrays.binarySearch(selected_roaming, app.uid) >= 0) {
app.selected_roaming = true;
}
if (Arrays.binarySearch(selected_vpn, app.uid) >= 0) {
app.selected_vpn = true;
}
map.put(app.uid, app);
}
}
/* convert the map into an array */
applications = new ArrayList<DroidApp>(map.values());
return applications;
排序代码:
class ApplicationSort implements Comparator<DroidApp> {
@Override
public int compare(DroidApp o1, DroidApp o2) {
if (o1.firstseen != o2.firstseen) {
return (o1.firstseen ? -1 : 1);
}
boolean o1_selected;
boolean o2_selected;
boolean vpnenabled = getApplicationContext()
.getSharedPreferences(Api.PREFS_NAME, 0).getBoolean(
Api.PREF_VPNENABLED, false);
boolean roamenabled = getApplicationContext()
.getSharedPreferences(Api.PREFS_NAME, 0).getBoolean(
Api.PREF_ROAMENABLED, false);
if (vpnenabled && !roamenabled) {
o1_selected = o1.selected_3g || o1.selected_wifi
|| o1.selected_vpn;
o2_selected = o2.selected_3g || o2.selected_wifi
|| o2.selected_vpn;
if (o1_selected == o2_selected) {
return String.CASE_INSENSITIVE_ORDER.compare(
o1.names.get(0).toString(), o2.names.get(0).toString());
}
if (o1_selected)
return -1;
}
if (roamenabled && !vpnenabled) {
o1_selected = o1.selected_3g || o1.selected_wifi
|| o1.selected_roaming;
o2_selected = o2.selected_3g || o2.selected_wifi
|| o2.selected_roaming;
if (o1_selected == o2_selected) {
return String.CASE_INSENSITIVE_ORDER.compare(
o1.names.get(0).toString(), o2.names.get(0).toString());
}
if (o1_selected)
return -1;
}
if (roamenabled && vpnenabled) {
o1_selected = o1.selected_3g || o1.selected_wifi
|| o1.selected_roaming || o1.selected_vpn;
o2_selected = o2.selected_3g || o2.selected_wifi
|| o2.selected_roaming || o2.selected_vpn;
if (o1_selected == o2_selected) {
return String.CASE_INSENSITIVE_ORDER.compare(
o1.names.get(0).toString(), o2.names.get(0).toString());
}
if (o1_selected)
return -1;
}
if (!roamenabled && !vpnenabled) {
o1_selected = o1.selected_3g || o1.selected_wifi;
o2_selected = o2.selected_3g || o2.selected_wifi;
if (o1_selected == o2_selected) {
return String.CASE_INSENSITIVE_ORDER.compare(
o1.names.get(0).toString(), o2.names.get(0).toString());
}
if (o1_selected)
return -1;
}
return 1;
}
}
调用排序类的 ListView 代码
private void createListView(final String searching) {
this.dirty = false;
boolean results = false;
List<DroidApp> namesearch = new ArrayList<DroidApp>();
final List<DroidApp> appnames = Api.getApps(this, null);
if (searching != null && searching.length() > 1) {
for (DroidApp app : appnames) {
for (String str : app.names) {
if (str.contains(searching.toLowerCase())
|| str.toLowerCase().contains(
searching.toLowerCase())) {
namesearch.add(app);
results = true;
}
}
}
}
final List<DroidApp> apps = results ? namesearch
: searching.equals("") ? appnames
: new ArrayList<Api.DroidApp>();
// Sort applications - selected first, then alphabetically
Collections.sort(apps, new ApplicationSort());