Android使用Rxjava异步递归读取内存卡中所有的视频文件

Rxjava是一个异步调用库,可以很灵活地使用操作符来满足各种的异步操作需求。
RXjava入门引导文章请看:http://blog.csdn.net/u010072711/article/details/51590553

我们都知道,android中可以使用HandlerThread做异步耗时操作,使用是可以使用,但是其步骤过于繁琐,看起来也不优雅。

使用HandlerThread读取文件夹中的视频文件:

package com.danxx.mdplayer.ui;

import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.transition.Explode;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.danxx.mdplayer.R;
import com.danxx.mdplayer.adapter.BaseRecyclerViewAdapter;
import com.danxx.mdplayer.adapter.BaseRecyclerViewHolder;
import com.danxx.mdplayer.model.VideoBean;
import com.danxx.mdplayer.utils.FileUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

public class VideoListActivity extends AppCompatActivity {
    private String path;
    private static final int MSG_READ_FINISH = 1;
    private VideoListAdapter mAdapter;
    private LinearLayoutManager mLayoutManager;
    private RecyclerView videoListView;
    private File rootFile;
    private TextView tvFilePath;

    /**包含有视频文件夹集合**/
    private List<VideoBean> videoBeans = new ArrayList<VideoBean>();
    private List<VideoBean> videoBeans2 = new ArrayList<VideoBean>();
    private HandlerThread handlerThread;
    private Handler readTaskHandler;
    private Handler mainHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            if(msg.what == MSG_READ_FINISH){
                if(videoBeans.size()>0){
                    mAdapter.setData(videoBeans);
                    mAdapter.notifyDataSetChanged();
                }else{
                    Toast.makeText(VideoListActivity.this, "sorry,没有读取到视频文件!", Toast.LENGTH_LONG).show();
                }
            }
            return false;
        }
    });

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // set Explode enter transition animation for current activity
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        getWindow().setEnterTransition(new Explode().setDuration(800));
        getWindow().setExitTransition(null);

        setContentView(R.layout.activity_video_list);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        Intent intent = getIntent();
        path = intent.getStringExtra("path");
        mAdapter = new VideoListAdapter();
        tvFilePath = (TextView) findViewById(R.id.tvFilePath);
        videoListView = (RecyclerView) findViewById(R.id.videoListView);
        mLayoutManager = new LinearLayoutManager(this);
        mLayoutManager.setOrientation(OrientationHelper.VERTICAL);
        videoListView.setLayoutManager(mLayoutManager);
        videoListView.setAdapter(mAdapter);
        if(path != null && !TextUtils.isEmpty(path)){
            tvFilePath.setText(path);
            initData();
        }
    }

    private void initData(){
        rootFile = new File(path);

        handlerThread = new HandlerThread("ReadVideoFileTask");
        handlerThread.start();
        readTaskHandler = new Handler(handlerThread.getLooper());
        ReadVideoFileTask readVideoFileTask = new ReadVideoFileTask(mainHandler);
        readTaskHandler.post(readVideoFileTask);

        mAdapter.setOnItemClickListener(new BaseRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position, Object data) {
                VideoActivity.intentTo(VideoListActivity.this , ((VideoBean)data).path ,((VideoBean)data).name);
            }
        });
    }

    class ReadVideoFileTask implements Runnable{

        Handler mainHandler;
        public ReadVideoFileTask(Handler handler){
            this.mainHandler = handler;
        }
        @Override
        public void run() {
            eachAllMedias(rootFile);
            Log.d("danxx", "文件读取完成");
            Message msg = mainHandler.obtainMessage(MSG_READ_FINISH);
            msg.sendToTarget();
        }

        /** 遍历所有文件夹,查找出视频文件 */
        private void eachAllMedias(File f) {
            if (f != null && f.exists() && f.isDirectory()) {
                File[] files = f.listFiles();
                if (files != null) { //文件夹里面存在文件或者文件夹
                    for (File file : f.listFiles()) {
                        if (file.isDirectory()) {
                            eachAllMedias(file);
                        } else if (file.exists() && file.canRead() && FileUtils.isVideo(file)) {
                            String name = file.getName();
                            String size = FileUtils.showFileSize(file.length());
                            String path = file.getPath();
                            videoBeans.add(new VideoBean(name , path , size));
                        }
                    }
                }
            }else{
                Log.d("danxx" ,"目录直接为空");
            }
        }
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == android.R.id.home)
        {
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finish();
    }

    class VideoListAdapter extends BaseRecyclerViewAdapter<VideoBean>{

        /**
         * 创建item view
         *
         * @param parent
         * @param viewType
         * @return
         */
        @Override
        protected BaseRecyclerViewHolder createItem(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(VideoListActivity.this).inflate(R.layout.item_videos_layout, parent, false);
            MyViewHolder viewHolder = new MyViewHolder(view);
            return viewHolder;
        }

        /**
         * 绑定数据
         *
         * @param holder
         * @param position
         */
        @Override
        protected void bindData(BaseRecyclerViewHolder holder, int position) {
            ((MyViewHolder)holder).tvName.setText(getItemData(position).name);
            ((MyViewHolder)holder).tvSize.setText(getItemData(position).size);
        }

        class MyViewHolder extends BaseRecyclerViewHolder{
            View mView;
            ImageView ivPic;
            TextView tvName,tvSize,tvlength;
            public MyViewHolder(View itemView) {
                super(itemView);
                ivPic = (ImageView) itemView.findViewById(R.id.ivPic);
                tvName = (TextView) itemView.findViewById(R.id.tvName);
                tvSize = (TextView) itemView.findViewById(R.id.tvSize);
                tvlength = (TextView) itemView.findViewById(R.id.tvlength);
                mView = itemView;
            }

            @Override
            protected View getView() {
                return mView;
            }
        }
    }
}

