本文主要是介绍Android进阶 -- 知乎Matisse源码解析(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Matisse做了这样一件事情,在需要选择图片视频的时候,调用
Matisse.from(MainActivity.this).choose(MimeType.allOf()).countable(true).maxSelectable(9).addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K)).gridExpectedSize(getResources().getDimensionPixelSize(R.dimen.grid_expected_size)).restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED).thumbnailScale(0.85f).imageEngine(new GlideEngine()).showPreview(false) // Default is `true`.forResult(REQUEST_CODE_CHOOSE);
然后在onActivityResult里回调给我们结果
List<Uri> mSelected;@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == REQUEST_CODE_CHOOSE && resultCode == RESULT_OK) {mSelected = Matisse.obtainResult(data);Log.d("Matisse", "mSelected: " + mSelected);}
}
使用起来非常方便,接下来,一起看看它的内部是怎么实现的。
首先,从入口函数看起
public final class Matisse {private final WeakReference<Activity> mContext;private final WeakReference<Fragment> mFragment;private Matisse(Activity activity) {this(activity, null);}private Matisse(Fragment fragment) {this(fragment.getActivity(), fragment);}private Matisse(Activity activity, Fragment fragment) {mContext = new WeakReference<>(activity);mFragment = new WeakReference<>(fragment);}public static Matisse from(Activity activity) {return new Matisse(activity);}public static Matisse from(Fragment fragment) {return new Matisse(fragment);}public static List<Uri> obtainResult(Intent data) {return data.getParcelableArrayListExtra(MatisseActivity.EXTRA_RESULT_SELECTION);}public static List<String> obtainPathResult(Intent data) {return data.getStringArrayListExtra(MatisseActivity.EXTRA_RESULT_SELECTION_PATH);}public static boolean obtainOriginalState(Intent data) {return data.getBooleanExtra(MatisseActivity.EXTRA_RESULT_ORIGINAL_ENABLE, false);}public SelectionCreator choose(Set<MimeType> mimeTypes) {return this.choose(mimeTypes, true);}public SelectionCreator choose(Set<MimeType> mimeTypes, boolean mediaTypeExclusive) {return new SelectionCreator(this, mimeTypes, mediaTypeExclusive);}@NullableActivity getActivity() {return mContext.get();}@NullableFragment getFragment() {return mFragment != null ? mFragment.get() : null;}}
(1)from两个重载函数,分别接收Activity和Fragment实例,从而保证用户可以在Activity和Fragment直接调用,在方法里通过私有构造函数创建了Matisse的实例,并且都为弱引用,由于选择媒体的操作往往都是一步完成,不需要持有强引用的实例,使用弱引用,在下一次GC的时候,可以实现内存空间的回收。
(2)choose函数用来返回SelectionCreator对象实例并且确定选取的媒体类型(可查看源码里的MimeType枚举类),SelectionCreator使用建造者模式,根据用户的具体需求来初始化一些变量,下面举几个栗子,更多的设置可以查看SelectionCreator的源码,里面的注释都很到位。
- countable:是否开启序号自增计数
- maxSelectable:最大选择数
- addFilter:文件过滤,源码定义了抽象类Filter,用户可以根据需求去自定义Filter
- theme:设置主题
- imageEngine:图片加载引擎
(3)imageEngine:Matisse支持目前主流的图片加载框架glide和picasso,源码里定义了图片引擎接口IamgeEngine
@SuppressWarnings("unused")
public interface ImageEngine {void loadThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView, Uri uri);void loadGifThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView, Uri uri);void loadImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri);void loadGifImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri);boolean supportAnimatedGif();
}
然后使用glide和picasso分别实现了ImageEngine,对应的源码是GlideEngine和PicassoEngine,如果项目里使用的Glide或者Picasso直接使用就好,如果使用fresco或者其他ImageLoader,只需要实现ImageEngine接口,在将其传递进去就好,这里也体现出了一个良好的开源框架的可拓展性。
(4)SelectionCreator内部持有了Matisse的SelectionSpec的实例,Matisse在启动Activity或者Fragment的时候会用到,而SelectionSpec则是所有设置变量的实体类,前面设置的属性都保存在SelectionSpec实体类里,SelectionSpec采用了非线程安全的单例模式写法,因为这里并没有线程安全的隐患,这样写销量更高。
(5)forResult方法启动了MatisseActivity,这个Activity也就是我们看到的图片选择Activity,并且设置了onActivityResult的回调
public void forResult(int requestCode) {Activity activity = mMatisse.getActivity();if (activity == null) {return;}Intent intent = new Intent(activity, MatisseActivity.class);Fragment fragment = mMatisse.getFragment();if (fragment != null) {fragment.startActivityForResult(intent, requestCode);} else {activity.startActivityForResult(intent, requestCode);}}
本篇文章为Matisse源码解读系列的第一篇,了解了Matisse的用法和相关配置的源码部分,下一篇将开始看启动MatisseActivity之后的源码实现。
这篇关于Android进阶 -- 知乎Matisse源码解析(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!