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]);    }}
0 0
原创粉丝点击