项目总结(VideoStream网页播放视频)

代码中sd卡下music文件夹的位置:/storage/emulated/0/Music/xxx.mp3

项目使用技术:ButterKnife、RxBinding、RxJava2、IJKPlayer、RecyclerView、IMediaPlayer。

ButterKnife:

以前总是要写很多findViewById来找到View对象,ButterKnife可以省去这些步骤,强大的View绑定和Click事件处理功能。使用ButterKnife对性能基本没有损失,因为ButterKnife用到的注解并不是在运行时反射的,而是在编译的时候生成新的class。

ButterKnife使用:

1、在Activity 类中绑定 :ButterKnife.bind(this);必须在setContentView();之后绑定;且父类bind绑定后,子类不需要再bind。

2、在Activity中不需要做解绑操作,在Fragment 中必须在onDestroyView()中做解绑操作。

3、使用ButterKnife修饰的方法和控件,不能用private or static 修饰,否则会报错。

4、setContentView()不能通过注解实现。(其他的有些注解框架可以)

5、使用Activity为根视图绑定任意对象时,如果你使用类似MVC的设计模式你可以在Activity 调用ButterKnife.bind(this, activity),来绑定Controller。

6、使用ButterKnife.bind(this,view)绑定一个view的子节点字段。如果你在子View的布局里或者自定义view的构造方法里 使用了inflate,你可以立刻调用此方法。或者,从XML inflate来的自定义view类型可以在onFinishInflate回调方法中使用它。

ButterKnife注解示例:

    @BindViews({ R2.id.button1, R2.id.button2,  R2.id.button3})  
    public List<Button> buttonList ;  
  @BindArray(R2.array.city)  //绑定string里面array数组  
    String [] citys ;  
    @BindBitmap( R2.mipmap.bm)//绑定Bitmap 资源  
    public Bitmap bitmap ;  
@OnClick(R.id.submitCode,R.id.submitFile,R.id.submitTest)  
    public void sayHi(Button button) {//多个控件对应公共事件
      button.setText("Success!");  
    }  

IJKPlayer:

ijkplayer是b站开源的视频播放器。Android和ios都可用,还支持多种视频的硬解码。ijkplayer没有提供一个播放器控件给我们使用,所以自己定义一个。主要是创建一个surfaceview,把它赋给IMediaPlayer,自定义了一个监听器继IMediaPlayer的n个listener。在activity中加载so包,设置监听器,设置路径。

//加载native库

IjkMediaPlayer.loadLibrariesOnce(null); I

jkMediaPlayer.native_profileBegin("libijkplayer.so"); 

ijkPlayer.setListener(...)

ijkPlayer.setVideoPath(path);

SurfaceView:

Surface对应了一块屏幕缓冲区,每个window对应一个Surface,任何View都要画在Surface的Canvas上。传统的view共享一块屏幕缓冲区,所有的绘制必须在UI线程中进行。SurfaceView中具有两个Surface, 即双缓冲机制。

SurfaceView就是展示Surface中数据的地方,同时可以认为SurfaceView是用来控制Surface中View的位置和尺寸的。

SurfaceView可以用独立的线程进行绘制,因此可以提供更高的帧率。

SurfaceHolder是一个接口,其作用就像一个关于Surface的监听器,提供访问和控制SurfaceView内嵌的Surface 相关的方法。它通过三个回调方法,让我们可以感知到Surface的创建、销毁或者改变。

Surface、SurfaceView和SurfaceHolder实质上就是广为人知的MVC。Model就是数据模型也就是这里的Surface;View即视图,代表用户交互界面也就是这里的SurfaceView;SurfaceHolder很明显可以理解为Controller。

SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。

Rect:

Rect类主要用于表示坐标系中的一块矩形区域,Rect 其实就是左上右下。

Paint:

Paint即画笔,在绘图过程中极其重要的作用,画笔主要保存了颜色、样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法,大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关。

Canvas:

在android中既然把Canvas当做画布,那么就可以在画布上绘制我们想要的任何东西。除了在画布上绘制之外,还需要设置一些关于画布的属性,比如,画布的颜色、尺寸等。

RecyclerView:

RecyclerView并没有像ListView的点击事件,而是可以在Adapter中设置点击事件以及长按点击事件,如下:

