medialoader/src/main/java/com/jiajunhui/xapp/medialoader/bean/VideoResult.java
public class VideoResult extends BaseResult {

    private List<VideoFolder> folders;
    private List<VideoItem> items;

    public VideoResult() {
    }

    public VideoResult(List<VideoFolder> folders, List<VideoItem> items) {
        this.folders = folders;
        this.items = items;
    }

    public VideoResult(List<VideoFolder> folders, List<VideoItem> items,long totalSize) {
        super(totalSize);
        this.folders = folders;
        this.items = items;
    }

    public List<VideoFolder> getFolders() {
        return folders;
    }

    public void setFolders(List<VideoFolder> folders) {
        this.folders = folders;
    }

    public List<VideoItem> getItems() {
        return items;
    }

    public void setItems(List<VideoItem> items) {
        this.items = items;
    }
}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/utils/TraversalSearchLoader.java
public class TraversalSearchLoader {

    private static void load(File root, FileFilter filter,List<File> result, OnLoadListener onLoadListener){
        if(root!=null && root.isDirectory()){
            Queue<File> dirQueue = new LinkedList<>();
            dirQueue.offer(root);
            while (!dirQueue.isEmpty()){
                File dir = dirQueue.poll();
                File[] dirFiles = dir.listFiles();
                if(dirFiles!=null && dirFiles.length>0){
                    for(File file : dirFiles){
                        if(filter.accept(file)){
                            result.add(file);
                            if(onLoadListener!=null){
                                onLoadListener.onItemAdd(file, result.size());
                            }
                        }
                        if(file.isDirectory()){
                            dirQueue.offer(file);
                        }
                    }
                }
            }
        }
    }

    /**
     * synchronized load , may be you need start a thread.
     * @param params
     * @param onRecursionListener
     */
    public static void loadSync(LoadParams params, final OnRecursionListener onRecursionListener){
        if(onRecursionListener!=null){
            onRecursionListener.onStart();
        }
        List<File> result = new ArrayList<>();
        load(params.root, params.fileFilter, result, new OnLoadListener() {
            @Override
            public void onItemAdd(File file, int counter) {
                if(onRecursionListener!=null){
                    onRecursionListener.onItemAdd(file, counter);
                }
            }
        });
        if(onRecursionListener!=null){
            onRecursionListener.onFinish(result);
        }
    }

    /**
     * async load .
     * @param params
     * @param onRecursionListener
     * @return return a AsyncTask , and you can cancel load.
     */
    public static AsyncTask loadAsync(LoadParams params, final OnRecursionListener onRecursionListener){
        return AsyncTaskExecutor.executeConcurrently(new AsyncTask<LoadParams, LoadProgress, List<File>>() {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                if(onRecursionListener!=null){
                    onRecursionListener.onStart();
                }
            }

            @Override
            protected List<File> doInBackground(LoadParams... params) {
                List<File> result = new ArrayList<>();
                LoadParams p = params[0];
                load(p.root, p.fileFilter, result, new OnLoadListener() {
                    @Override
                    public void onItemAdd(File file, int counter) {
                        publishProgress(new LoadProgress(file, counter));
                    }
                });
                return result;
            }

            @Override
            protected void onProgressUpdate(LoadProgress... values) {
                super.onProgressUpdate(values);
                if(onRecursionListener!=null){
                    LoadProgress progress = values[0];
                    onRecursionListener.onItemAdd(progress.file,progress.counter);
                }
            }

            @Override
            protected void onPostExecute(List<File> files) {
                super.onPostExecute(files);
                if(onRecursionListener!=null){
                    onRecursionListener.onFinish(files);
                }
            }
        },params);
    }

    public static class LoadParams{
        public File root;
        public FileFilter fileFilter;
    }

    private static class LoadProgress{
        public File file;
        public int counter;

        public LoadProgress(File file, int counter) {
            this.file = file;
            this.counter = counter;
        }
    }

    private interface OnLoadListener{
        void onItemAdd(File file, int counter);
    }

}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/bean/FileType.java
public enum  FileType {

