简体   繁体   English

Android-获取已安装应用程序列表的时间过长

[英]Android - Getting list of installed apps takes too long

First attempt: 第一次尝试:

    Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
    mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);            
    Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
    pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
    this.startActivityForResult(pickIntent, MoreIconsConstants.REQUEST_PICK_APPLICATION)

Average time needed-->8-10 second 平均所需时间-> 8-10秒

Second attempt I tried getting the list of apps in a list programmatically and showing the list my self in a dialog.-----> about 4 seconds...Faster but still slow. 第二次尝试是我尝试以编程方式在列表中获取应用程序列表,并在对话框中显示该列表。----->大约4秒钟...较快,但仍然很慢。

Third attempt: I store the list in my preferences file so that in the future I load that list instantly...meanwhile getting the current list in the background and if there are differences update the list being shown to the user----Also about 4 seconds. 第三次尝试:将列表存储在我的首选项文件中,以便将来我可以立即加载该列表...同时在后台获取当前列表,如果有差异,则更新显示给用户的列表----也大约4秒。

This is where it gets weird. 这是奇怪的地方。 Using Log statements i measured th exact time each method needs. 使用Log语句,我测量了每种方法所需的确切时间。 If I load the list from the prefferences first and then load it by querying the package manager I takes again 4 seconds for the preferences method and 0.5 second for the querying method 如果我先从偏好中加载列表,然后通过查询程序包管理器加载它,则我再花4秒钟来选择首选项方法,再花0.5秒来获取查询方法。

If i load the list querying the package manager first and then load it from preferences it takes about 4 seconds for the querying method and 0.5 second for the preference method 如果我先加载列表以查询程序包管理器,然后从首选项中加载它,则查询方法大约需要4秒钟,而首选项方法则需要0.5秒

So no matter what I do the first method takes a lot of time and the second is executed right away. 因此,无论我做什么,第一种方法都会花费很多时间,而第二种方法会立即执行。

Is there an explanation for this or some other way to load this list faster? 是否有关于此或其他更快加载此列表的方法的说明?

I quote my code for both methods 我引用两种方法的代码

loading list quering the package manager 正在加载列表,查询软件包管理器

private class AppAsyncCaller extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute() { super.onPreExecute();  }
    @Override
    protected Void doInBackground(Void... params) {
        ArrayList<AppItem> allAppsInDevice2 = new ArrayList<AppItem>();
        long timeStart=System.currentTimeMillis();
        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER);
        List<ResolveInfo> packages=pm.queryIntentActivities(mainIntent, 0);
        for(int i=0;i<packages.size();i++){
            try{  
                String packageName=packages.get(i).activityInfo.packageName;
                AppItem item=getAppItem(packageName,false);
                if(item!=null){allAppsInDevice2.add(item);}
            }catch(Exception e){}
        }
        Log.w(Long.toString(System.currentTimeMillis()-timeStart),"duration using async caller");
        return null;
    }
    @Override
    protected void onPostExecute(Void result) {  super.onPostExecute(result);  }

 }

loading list from preferences method: 从首选项方法加载列表:

private class AppPrefsAsyncCaller extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute() { super.onPreExecute();  }
    @Override
    protected Void doInBackground(Void... params) {
        long timeStart=System.currentTimeMillis();
        String allAppsListString = prefs.getString("allAppsListString", "");
        String[] tab=allAppsListString.split("_APPAPPAPP_");
        allAppsInDevice.clear();
        boolean updateAllApps=false;
        for(String s:tab){
            if(!s.equals("") && !s.equals(" ")){
                AppItem item=getAppItem(s,false); 
                if(item!=null){ allAppsInDevice.add(item); }
            }
        }

        Log.w(Long.toString(System.currentTimeMillis()-timeStart),"duration apo pref");


        return null;
    }
    @Override
    protected void onPostExecute(Void result) {  super.onPostExecute(result);  }

 }




public AppItem getAppItem(String packageName,boolean getIcon){
        AppItem item=new AppItem();
        item.packageName=packageName;
        ApplicationInfo ai=null;
        try {  ai = pm.getApplicationInfo( packageName, 0); } 
        catch (final NameNotFoundException e) {return null; }
        final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
        item.appName=applicationName;
        Intent intent = pm.getLaunchIntentForPackage(packageName);
        if(getIcon){
        Drawable icon=null;
            if (intent != null) {  try { icon = pm.getActivityIcon(intent); } catch (NameNotFoundException e) {} } 
            item.icon=icon;
        }

        return item;
    }
public class AppItem{
    String packageName;
    String appName;
    Drawable icon;
}

You can do it with android PackageManager. 您可以使用android PackageManager做到这一点。

Below is a small code snippet. 以下是一个小代码段。

final PackageManager pm = getPackageManager();
//get a list of installed apps.
List<ApplicationInfo> packages =  pm.getInstalledApplications(PackageManager.GET_META_DATA);

for (ApplicationInfo packageInfo : packages) {
    Log.d(TAG, "Installed package :" + packageInfo.packageName);
    Log.d(TAG, "Apk file path:" + packageInfo.sourceDir);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM