Android: получение списка установленных приложений занимает слишком много времени

Первая попытка:

    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)

Среднее необходимое время --> 8-10 секунд

Вторая попытка. Я попытался программно получить список приложений в списке и показать список в диалоговом окне. -----> около 4 секунд ... Быстрее, но все еще медленно.

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

Вот где это становится странным. Используя операторы журнала, я измерил точное время, необходимое каждому методу. Если я сначала загружу список из настроек, а затем загружу его, запросив диспетчер пакетов, я снова возьму 4 секунды для метода настроек и 0,5 секунды для метода запроса.

Если я сначала загружаю список, запрашивая диспетчер пакетов, а затем загружаю его из настроек, это занимает около 4 секунд для метода запроса и 0,5 секунды для метода предпочтений.

Поэтому что бы я ни делал, первый метод занимает много времени, а второй выполняется сразу.

Есть ли объяснение этому или какой-то другой способ ускорить загрузку этого списка?

Я цитирую свой код для обоих методов

список загрузки, запрашивающий менеджер пакетов

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

 }

список загрузки из метода настроек:

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

person Anonymous    schedule 08.10.2014    source источник
comment
Используйте Traceview и точно определите, в чем заключается ваша проблема.   -  person CommonsWare    schedule 09.10.2014


Ответы (1)


Вы можете сделать это с помощью Android PackageManager.

Ниже приведен небольшой фрагмент кода.

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);
}
person Sagar Waghmare    schedule 08.10.2014