    DOC(new FileProperty(null, FileLoaderConfig.documentMIME)),
    APK(new FileProperty(FileLoaderConfig.apkExtension,null)),
    ZIP(new FileProperty(FileLoaderConfig.zipExtension,null));

    FileProperty property;

    FileType(FileProperty property){
        this.property = property;
    }

    public FileProperty getProperty() {
        return property;
    }

    public void setProperty(FileProperty property) {
        this.property = property;
    }
}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/inter/OnRecursionListener.java
public interface OnRecursionListener {
    void onStart();
    void onItemAdd(File file, int counter);
    void onFinish(List<File> files);
}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/callback/OnPhotoLoaderCallBack.java
public abstract class OnPhotoLoaderCallBack extends BaseLoaderCallBack<PhotoResult> {

    @Override
    public void onLoadFinish(Loader<Cursor> loader, Cursor data) {
        List<PhotoFolder> folders = new ArrayList<>();
        List<PhotoItem> allPhotos = new ArrayList<>();
        if(data == null){
            onResult(new PhotoResult(folders,allPhotos));
            return;
        }
        PhotoFolder folder;
        PhotoItem item;
        long sum_size = 0;
        while (data.moveToNext()) {
            String folderId = data.getString(data.getColumnIndexOrThrow(BUCKET_ID));
            String folderName = data.getString(data.getColumnIndexOrThrow(BUCKET_DISPLAY_NAME));
            int imageId = data.getInt(data.getColumnIndexOrThrow(_ID));
            String name = data.getString(data.getColumnIndexOrThrow(DISPLAY_NAME));
            long size = data.getLong(data.getColumnIndexOrThrow(SIZE));
            String path = data.getString(data.getColumnIndexOrThrow(DATA));
            long modified = data.getLong(data.getColumnIndexOrThrow(DATE_MODIFIED));
            folder = new PhotoFolder();
            folder.setId(folderId);
            folder.setName(folderName);
            item = new PhotoItem(imageId,name,path,size,modified);
            if(folders.contains(folder)){
                folders.get(folders.indexOf(folder)).addItem(item);
            }else{
                folder.setCover(path);
                folder.addItem(item);
                folders.add(folder);
            }
            allPhotos.add(item);
            sum_size += size;
        }
        onResult(new PhotoResult(folders,allPhotos,sum_size));
    }

    @Override
    public String[] getSelectProjection() {
        String[] PROJECTION = {
                MediaStore.Images.Media._ID,
                MediaStore.Images.Media.DATA,
                MediaStore.Images.Media.BUCKET_ID,
                MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
                MediaStore.Images.Media.DISPLAY_NAME,
                MediaStore.Images.Media.SIZE,
                MediaStore.Images.Media.DATE_MODIFIED
        };
        return PROJECTION;
    }

    @Override
    public Uri getQueryUri() {
        return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    }
}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/callback/OnFileLoaderCallBack.java
public abstract class OnFileLoaderCallBack extends BaseFileLoaderCallBack<FileResult> {

    public OnFileLoaderCallBack() {
    }

    public OnFileLoaderCallBack(FileType type) {
        super(type);
    }

    public OnFileLoaderCallBack(FileProperty property) {
        super(property);
    }

    @Override
    public void onLoadFinish(Loader<Cursor> loader, Cursor data) {
        List<FileItem> result = new ArrayList<>();
        FileItem item;
        long sum_size = 0;
        while (data.moveToNext()) {
            item = new FileItem();
            int audioId = data.getInt(data.getColumnIndexOrThrow(BaseColumns._ID));
            String path = data.getString(data.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA));
            long size = data.getLong(data.getColumnIndexOrThrow(MediaStore.MediaColumns.SIZE));
            String name = data.getString(data.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME));
            String mime = data.getString(data.getColumnIndexOrThrow(MIME_TYPE));
            long modified = data.getLong(data.getColumnIndexOrThrow(DATE_MODIFIED));
            item.setId(audioId);
            item.setDisplayName(name);
            item.setPath(path);
            item.setSize(size);
            item.setMime(mime);
            item.setModified(modified);
            result.add(item);
            sum_size += size;
        }
        onResult(new FileResult(sum_size,result));
    }

}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/bean/AudioResult.java
public class AudioResult extends BaseResult {

