AsyncTask и getInstalledPackages() не работают

Я действительно не понимаю, что происходит, и, возможно, вы можете дать мне идею. Я использую getInstalledPackages() для получения списка всех установленных пользователем приложений и их разрешений. Вот как я это делаю:

private PackageManager pm;

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        pm = getPackageManager();
        getListData();
}

 private void getListData()
    {

        backTask = new BackTask();
        backTask.execute();
    }

 protected class BackTask extends AsyncTask<Context, String, ArrayList<App>>
    {
....
        @Override
        protected ArrayList<App> doInBackground(Context... param) 
        {

                try {

                      //get a list of installed apps.
                          List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS);

                            for (PackageInfo packageInfo : packages) {
                                ApplicationInfo application = packageInfo.applicationInfo;
....
}

Мне нужно обновить список, отображаемый на основе взаимодействия с пользователем. Проблема появляется в этой строке в AsyncTask:

List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS);

Иногда пакеты содержат все установленные приложения, иногда ПУСТОЙ. Скажем, например, из 3 раз, 3-й раз пустой. Вынос этого кода из AsyncTask и добавление его в getListData() работает каждый раз без каких-либо проблем. Проблема в том, что я немного зависаю, потому что операция не в обратном потоке. Так в чем же дело с AsyncTask? Я делаю что-то неправильно ?


person Alin    schedule 10.11.2011    source источник


Ответы (3)


Посмотрите аналогичный вопрос SO здесь, CommonsWare утверждает, что этот метод должен быть задействован в UI thread, Насколько я понимаю, это единственное разумное объяснение.

person yorkw    schedule 11.11.2011
comment
Пожалуйста, проверьте мой другой ответ, я не думаю, что его нужно выполнять в потоке пользовательского интерфейса, см.: stackoverflow.com/questions/3455781/ - person darken; 03.10.2014

В принципе, это исключение было исправлено на Android 5.1 (по крайней мере, я так где-то читал), но для pre-5.1 нужно что-то делать самостоятельно.

Вы можете избежать сбоя этого исключения и получить полный список установленных приложений с помощью оболочки, как я показал здесь:

https://code.google.com/p/android/issues/detail?id=172058

Вот код:

  public static List<PackageInfo> getInstalledPackages(Context context,int flags)
    {
    final PackageManager pm=context.getPackageManager();
    //if it's Android 5.1, no need to do any special work
    if(VERSION.SDK_INT>=VERSION_CODES.LOLLIPOP_MR1)
      return pm.getInstalledPackages(flags);
    //else, protect against exception, and use a fallback if needed:
    try
      {
      return pm.getInstalledPackages(flags);
      }
    catch(Exception ignored)
      {
      //we don't care why it didn't succeed. We'll do it using an alternative way instead
      }
    // use fallback:
    Process process;
    List<PackageInfo> result=new ArrayList<>();
    BufferedReader bufferedReader=null;
    try
      {
      process=Runtime.getRuntime().exec("pm list packages");
      bufferedReader=new BufferedReader(new InputStreamReader(process.getInputStream()));
      String line;
      while((line=bufferedReader.readLine())!=null)
        {
        final String packageName=line.substring(line.indexOf(':')+1);
        final PackageInfo packageInfo=pm.getPackageInfo(packageName,flags);
        result.add(packageInfo);
        }
      process.waitFor();
      }
    catch(Exception e)
      {
      e.printStackTrace();
      }
    finally
      {
      if(bufferedReader!=null)
        try
          {
          bufferedReader.close();
          }
        catch(IOException e)
          {
          e.printStackTrace();
          }
      }
    return result;
    }
person android developer    schedule 17.09.2015

Я предлагаю другое объяснение:

Буфер IPC заполняется, и в более ранних версиях Android (sub API15) возвращается только пустой список, а в более новых версиях Android создается исключение TransactionTooLargeException.

Также см.: PackageManager.getInstalledPackages() возвращает пустой список

person darken    schedule 03.10.2014