发表于: 2018-11-24 18:55:23
0 892
一、今天完成的事情
学习MVP模式
按照 MVC 的分层,Activity 和 Fragment(后面只说 Activity)应该属于 View 层,用于展示 UI 界面,以及接收用户的输入,此外还要承担一些生命周期的工作。Activity 是在 Android 开发中充当非常重要的角色,特别是它的生命周期的功能,所以开发的时候我们经常把一些业务逻辑直接写在 Activity 里面,这非常直观方便,代价就是 Activity 会越来越臃肿,Activity 不仅承担了 View 的角色,还承担了一部分的 Controller 角色,这样一来 V 和 C 就耦合在一起了,虽然这样写方便,但是如果业务调整的话,要维护起来就难了,而且在一个臃肿的 Activity 类查找业务逻辑的代码也会非常困难,所以看起来有必要在 Activity 中,把 View 和 Controller 抽离开来,而这就是 MVP 模式的工作了。
MVP 模式的核心思想是把 Activity 中的 UI 逻辑抽象成 View 接口,把业务逻辑抽象成 Presenter 接口,Model 类还是原来的 Model。
MVP 模式的优点
分离了视图逻辑和业务逻辑,降低了耦合;
Activity 只处理生命周期的任务,代码变得更加简洁;
视图逻辑和业务逻辑分别抽象到了 View 和 Presenter 的接口中去,提高代码的可阅读性;
Presenter 被抽象成接口,可以有多种具体的实现,所以方便进行单元测试;
把业务逻辑抽到 Presenter 中去,避免后台线程引用着 Activity 导致 Activity 的资源无法被系统回收从而引起 内存泄露和 OOM。
我试着用MVP模式把之前做的播放器重写了一下
播放本地视频模块,目录结构
public interface ILocalVideoView {
void queryLocalVideoResult(boolean result);
void onProgressBarVisibility(int visibility);
void recyclerViewItemClick(String source);
}
public interface ILocalVideoPresenter {
void queryLocalVideo(Context context, LocalVideoAdapter adapter);
void setProgressBarVisibility(int visibility);
void onItemClick(int position);
}
public class LocalVideoPresenterCompl implements ILocalVideoPresenter {
ILocalVideoView iLocalVideoView;
LocalVideo localVideo;
List<LocalVideo> list;
public LocalVideoPresenterCompl(ILocalVideoView iLocalVideoView) {
this.iLocalVideoView = iLocalVideoView;
initLocalVideo();
list = new ArrayList<LocalVideo>();
}
@Override
public void queryLocalVideo(Context context, LocalVideoAdapter adapter) {
list.clear();
list = localVideo.getLocalVideoList(context);
boolean result = false;
if (list != null && list.size() > 0) {
adapter.setData(list);
result = true;
}
iLocalVideoView.queryLocalVideoResult(result);
}
@Override
public void setProgressBarVisibility(int visibility) {
iLocalVideoView.onProgressBarVisibility(visibility);
}
@Override
public void onItemClick(int position) {
String source = list.get(position).getPath();
iLocalVideoView.recyclerViewItemClick(source);
}
private void initLocalVideo() {
localVideo = new LocalVideo(0, "", "", "", "",
"", "", "", "");
}
}
public class LocalVideoFragment extends Fragment implements ILocalVideoView, LocalVideoAdapter.OnItemClickListener {
private static final String TAG = "LocalVideoFragment";
private static final int TAKE_VIDEO = 1;
private ILocalVideoPresenter iLocalVideoPresenter;
private static LocalVideoAdapter localVideoAdapter;
private static ProgressBar progressBar;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_local_video, container, false);
iLocalVideoPresenter = new LocalVideoPresenterCompl(this);
initView(view);
initLocalVideo();
return view;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//指明fragment愿意添加item到选项菜单(否则, fragment将接收不到对 onCreateOptionsMenu()的调用)
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.local_video_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.take_video:
takeVideo();
break;
case R.id.refresh:
initLocalVideo();
break;
default:
break;
}
return true;
}
@Override
public void onItemClick(int position) {
iLocalVideoPresenter.onItemClick(position);
}
/*
初始化控件
*/
public void initView(View view) {
progressBar = (ProgressBar) view.findViewById(R.id.bar_progress);
iLocalVideoPresenter.setProgressBarVisibility(View.GONE);
RecyclerView videoRV = (RecyclerView) view.findViewById(R.id.rv_video);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
videoRV.setLayoutManager(linearLayoutManager);
localVideoAdapter = new LocalVideoAdapter(getContext());
localVideoAdapter.setOnItemClickListener(this);
videoRV.setAdapter(localVideoAdapter);
}
//初始化视频
public void initLocalVideo() {
iLocalVideoPresenter.setProgressBarVisibility(View.VISIBLE);
iLocalVideoPresenter.queryLocalVideo(getContext(), localVideoAdapter);
}
@Override
public void queryLocalVideoResult(boolean result) {
if (result) {
localVideoAdapter.notifyDataSetChanged();
iLocalVideoPresenter.setProgressBarVisibility(View.GONE);
} else {
Toast.makeText(getContext(), "没有更多视频", Toast.LENGTH_SHORT).show();
iLocalVideoPresenter.setProgressBarVisibility(View.GONE);
}
}
@Override
public void onProgressBarVisibility(int visibility) {
progressBar.setVisibility(visibility);
}
@Override
public void recyclerViewItemClick(String source) {
Intent intent = new Intent(getActivity(), PlayVideoActivity.class);
intent.putExtra("source", source);
startActivity(intent);
}
/*
拍摄视频
*/
public void takeVideo() {
Log.i(TAG, "takeVideo: 录视频");
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(takeVideoIntent, TAKE_VIDEO);
} else {
Log.i(TAG, "takeVideo: 错误");
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
//如果希望结果传回Fragment,必须加上下面这一句
super.onActivityResult(requestCode, resultCode,data);
switch (requestCode) {
case TAKE_VIDEO:
if (resultCode == RESULT_OK) {
initLocalVideo();
Toast.makeText(getContext(), "拍摄成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), "拍摄失败", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
}
三、遇到的问题
四、收获
初步学习了MVP设计模式,今后会逐步转移到这种设计模式上来,并继续深入学习。
评论