    private List<AudioItem> items;

    public AudioResult() {
    }

    public AudioResult(List<AudioItem> items) {
        this.items = items;
    }

    public AudioResult(long totalSize, List<AudioItem> items) {
        super(totalSize);
        this.items = items;
    }

    public List<AudioItem> getItems() {
        return items;
    }

    public void setItems(List<AudioItem> items) {
        this.items = items;
    }
}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/callback/OnVideoLoaderCallBack.java
public abstract class OnVideoLoaderCallBack extends BaseLoaderCallBack<VideoResult> {

    @Override
    public void onLoadFinish(Loader<Cursor> loader, Cursor data) {
        List<VideoFolder> folders = new ArrayList<>();
        VideoFolder folder;
        VideoItem item;
        long sum_size = 0;
        List<VideoItem> items = new ArrayList<>();
        while (data.moveToNext()) {
            String folderId = data.getString(data.getColumnIndexOrThrow(BUCKET_ID));
            String folderName = data.getString(data.getColumnIndexOrThrow(BUCKET_DISPLAY_NAME));
            int videoId = data.getInt(data.getColumnIndexOrThrow(_ID));
            String name = data.getString(data.getColumnIndexOrThrow(DISPLAY_NAME));
            String path = data.getString(data.getColumnIndexOrThrow(DATA));
            long duration = data.getLong(data.getColumnIndexOrThrow(DURATION));
            long size = data.getLong(data.getColumnIndexOrThrow(SIZE));
            long modified = data.getLong(data.getColumnIndexOrThrow(DATE_MODIFIED));
            item = new VideoItem(videoId,name,path,size,modified,duration);
            folder = new VideoFolder();
            folder.setId(folderId);
            folder.setName(folderName);
            if(folders.contains(folder)){
                folders.get(folders.indexOf(folder)).addItem(item);
            }else{
                folder.addItem(item);
                folders.add(folder);
            }
            items.add(item);
            sum_size += size;
        }
        onResult(new VideoResult(folders,items,sum_size));
    }

    @Override
    public String[] getSelectProjection() {
        String[] PROJECTION = {
                MediaStore.Video.Media._ID,
                MediaStore.Video.Media.DATA,
                MediaStore.Video.Media.BUCKET_ID,
                MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
                MediaStore.Video.Media.DISPLAY_NAME,
                MediaStore.Video.Media.DURATION,
                MediaStore.MediaColumns.SIZE,
                MediaStore.Video.Media.DATE_MODIFIED
        };
        return PROJECTION;
    }

    @Override
    public Uri getQueryUri() {
        return MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    }

}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/filter/PhotoFilter.java
public class PhotoFilter implements FileFilter {
    @Override
    public boolean accept(File pathname) {
        if(pathname.length()<=0)
            return false;
        String name = pathname.getName();
        int i = name.lastIndexOf('.');
        if (i != -1) {
            name = name.substring(i);
            if (name.equalsIgnoreCase(".jpg")
                    || name.equalsIgnoreCase(".jpeg")
                    || name.equalsIgnoreCase(".png")
                    || name.equalsIgnoreCase(".gif")
                    || name.equalsIgnoreCase(".bmp")) {
                return true;
            }
        }
        return false;
    }
}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/callback/OnAudioLoaderCallBack.java
public abstract class OnAudioLoaderCallBack extends BaseLoaderCallBack<AudioResult> {