@Override
public void onBindViewHolder(@NonNull MyViewHodler myViewHodler, final int i) {
    myViewHodler.tv.setText(datas.get(i));
    myViewHodler.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(MainActivity.this,"点击了第"+i+"个",Toast.LENGTH_SHORT).show();
        }
    });

自定义Adapter重写方法onCreateViewHolder(inflate了recyclerView的子布局)、onBindViewHolder(绑定数据)、getItemCount(得到总条数)以及内部类ViewHolder。SwipeRefreshLayout实现下拉刷新,OnScrollListener实现上拉刷新。

优势:低耦合高类聚

IMediaPlayer:

Android下对于音频或者视频的支持均需要使用到MediaPlayer类。

IMediaPlayer使用:

1.在使用start()播放流媒体之前,需要装载流媒体资源。最好使用prepareAsync()用异步的方式装载。在一些硬件不理想的设备上,如果使用prepare()同步的方式装载资源,可能会造成UI界面的卡顿,为了避免还没有装载完成就调用start()而报错的问题,需要绑定MediaPlayer.setOnPreparedListener()事件,在异步装载完成之后回调。

2.MediaPlayer是很消耗系统资源所以使用完不要等待系统自动回收,用release()主动回收资源。

3.对于单曲循环可以使用setLooping()方法进行设置,还可以为MediaPlayer注册播放完毕回调函数MediaPlayer.setOnCompletionListener()。

4.可能一段流媒体前半段可以正常播放中间一段无法播放,可以为MediaPlayer注册回调函数setOnErrorListener()来设置出错之后的解决办法。

RxJava2:

RxJava可以浓缩为异步两个字,其核心的东西不外乎两个, Observables(被观察者) 和 Observable(观察者)。Observables可以发出一系列的事件(例如网络请求、复杂计算、数据库操作、文件读取等),事件执行结束后交给Observable 的回调处理。

观察者模式:举个例子,Android中View的点击监听器的实现,View是被观察者,OnClickListener对象是观察者,Activity要如何知道View被点击了?那就是派一个OnClickListener对象,入驻View,与View达成一个订阅关系,一旦View被点击了,就通过OnClickListener对象的OnClick方法传达给Activity。

RxJava的观察者模式

如图所示,RxJava的概念分别为:Observable(被观察者,事件源),Observer(观察者,订阅者),subscribe(订阅)、事件;,RxJava 把多个事件看做一个队列,并对每个事件单独处理。在一个队列中 onCompleted() 和 onError(),只有一个会被调用。如果调用了 onCompleted() 就说明队列执行完毕,没有出现异常,否则调用 onError() 方法并终止队列。

响应式编程的组成为Observable/Operator/Subscriber,RxJava在响应式编程中的基本流程如下:

这个流程,可以简单的理解为:Observable -> Operator1 -> Operator2 -> Operator3 -> Subscriber

1. Observable发出一系列事件,他是事件的产生者;
2. Subscriber负责处理事件,他是事件的消费者;
3. Operator是对Observable发出的事件进行修改和变换;
4. 若事件从产生到消费不需要其他处理,则可以省略掉中间的Operator,从而流程变为Obsevable -> Subscriber;
5. Subscriber通常在主线程执行,所以原则上不要去处理太多的事务,而这些复杂的处理则交给Operator;

RxBinding:

1.首先RxBinding是对Android View事件的扩展,它使得你可以对View事件使用RxJava的各种操作。

2.提供了与RxJava一致的回调,使得代码简洁明了。尤其是页面中充斥着大量的监听事件,各种各样的匿名内部类时。

3.几乎支持我们常用的所有控件及事件。

RxBinding使用场景:

1.防止按钮重复点击

这个应该是最常用的方法了。利用操作符throttleFirst()取时间间隔内第一次点击事件。

2.点击的多次监听

Android是不能多次监听同一个点击事件。但利用RxJava的操作符,例如publish, sharereplay可以实现。而RxBinding恰好支持对点击事件的多次监听。

3.获取验证码倒计时

interval()在给定的时间间隔发射从0开始的整数序列。

猜你喜欢

转载自blog.csdn.net/a83350695/article/details/81303294