3

I am getting a list of installed non-system apps to show to the user and I am using this to do so:

    private class getApplications extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        // perform long running operation operation

        for (i = 0; i < list.size(); i++) {

            if ((list.get(i).flags & ApplicationInfo.FLAG_SYSTEM) != 1) {

                label = (String) pm.getApplicationLabel(list.get(i));

                Log.w("Installed Applications", list.get(i).packageName.toString());

            }
        }

        return label;
    }

    @Override
    protected void onPostExecute(String result) {

        txtApplications.append(label);

        if (i!=list.size()-1) {

             txtApplications.append(", ");

           }
    }

    @Override
    protected void onPreExecute() {

        pm = getPackageManager();

        list = pm.getInstalledApplications(PackageManager.GET_META_DATA);

    }

};

This works fine as long as it is on the main UI, but it causes the app to lag when loading. I have read these three questions: AsyncTask and getInstalledPackages() fail, PackageManager.getInstalledPackages() returns empty list, Showing ProgressDialog during UI Thread operation in Android and I think understand what they are saying to do, but I am having problems understanding how to make it work. I know the delay is coming from List list = pm.getInstalledApplications(PackageManager.GET_META_DATA); and I know getInstalledApplications(PackageManager.GET_META_DATA); has to be run on the main UI or the app force closes. How do I go about keeping getInstalledApplications(PackageManager.GET_META_DATA); where it needs to be, but populate the list in the background so the app doesn't appear to be frozen? Thank you in advance for any help.

Updated code to show Asynctask. I got the code to run in an Async, but now it only shows one result in the textview instead of the list. I know it has to be some thing simple that I am missing to make it work.

Community
  • 1
  • 1
Jasonwilliams10
  • 292
  • 1
  • 4
  • 17
  • If `pm.getInstalledApplications()` needs to be on the UI Thread, then as one of the answers suggested, put it in the AsyncTask's `onPreExecute()` method. Then do your package parsing (that big loop) in `doInBackground()` - the list *should* be available. – A--C Jan 09 '13 at 02:55
  • @ A-C, Thank you, that helped me get it straight. I am having one other problem though. Now that is in an Asynctask, it only shows one result in the textview instead of the list. The Log is still showing all the results though. – Jasonwilliams10 Jan 10 '13 at 16:05
  • I don't think it needs to be executed on the UI thread, see here: http://stackoverflow.com/questions/3455781/packagemanager-getinstalledpackages-returns-empty-list/26172008#26172008 – darken Oct 03 '14 at 01:32

1 Answers1

2

I'd modify your doInBackground() so it looks like this:

@Override
protected String doInBackground(String... params) {
    // perform long running operation operation

    for (i = 0; i < list.size(); i++) {

        if ((list.get(i).flags & ApplicationInfo.FLAG_SYSTEM) != 1) {

            //add all the application names to the same String.
            label +=", " + (String) pm.getApplicationLabel(list.get(i));


            Log.w("Installed Applications", list.get(i).packageName.toString());

        }
    }

    return label;
}

And so, I'd say that your onPostExecute() needs to look just like:

    @Override
    protected void onPostExecute(String result) {

        txtApplications.append(label);

           }
    }

Since now, label contains all the application names (because of the label += ...);

A--C
  • 36,351
  • 10
  • 106
  • 92