    @Override
    public void onLoadFinish(Loader<Cursor> loader, Cursor data) {
        List<AudioItem> result = new ArrayList<>();
        AudioItem item;
        long sum_size = 0;
        while (data.moveToNext()) {
            item = new AudioItem();
            int audioId = data.getInt(data.getColumnIndexOrThrow(_ID));
            String name = data.getString(data.getColumnIndexOrThrow(DISPLAY_NAME));
            String path = data.getString(data.getColumnIndexOrThrow(DATA));
            long duration = data.getLong(data.getColumnIndexOrThrow(DURATION));
            long size = data.getLong(data.getColumnIndexOrThrow(SIZE));
            long modified = data.getLong(data.getColumnIndexOrThrow(DATE_MODIFIED));
            item.setId(audioId);
            item.setDisplayName(name);
            item.setPath(path);
            item.setDuration(duration);
            item.setSize(size);
            item.setModified(modified);
            result.add(item);
            sum_size += size;
        }
        onResult(new AudioResult(sum_size,result));
    }

    @Override
    public Uri getQueryUri() {
        return MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    }

    @Override
    public String[] getSelectProjection() {
        String[] PROJECTION = {
                MediaStore.Audio.Media._ID,
                MediaStore.Audio.Media.DATA,
                MediaStore.Audio.Media.DISPLAY_NAME,
                MediaStore.Audio.Media.DURATION,
                MediaStore.MediaColumns.SIZE,
                MediaStore.Audio.Media.DATE_MODIFIED
        };
        return PROJECTION;
    }
}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/bean/PhotoResult.java
public class PhotoResult extends BaseResult {

    private List<PhotoFolder> folders;
    private List<PhotoItem> items;

    public PhotoResult() {
    }

    public PhotoResult(List<PhotoFolder> folders, List<PhotoItem> items) {
        this.folders = folders;
        this.items = items;
    }

    public PhotoResult(List<PhotoFolder> folders, List<PhotoItem> items,long totalSize) {
        super(totalSize);
        this.folders = folders;
        this.items = items;
    }

    public List<PhotoFolder> getFolders() {
        return folders;
    }

    public void setFolders(List<PhotoFolder> folders) {
        this.folders = folders;
    }

    public List<PhotoItem> getItems() {
        return items;
    }

    public void setItems(List<PhotoItem> items) {
        this.items = items;
    }
}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/MediaLoader.java
public class MediaLoader {

    private static final int DEFAULT_START_ID = 1000;

    private final String TAG = "MediaLoader";
    private static MediaLoader loader = new MediaLoader();

    private Map<String,Queue<LoaderTask>> mTaskGroup = new HashMap<>();

    private Map<String,Integer> mIds = new HashMap<>();

    private final int MSG_CODE_LOAD_FINISH = 101;
    private final int MSG_CODE_LOAD_START = 102;

