0

我正在将 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());
4

1 回答 1

0

我看不到是什么DroidApp,但您使用的是这样的东西:

o1.names.get(0) and o2.names.get(0)

有没有可能有些人的DroidApps名单是空的?

于 2013-06-04T18:49:23.573 回答