1. 程式人生 > >Glide4.x載入應用圖示

Glide4.x載入應用圖示

載入應用圖示其實非常簡單:

ApplicationInfo applicationInfo = packageManager.getApplicationInfo(pkgName.getPkg(), 0);
Drawable drawable = applicationInfo.loadIcon(packageManager)

只是載入應用圖示也是一個耗時的過程,需要開子執行緒進行載入,以前要麼使用thread+hander方式或者直接RXJava實現。一次偶然突發奇想,為什麼不用glide來實現,畢竟以前的ImageLoader是支援的。只是glide需要自定義模組來實現,glide4.x與以前版本在介面上還是有一些差異,我是基於4.x實現的。如果不瞭解4.x怎麼自定義模組,可以看一下這篇文件上程式碼:

編寫定製的 ModelLoader

上程式碼

GMGlideModule.java

@GlideModule
public class GMGlideModule extends AppGlideModule {
    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        super.registerComponents(context, glide, registry);
        registry.prepend(ApkIconModel.class,InputStream.class,new ApkModelLoaderFactory(context));
    }
}

ApkModelLoaderFactory.java

public class ApkModelLoaderFactory implements ModelLoaderFactory<ApkIconModel, InputStream> {
    private Context context;

    public ApkModelLoaderFactory(Context context) {
        this.context = context;
    }

    @NonNull
    @Override
    public ModelLoader<ApkIconModel, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
        return new ApkIconModelLoader(context);
    }

    @Override
    public void teardown() {

    }
}

ApkIconModelLoader.java 

public class ApkIconModelLoader implements ModelLoader<ApkIconModel,InputStream> {
    private Context context;
    public ApkIconModelLoader(Context context){
        this.context = context;

    }

    @Nullable
    @Override
    public LoadData<InputStream> buildLoadData(@NonNull ApkIconModel apkIconModel, int width, int height, @NonNull Options options) {
       return new LoadData<>(new ObjectKey(apkIconModel.getPkg()),new ApkIconFetcher(context,apkIconModel));
    }

    @Override
    public boolean handles(@NonNull ApkIconModel apkIconModel) {
        return true;
    }
}

 ApkIconFetcher.java

 

public class ApkIconFetcher implements DataFetcher<InputStream> {
    private ApkIconModel pkgName;
    private Context context;
    private final PackageManager packageManager;

    public ApkIconFetcher(Context context, ApkIconModel pkgName){
        this.context = context;
        this.pkgName = pkgName;
        packageManager = context.getPackageManager();
    }

    @Override
    public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
        ApplicationInfo applicationInfo;
        try {
            applicationInfo = packageManager.getApplicationInfo(pkgName.getPkg(), 0);
            Drawable d = packageManager.getApplicationIcon(applicationInfo); //xxx根據自己的情況獲取drawable
            BitmapDrawable bd = (BitmapDrawable) d;
            Bitmap iconBitmap = bd.getBitmap();
            InputStream inputStream = bitmap2InputStream(iconBitmap);
            callback.onDataReady(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
            callback.onLoadFailed(e);
        }
    }
    // 將Bitmap轉換成InputStream
    private InputStream bitmap2InputStream(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return new ByteArrayInputStream(baos.toByteArray());
    }
    @Override
    public void cleanup() {

    }

    @Override
    public void cancel() {

    }

    @NonNull
    @Override
    public Class<InputStream> getDataClass() {
        return InputStream.class;
    }

    @NonNull
    @Override
    public DataSource getDataSource() {
        return DataSource.LOCAL;
    }
}

ApkIconModel.java

public class ApkIconModel {
    private String pkgName;

    public ApkIconModel(String pkgName) {
        this.pkgName = pkgName;
    }

    public String getPkg() {
        return pkgName;
    }
}