    private Handler mHandler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case MSG_CODE_LOAD_FINISH:
                    Message message = Message.obtain();
                    message.what = MSG_CODE_LOAD_START;
                    message.obj = msg.obj;
                    sendMessage(message);
                    break;
                case MSG_CODE_LOAD_START:
                    String group = (String) msg.obj;
                    if(!TextUtils.isEmpty(group)){
                        Queue<LoaderTask> queue = mTaskGroup.get(group);
                        LoaderTask task = queue.poll();
                        if(task!=null){
                            queueLoader(task.activity.get(),task.onLoaderCallBack);
                        }
                        Log.d(TAG,"after poll current group = " + group + " queue length = " + queue.size());
                    }
                    break;
            }
        }
    };

    private MediaLoader(){
    }

    public static MediaLoader getLoader(){
        return loader;
    }

    private int checkIds(FragmentActivity activity){
        String name = activity.getClass().getName();
        int id;
        if(!mIds.containsKey(name)){
            id = DEFAULT_START_ID;
            mIds.put(name, id);
        }else{
            int preId = mIds.get(name);
            preId++;
            mIds.put(name, preId);
            id = preId;
        }
        return id;
    }

    private void loadMedia(FragmentActivity activity, AbsLoaderCallBack absLoaderCallBack){
        activity.getSupportLoaderManager().restartLoader(checkIds(activity),null,absLoaderCallBack);
    }

    private synchronized void load(FragmentActivity activity, OnLoaderCallBack onLoaderCallBack){

        String name = activity.getClass().getSimpleName();
        Queue<LoaderTask> queue = mTaskGroup.get(name);
        LoaderTask task = new LoaderTask(new WeakReference<>(activity),onLoaderCallBack);
        if(queue==null){
            queue = new LinkedList<>();
            mTaskGroup.put(name,queue);
        }
        queue.offer(task);
        Log.d(TAG,"after offer current queue group = " + name + " queue length = " + queue.size());
        if(queue.size()==1){
            Message message = Message.obtain();
            message.what = MSG_CODE_LOAD_START;
            message.obj = name;
            mHandler.sendMessage(message);
        }
    }

    private void queueLoader(final FragmentActivity activity, OnLoaderCallBack onLoaderCallBack){
        loadMedia(activity, new AbsLoaderCallBack(activity,onLoaderCallBack){
            @Override
            public void onLoaderReset(Loader<Cursor> loader) {
                super.onLoaderReset(loader);
                Queue<LoaderTask> queue = mTaskGroup.get(activity.getClass().getSimpleName());
                if(queue!=null){
                    queue.clear();
                }
                Log.d(TAG,"***onLoaderReset***");
            }

            @Override
            public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
                super.onLoadFinished(loader, data);
                Message message = Message.obtain();
                message.what = MSG_CODE_LOAD_FINISH;
                message.obj = activity.getClass().getSimpleName();
                mHandler.sendMessage(message);
                Log.d(TAG,"***onLoaderFinished***");
            }
        });
    }

    public void loadPhotos(FragmentActivity activity, OnPhotoLoaderCallBack onPhotoLoaderCallBack){
        load(activity,onPhotoLoaderCallBack);
    }

    public void loadVideos(FragmentActivity activity, OnVideoLoaderCallBack onVideoLoaderCallBack){
        load(activity,onVideoLoaderCallBack);
    }

    public void loadAudios(FragmentActivity activity, OnAudioLoaderCallBack onAudioLoaderCallBack){
        load(activity,onAudioLoaderCallBack);
    }

    public void loadFiles(FragmentActivity activity, OnFileLoaderCallBack onFileLoaderCallBack){
        load(activity,onFileLoaderCallBack);
    }

    public static class LoaderTask{
        public WeakReference<FragmentActivity> activity;
        public OnLoaderCallBack onLoaderCallBack;

        public LoaderTask(WeakReference<FragmentActivity> activity, OnLoaderCallBack onLoaderCallBack) {
            this.activity = activity;
            this.onLoaderCallBack = onLoaderCallBack;
        }
    }

}
medialoader/src/main/java/com/jiajunhui/xapp/medialoader/bean/FileResult.java
public class FileResult extends BaseResult {

    private List<FileItem> items;

    public FileResult() {
    }

    public FileResult(long totalSize, List<FileItem> items) {
        super(totalSize);
        this.items = items;
    }

    public List<FileItem> getItems() {
        return items;
    }

    public void setItems(List<FileItem> items) {
        this.items = items;
    }
}


Question: package com.jiajunhui.xapp.medialoaderdemo;
import android.Manifest;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.jiajunhui.xapp.medialoader.MediaLoader;
import com.jiajunhui.xapp.medialoader.bean.AudioResult;
import com.jiajunhui.xapp.medialoader.bean.FileResult;
import com.jiajunhui.xapp.medialoader.bean.FileType;
import com.jiajunhui.xapp.medialoader.bean.PhotoResult;
import com.jiajunhui.xapp.medialoader.bean.VideoResult;
import com.jiajunhui.xapp.medialoader.callback.OnAudioLoaderCallBack;
import com.jiajunhui.xapp.medialoader.callback.OnFileLoaderCallBack;
import com.jiajunhui.xapp.medialoader.callback.OnVideoLoaderCallBack;
import com.jiajunhui.xapp.medialoader.callback.OnPhotoLoaderCallBack;
import com.jiajunhui.xapp.medialoader.filter.PhotoFilter;
import com.jiajunhui.xapp.medialoader.inter.OnRecursionListener;
import com.jiajunhui.xapp.medialoader.utils.TraversalSearchLoader;
import java.io.File;
import java.util.List;
import kr.co.namee.permissiongen.PermissionFail;
import kr.co.namee.permissiongen.PermissionGen;
import kr.co.namee.permissiongen.PermissionSuccess;





