【问题标题】:AsyncTask and getInstalledPackages() failAsyncTask 和 getInstalledPackages() 失败
【发布时间】:2023-03-25 02:10:01
【问题描述】:

我真的不明白发生了什么,也许你可以给我一个想法。我使用 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);

有时 packages 包含所有已安装的应用程序有时是空的。例如,在 3 次中,第 3 次是空的。将此代码从 AsyncTask 中取出并将其放在 getListData() 上,每次都可以正常工作,没有任何问题。问题是我有点冻结,因为操作不在后台线程上。 那么与 AsyncTask 有什么关系呢?我是不是做错了什么?

【问题讨论】:

    标签: android package-managers


    【解决方案1】:

    基本上,这个异常在 Android 5.1 上已修复(或者至少我在某处读到过),但对于 5.1 之前的版本,您需要自己做一些事情。

    您可以避免出现此异常崩溃并使用 shell 获取已安装应用程序的完整列表,如下所示:

    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;
        }
    

    【讨论】:

      【解决方案2】:

      查看一个类似的SO问题here,CommonsWare认为这个方法需要在UI线程中涉及,据我所知,这是唯一合理的解释。

      【讨论】:

      【解决方案3】:

      我提出了不同的解释:

      IPC 缓冲区已满,在较早的 Android 版本(子 API15)上只返回一个空列表,而在较新的 Android 版本上抛出 TransactionTooLargeException。

      另见: PackageManager.getInstalledPackages() returns empty list

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-30
        • 1970-01-01
        • 1970-01-01
        • 2016-06-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多