MVP 入门 (Android demo解析)
来源:互联网 发布:简谱打谱软件for mac 编辑:程序博客网 时间:2024/06/07 04:43
1、mvc mvp
由于mvc下的Controller(也就是Activity)非常的臃肿,不仅要管理视图相关,还要处理一部分逻辑,于是就有了mvp的出现,将Activity看成视图,让他仅仅管理视图相关的工作,Activity不再和业务直接发生关系,
将与业务发生关系的代码从Activity中抽出,放在presenter 中。
看过别人写的关于mvp的博客,自己不写一遍,觉得还是懵懵懂懂,hongyang有一个登陆的例子,http://blog.csdn.net/lmj623565791/article/details/46596109
我觉得写的挺好的,在理解之后,我自己实现了一个demo,功能很简单就 是下载一个文件到本地,然后显示进度条,下载结束后对话框告知用户,下载出错了也会对话框提示哪里错了。
地址如下:
https://github.com/yuzhiyun/MVPDownloadFile
注意:运行demo之后,下载的文件在sd卡根目录(Environment.getExternalStorageDirectory())下。
图解
根据自己写的demo我自己又画了一个图
包结构
代码解释
IDownloadFileView.java
这是view层的接口,view实现这个接口中对view的操作函数
public interface IDownloadFileView { String getUrl(); void showErrorDialog(String error); void showSuccessDialog(); void changeProgress(int progress);}
MainActivity.java
view层,实现IView接口,实现对view的操作函数;
view关联一个presenter,并且把对IView的实现传递给presenter。这样,presenter就可以通过IView操作UI了。
public class MainActivity extends BaseActivity implements View.OnClickListener,IDownloadFileView { Button btn_download; EditText et_url; ProgressBar progressBar; DownloadPresenter downloadPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected void setViewForActivity() { setContentView(R.layout.activity_main); } @Override protected void findViewByIds() { btn_download= (Button) findViewById(R.id.btn_download); et_url= (EditText) findViewById(R.id.et_url); progressBar= (ProgressBar) findViewById(R.id.progressBar); } @Override protected void setListeners() { btn_download.setOnClickListener(this); } @Override protected void initOther() { downloadPresenter=new DownloadPresenter(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.btn_download: downloadPresenter.startDownLoad(); break; } } /** * 获取下载链接 * @return */ @Override public String getUrl() {// return ; return et_url.getText().toString().trim(); } @Override public void showErrorDialog(String error) { //Toast.makeText(this,error,Toast.LENGTH_LONG); //Log.i("MainActivity",error); showDialog(error); } @Override public void showSuccessDialog() { // Toast.makeText(MainActivity.this,"下载成功",Toast.LENGTH_LONG); showDialog("下载成功"); //Log.i("MainActivity","下载成功"); } @Override public void changeProgress(int progress) { progressBar.setProgress(progress); } /** * 弹出对话框 * * @param msg */ public void showDialog(String msg) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("返回结果:\n" + msg) .setCancelable(false) .setPositiveButton("确认", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }); builder.create().show(); }}
DownloadPresenter.java
presenter持有iview接口(IDownloadFileView)以及model层的业务类(IDownloadFileBiz),这样presenter先调用model 完成业务,再把反馈结果显示到UI 上。
public class DownloadPresenter { IDownloadFileView downloadFileView; IDownloadFileBiz downloadFileBiz; public DownloadPresenter(IDownloadFileView iDownloadFileView){ downloadFileView=iDownloadFileView; downloadFileBiz=new DownloadBiz(); } public void startDownLoad(){ downloadFileBiz.startDownload(downloadFileView.getUrl(), new OnDownloadListener() { @Override public void OnError(String error) { downloadFileView.showErrorDialog(error); } @Override public void OnSuccess() { downloadFileView.showSuccessDialog(); } @Override public void OnProgress(Integer progress) { downloadFileView.changeProgress(progress); } }); }}
DownloadBiz.java
Model层的业务类,依赖presenter传递过来的OnDownloadListener最终把执行结果反馈到UI上
public class DownloadBiz implements IDownloadFileBiz { @Override public void startDownload(String url, OnDownloadListener downloadListener) { new DownLoadAsynctask(downloadListener).execute(url); }}class DownLoadAsynctask extends AsyncTask<String,Integer,String>{ OnDownloadListener downloadListener; DownLoadAsynctask(OnDownloadListener downloadListener){ this.downloadListener=downloadListener; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... strings) { double now_length=0; double sum_length=0; String filename=""; boolean isPaused = false; File file = null; int startIndex = 0,endIndex=0; try { byte[] bytes = new byte[1024]; URL url = null; HttpURLConnection conn = null; url = new URL(strings[0]); conn = (HttpURLConnection) url.openConnection(); endIndex = conn.getContentLength(); System.out.println("获得输入流"); InputStream is = conn.getInputStream(); System.out.println("输入流完毕"); sum_length = endIndex; filename = strings[0].substring(strings[0].lastIndexOf("/")+1); file = new File(Environment.getExternalStorageDirectory(),filename); /** * RandomAccessFile可以访问文件的任意位置 * "r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。 * "rw" 打开以便读取和写入。 * "rws" 打开以便读取和写入。相对于 "rw","rws" 还要求对“文件的内容”或“元数据”的每个更新都同步写入到基础存储设备。 * "rwd" 打开以便读取和写入,相对于 "rw","rwd" 还要求对“文件的内容”的每个更新都同步写入到基础存储设备。 * 明白? */ RandomAccessFile raf1 = new RandomAccessFile(file,"rwd"); System.out.println("开始写入"); raf1.seek(startIndex); now_length += startIndex; int i =1; int len =0; while (((len=is.read(bytes))!=-1)&&!isPaused){ System.out.println("第"+i+"次读入"); raf1.write(bytes, 0, len); System.out.println("第" + i + "次写入"); now_length+=len; i++; publishProgress((int)(now_length/sum_length *100)); } System.out.println("写入完毕"); raf1.close(); conn.disconnect(); } catch (IOException e) { e.printStackTrace(); return e.toString(); } return "success"; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); if(s.equals("success")) downloadListener.OnSuccess(); else downloadListener.OnError(s); } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); downloadListener.OnProgress(values[0]); }}
- MVP 入门 (Android demo解析)
- MVP入门Demo
- Android中的MVP模式入门解析
- Android——MVP架构模式之入门demo
- android mvp demo
- Android MVP Demo
- Android MVP解析实践
- Android MVP架构解析
- android:mvp+dagger2解析
- Android MVP框架解析
- android使用mvp模式实现登陆demo
- Android MVP架构学习(附demo)
- ANdroid mvp 模式 优秀的学习demo
- 浅析Android中MVP及Demo
- Android开发MVP模式解析
- Android开发MVP模式解析
- Android开发MVP模式解析
- Android使用mvp模式入门
- 慎用console.log(),这个方法打印出来的东西,有时候是错误的。 so amazing。。。你真的了解console.log()吗,它不是同步的,即不是实时的,不是实时的,不是实时的
- VS2008+QT添加UI后无法编译
- 测试用例需要注意以下几点(转载)
- A+B Problem c++
- 基石---web开发技术发展史
- MVP 入门 (Android demo解析)
- 程序设计模式(五) C++ 单实例(Singleton)模式
- MyCat:开源分布式数据库中间件
- 按层次遍历二叉树算法
- 利用java实现验证码
- dubbo能做什么
- JZOJ 2112——纪中食堂
- Android 屏幕适配方案(三)
- Lisp in a Box下载及简单使用