public class MainActivity extends AppCompatActivity {

    private TextView tv_photo_info;
    private TextView tv_video_info;
    private TextView tv_audio_info;
    private TextView tv_file_info;
    private TextView tv_traversal_info;

    private long start;
    private AsyncTask mTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv_photo_info = (TextView) findViewById(R.id.tv_photo_info);
        tv_video_info = (TextView) findViewById(R.id.tv_video_info);
        tv_audio_info = (TextView) findViewById(R.id.tv_audio_info);
        tv_file_info = (TextView) findViewById(R.id.tv_file_info);
        tv_traversal_info = (TextView) findViewById(R.id.tv_traversal_info);

        findViewById(R.id.btn_next).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(),MainActivity2.class);
                startActivity(intent);
            }
        });

        PermissionGen.with(MainActivity.this)
                .addRequestCode(100)
                .permissions(
                        Manifest.permission.READ_EXTERNAL_STORAGE)
                .request();

    }

    private void recursionLoad() {
        TraversalSearchLoader.LoadParams params = new TraversalSearchLoader.LoadParams();
        //需要遍历的根目录
        params.root = Environment.getExternalStorageDirectory();
        //过滤器
        params.fileFilter = new PhotoFilter();
        mTask = TraversalSearchLoader.loadAsync(params, new OnRecursionListener() {
            @Override
            public void onStart() {
                System.out.println("load_log : start---->");
            }

            @Override
            public void onItemAdd(File file, int counter) {
                System.out.println("load_log : onItemAdd : " + file.getAbsolutePath());
                tv_traversal_info.setText("number : " + counter + " : " + file.getAbsolutePath());
            }

            @Override
            public void onFinish(List<File> files) {
                System.out.println("load_log : finish ***** size = " + files.size());
                tv_traversal_info.setText("number : " + files.size());
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
    }

    @PermissionSuccess(requestCode = 100)
    public void onPermissionSuccess(){
        start = System.currentTimeMillis();
        recursionLoad();
        startLoad();
    }

    private void startLoad() {
        loadPhotos();
        loadAudios();
        loadVideos();
        final StringBuilder mInfos = new StringBuilder();
        MediaLoader.getLoader().loadFiles(MainActivity.this, new OnFileLoaderCallBack(FileType.DOC) {
            @Override
            public void onResult(FileResult result) {
                mInfos.append("doc file : " + result.getItems().size()).append("\n");
            }
        });

        MediaLoader.getLoader().loadFiles(MainActivity.this, new OnFileLoaderCallBack(FileType.ZIP) {
            @Override
            public void onResult(FileResult result) {
                mInfos.append("zip file : " + result.getItems().size()).append("\n");
            }
        });

        MediaLoader.getLoader().loadFiles(MainActivity.this, new OnFileLoaderCallBack(FileType.APK) {
            @Override
            public void onResult(FileResult result) {
                mInfos.append("apk file : " + result.getItems().size()).append("\n");
                mInfos.append("consume time : " + (System.currentTimeMillis() - start)).append("ms");
                tv_file_info.setText(mInfos.toString());
            }
        });
    }

    @PermissionFail(requestCode = 100)
    public void onPermissionFail(){
        Toast.makeText(this, "permission deny", Toast.LENGTH_SHORT).show();
    }

    private void loadPhotos() {
        MediaLoader.getLoader().loadPhotos(this, new OnPhotoLoaderCallBack() {
            @Override
            public void onResult(PhotoResult result) {
                tv_photo_info.setText("图片: " + result.getItems().size() + " 张");
            }
        });
    }

    private void loadAudios() {
        MediaLoader.getLoader().loadAudios(this, new OnAudioLoaderCallBack() {
            @Override
            public void onResult(AudioResult result) {
                tv_audio_info.setText("音乐: " + result.getItems().size() + " 个");
            }
        });
    }

    private void loadVideos() {
Answer:         MediaLoader.getLoader().loadVideos(this, new OnVideoLoaderCallBack() {