从 ListView 中的 apk 文件加载许多图标
Posted
技术标签:
【中文标题】从 ListView 中的 apk 文件加载许多图标【英文标题】:Load many icon from apk files in ListView 【发布时间】:2018-05-15 19:06:44 【问题描述】:我正在尝试将许多 apk 文件中的图标加载到列表视图中。
这是我的适配器类
public class Apk_Adapter extends BaseAdapter
private ArrayList<File> apk;
private my_activity activity;
public static ArrayList<Integer> selection=new ArrayList<>();
public Adapter (my_activity activity, ArrayList<File> list)
super();
this.apk = list;
this.activity = activity;
selection.clear();
@Override
public int getCount()
return apk.size();
@Override
public String getItem(int position)
return String.valueOf(apk.get(position));
@Override
public long getItemId(int position)
return 0;
public class ViewHolder
public ImageView apk_img;
public TextView name;
public TextView size;
public CheckBox tick;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
final ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if (convertView == null)
view = new ViewHolder();
convertView = inflator.inflate(R.layout.apk_adapter, null);
view.apk_img = (ImageView) convertView.findViewById(R.id.img);
view.size = (TextView) convertView.findViewById(R.id.size);
view.name= (TextView) convertView.findViewById(R.id.name);
view.tick= (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(view);
else
view = (ViewHolder) convertView.getTag();
view.tick.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
//DO SOMETHING
);
view.name.setText(apk.get(position).getName());
view.size.setText(get_size(apk.get(position).length()));
ByteArrayOutputStream stream = new ByteArrayOutputStream();
get_apk_image(apk.get(position),activity.getApplication()).compress(Bitmap.CompressFormat.PNG, 100, stream);
Glide.with(activity.getApplicationContext())
.load(stream.toByteArray())
.placeholder(R.drawable.apk)
.centerCrop()
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.thumbnail(0.5f)
.into(view.apk_img);
if (selection.contains(new Integer(position)))
view.tick.setChecked(true);
else
view.tick.setChecked(false);
return convertView;
public Bitmap get_apk_image(File file,Context context)
String filePath = file.getPath();
PackageInfo packageInfo = context.getPackageManager().getPackageArchiveInfo(filePath, PackageManager.GET_ACTIVITIES);
if(packageInfo != null)
ApplicationInfo appInfo = packageInfo.applicationInfo;
if (Build.VERSION.SDK_INT >= 8)
appInfo.sourceDir = filePath;
appInfo.publicSourceDir = filePath;
final Drawable icon = appInfo.loadIcon(context.getPackageManager());
return ((BitmapDrawable) icon).getBitmap();
return null;
public double round(double value, int places)
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
public String get_size(double bytes)
if(bytes>(1024*1024*1024))
return String.valueOf(round((bytes/(1024*1024*1024)),2)+"GB");
else if(bytes>(1024*1024))
return String.valueOf(round((bytes/(1024*1024)),2)+"MB");
else
return String.valueOf(round((bytes/(1024)),2)+"KB");
但主要问题是,一旦我设置了适配器,所有图标图像都需要一些时间才能加载,然后手机就会挂起。
我尝试过使用 AsyncTask 但是 这是我得到的错误
Fatal Exception: java.util.concurrent.RejectedExecutionException
Task android.os.AsyncTask$3@16ffd1b rejected from java.util.concurrent.ThreadPoolExecutor@9af2eb8[Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 246]
我知道发生此错误是因为我同时在排队许多 AsyncTask。
我的应用程序有一个/两个以上的 AsyncTask(用于无法避免的不同目的)同时运行,因此我无法等待它们结束然后加载图标。
所以我必须使用下面的代码调用 AsyncTask 来执行。
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,path_to_icon);
任何人都可以帮助我顺利加载图标图像,而不会影响性能并且不会出现错误。
【问题讨论】:
【参考方案1】:您可能需要使用Loader 类。
Loader API 可让您从内容提供商或其他 在 FragmentActivity 或 Fragment 中显示的数据源。如果你 不明白为什么你需要 Loader API 来执行这个看似 琐碎的操作,那么首先考虑一些你可能会遇到的问题 遇到没有装载机:
如果您直接在 Activity 或 Fragment 中获取数据,您的用户将因执行而缺乏响应 来自 UI 线程的查询可能会很慢。 如果您从另一个线程获取数据,可能使用 AsyncTask,那么您负责管理线程和 UI 线程 通过各种活动或片段生命周期事件,例如 onDestroy() 和配置更改。装载机解决了这些问题并带来了其他好处。例如:
加载程序在单独的线程上运行,以防止 UI 出现卡顿或无响应。 加载程序通过在事件发生时提供回调方法来简化线程管理。 加载程序会在配置更改时保持并缓存结果,以防止重复查询。 加载器可以实现一个观察者来监控底层数据源的变化。例如,CursorLoader 自动 注册一个 ContentObserver 以在数据更改时触发重新加载。
还有一篇博文,您可能也会觉得有用:http://www.technotalkative.com/android-asynchronous-image-loading-in-listview/
【讨论】:
非常感谢您的回答。将尽快尝试更新您。 非常感谢您的出色解决方案。有什么我必须记住的,这样我才能防止任何错误。也很抱歉,由于我的声誉较低,我无法投票给答案。 该解决方案运行良好,但在设置适配器时提供了大约 1 秒的粗略体验。你能帮我解决这个问题吗?以上是关于从 ListView 中的 apk 文件加载许多图标的主要内容,如果未能解决你的问题,请参考以下文章
如何从QML中的GridView或ListView获取实例化的委托组件
使用matrixcursor加载带有缩略图的自定义ListView?但如何?