使用Rxjava读取文件夹中的视频文件:

Demo的GitHub地址:https://github.com/Dawish/MDPlayer

package com.danxx.mdplayer.ui;

import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.transition.Explode;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.danxx.mdplayer.R;
import com.danxx.mdplayer.adapter.BaseRecyclerViewAdapter;
import com.danxx.mdplayer.adapter.BaseRecyclerViewHolder;
import com.danxx.mdplayer.model.VideoBean;
import com.danxx.mdplayer.utils.FileUtils;
import com.danxx.mdplayer.utils.RxUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.Subscriber;
import rx.functions.Func1;

public class VideoListActivity extends AppCompatActivity {
    private String path;
    private static final int MSG_READ_FINISH = 1;
    private VideoListAdapter mAdapter;
    private LinearLayoutManager mLayoutManager;
    private RecyclerView videoListView;
    private File rootFile;
    private TextView tvFilePath;

    /**
     * 包含有视频文件夹集合
     **/
    private List<VideoBean> videoBeans = new ArrayList<VideoBean>();

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // set Explode enter transition animation for current activity
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        getWindow().setEnterTransition(new Explode().setDuration(800));
        getWindow().setExitTransition(null);

        setContentView(R.layout.activity_video_list);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        Intent intent = getIntent();
        path = intent.getStringExtra("path");
        mAdapter = new VideoListAdapter();
        tvFilePath = (TextView) findViewById(R.id.tvFilePath);
        videoListView = (RecyclerView) findViewById(R.id.videoListView);
        mLayoutManager = new LinearLayoutManager(this);
        mLayoutManager.setOrientation(OrientationHelper.VERTICAL);
        videoListView.setLayoutManager(mLayoutManager);
        videoListView.setAdapter(mAdapter);
        if (path != null && !TextUtils.isEmpty(path)) {
            tvFilePath.setText(path);
            initData();
        }
    }

    private void initData() {
        rootFile = new File(path);
        ReadVideoFileByRxjava();
    }


    /**
     * 参考:http://blog.csdn.net/job_hesc/article/details/46242117
     */
    private void ReadVideoFileByRxjava() {
        Observable.just(rootFile)
                .flatMap(new Func1<File, Observable<File>>() {
                    @Override
                    public Observable<File> call(File file) {
                        return RxUtil.listFiles(file);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        new Subscriber<File>() {
                            @Override
                            public void onCompleted() {
                                Log.d("danxx", "onCompleted");
                                if (videoBeans.size() > 0) {
                                    mAdapter.setData(videoBeans);
                                    mAdapter.notifyDataSetChanged();
                                } else {
                                    Toast.makeText(VideoListActivity.this, "sorry,没有读取到视频文件!", Toast.LENGTH_LONG).show();
                                }
                            }

                            @Override
                            public void onError(Throwable e) {
                            }

                            @Override
                            public void onNext(File file) {
                                String name = file.getName();
                                String size = FileUtils.showFileSize(file.length());
                                String path = file.getPath();
                                videoBeans.add(new VideoBean(name, path, size));
                                Log.d("danxx", "name--->" + name);
                            }
                        }
                );
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finish();
    }

    class VideoListAdapter extends BaseRecyclerViewAdapter<VideoBean> {

        /**
         * 创建item view
         *
         * @param parent
         * @param viewType
         * @return
         */
        @Override
        protected BaseRecyclerViewHolder createItem(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(VideoListActivity.this).inflate(R.layout.item_videos_layout, parent, false);
            MyViewHolder viewHolder = new MyViewHolder(view);
            return viewHolder;
        }

        /**
         * 绑定数据
         *
         * @param holder
         * @param position
         */
        @Override
        protected void bindData(BaseRecyclerViewHolder holder, int position) {
            ((MyViewHolder) holder).tvName.setText(getItemData(position).name);
            ((MyViewHolder) holder).tvSize.setText(getItemData(position).size);
        }

        class MyViewHolder extends BaseRecyclerViewHolder {
            View mView;
            ImageView ivPic;
            TextView tvName, tvSize, tvlength;

            public MyViewHolder(View itemView) {
                super(itemView);
                ivPic = (ImageView) itemView.findViewById(R.id.ivPic);
                tvName = (TextView) itemView.findViewById(R.id.tvName);
                tvSize = (TextView) itemView.findViewById(R.id.tvSize);
                tvlength = (TextView) itemView.findViewById(R.id.tvlength);
                mView = itemView;
            }

            @Override
            protected View getView() {
                return mView;
            }
        }
    }
}

上面用到的工具类RxUtil .java:

package com.danxx.mdplayer.utils;

import java.io.File;
import java.util.concurrent.Callable;

import rx.Observable;
import rx.Subscriber;
import rx.functions.Func1;

/**
 * Created by danxingxi
 * Observable创建工具类
 */
public class RxUtil {

    /**
     * rxjava递归查询内存中的视频文件
     * @param f
     * @return
     */
    public static Observable<File> listFiles(final File f){
        if(f.isDirectory()){
            return Observable.from(f.listFiles()).flatMap(new Func1<File, Observable<File>>() {
                @Override
                public Observable<File> call(File file) {
                    /**如果是文件夹就递归**/
                    return listFiles(file);
                }
            });
        } else {
            /**filter操作符过滤视频文件,是视频文件就通知观察者**/
            return Observable.just(f).filter(new Func1<File, Boolean>() {
                @Override
                public Boolean call(File file) {
                    return f.exists() && f.canRead() && FileUtils.isVideo(f);
                }
            });
        }
    }

}

使用Rxjava是不是优雅简洁很多?

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值