美文网首页
Android 架构 之 MVC

Android 架构 之 MVC

作者: acd614d363f2 | 来源:发表于2019-07-09 10:42 被阅读0次

第一次写博客,好紧张。就怕自己写不好,语言组织不好,标点符号使用错误。大家如果在阅读的过程中发现有错别字、病句、技术错误等问题,欢迎留言 或者给我发邮件 39156263@qq.com

首先说下在接下来的一系列的文章主要是说MVC、MVP、MVVM。今天我们主要将MVC部分,但是本文的重点不是说 MVC 如何使用、有什么优点、适应什么场景等。我们今天要说的是 为什么要使用MVC 或 MVP。我相信很多同学自己内心对于这个问题是没有一个明确的答案的。

好了,开始今天的主题 MVC。 MVC它的全称是 Model View Controller 它是一种架构设计模式。 它分三层 model、view、controller。 在Android中 model是模型层 指的是java bean,View是视图层 指的是各种layout文件 和 自定义的view,controller是控制层 指的是Activity 和 Network。MVC在java领域是非常成熟的,目前来说的话,后端绝大部分还是使用的这种模式,但是移动端使用的越来越少了。 下图是MVC的模型图

1562637362141.jpg

它的具体流程是 首先View层接收到用户的操作,然后View层将用户的操作交给Controller,然后Controller完成具体的业务逻辑,最后将得到的结果封装成model,交给View刷新。从模型图我们可以看出 Controller是作为媒介处于View 和 Model之间,model 和 view之间有紧密的联系,耦合性偏强。Controller既要做View层的职责,又要做model层的职责,这样就违反了面向对象的单一原则。

接下来我们看一个典型的MVC代码。首先新建一个项目 结构如下:


image

activity_main.xml文件代码如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <Button
        android:id="@+id/mLoadingImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="下载图片"/>

   <ImageView
       android:id="@+id/mImageView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
       android:layout_marginTop="20dp"/>
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity implements Callback{

    private static final String IMG_PATH = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1563193466&di=93ef19d7a55e5329da4ba468a4af029d&imgtype=jpg&er=1&src=http%3A%2F%2Fwww.liuhaihua.cn%2Fwp-content%2Fuploads%2F2018%2F05%2F6vm2y2I.jpg";
    private Button mLoadingImage;
    private ImageView mImageView;

    private Handler mHandler = new Handler(new Handler.Callback(){

        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what){
                case ImageDownloader.SUCCESS:{
                    mImageView.setImageBitmap((Bitmap) msg.obj);
                    break;
                }

                case ImageDownloader.ERROR:{
                    Toast.makeText(MainActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
                    break;
                }
            }

            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImageView = findViewById(R.id.mImageView);
        mLoadingImage = findViewById(R.id.mLoadingImage);

        mLoadingImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ImageBean imageBean = new ImageBean();
                imageBean.setUrlPath(IMG_PATH);

                new ImageDownloader().down(imageBean, MainActivity.this);
            }
        });
    }

    @Override
    public void callback(int resultCode, ImageBean imageBean) {

        Message msg = mHandler.obtainMessage(resultCode);
        msg.obj = imageBean.getBitmap();
        mHandler.sendMessage(msg);
    }
}

Callback.java

public interface Callback {

    /**
     *
     * @param resultCode 返回请求的code
     * @param imageBean 返回的结果
     */
    void callback(int resultCode, ImageBean imageBean);
}

ImageBean.java

public class ImageBean {
    //网络图片地址
    private String urlPath;
    //bitmap对象
    private Bitmap bitmap;

    public String getUrlPath() {
        return urlPath;
    }

    public void setUrlPath(String urlPath) {
        this.urlPath = urlPath;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }
}

ImageDownloader.java

public class ImageDownloader {

    static final int SUCCESS = 200;
    static final int ERROR = 404;


    public void down(ImageBean imageBean, Callback callback) {

        new Thread(new DownRunnable(imageBean, callback)).start();
    }

    static final class DownRunnable implements Runnable{

        private ImageBean imageBean;
        private Callback callback;
        public DownRunnable(ImageBean imageBean, Callback callback) {
            this.imageBean = imageBean;
            this.callback = callback;
        }

        @Override
        public void run() {

            try {
                URL url = new URL(imageBean.getUrlPath());
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setConnectTimeout(5000);
                httpURLConnection.setRequestMethod("GET");
                if(httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
                    Bitmap bitmap = BitmapFactory.decodeStream(httpURLConnection.getInputStream());
                    showUi(SUCCESS, bitmap);
                }else {
                    showUi(ERROR, null);
                }
            } catch (Exception e) {
                e.printStackTrace();
                showUi(ERROR, null);
            }

        }

        private void showUi(int code, Bitmap bitmap) {
            if(callback != null){
                imageBean.setBitmap(bitmap);
                callback.callback(code, imageBean);
            }
        }
    }
}

我们可以看到 当“下载图片”按钮接收到点击事件后,将事件传递给MainActivity 然后 MainActivity 将请求交给ImageDownloader处理,ImageDownloader开启异步线程处理完成后 通过接口回调返回ImageBean, 最后MainActivity拿到ImageBean通过Handler 更新UI。 从这就可以看出其实MainActivity 除了承担了控制层的工作外 还承担了View层的工作。

在实际的项目需求中,可能会有一些比较耗时的操作需要开启一个子线程处理,我们修改MainActivity代码如下:

public class MainActivity extends AppCompatActivity implements Callback{

    private static final String IMG_PATH = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1563193466&di=93ef19d7a55e5329da4ba468a4af029d&imgtype=jpg&er=1&src=http%3A%2F%2Fwww.liuhaihua.cn%2Fwp-content%2Fuploads%2F2018%2F05%2F6vm2y2I.jpg";
    private Button mLoadingImage;

    private ImageView mImageView;

    private Handler mHandler = new Handler(new Handler.Callback(){

        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what){
                case ImageDownloader.SUCCESS:{
                    mImageView.setImageBitmap((Bitmap) msg.obj);
                    break;
                }

                case ImageDownloader.ERROR:{
                    Toast.makeText(MainActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
                    break;
                }
            }

            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImageView = findViewById(R.id.mImageView);
        mLoadingImage = findViewById(R.id.mLoadingImage);


        mLoadingImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ImageBean imageBean = new ImageBean();
                imageBean.setUrlPath(IMG_PATH);

                new ImageDownloader().down(imageBean, MainActivity.this);
            }
        });
        
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                SystemClock.sleep(50000);
            }
        }).start();
    }

    @Override
    public void callback(int resultCode, ImageBean imageBean) {

        Message msg = mHandler.obtainMessage(resultCode);
        msg.obj = imageBean.getBitmap();
        mHandler.sendMessage(msg);
    }
}

就是在onCreate方法中 启动了一个线程,在线程中 休眠50000毫秒 模拟耗时操作。
然后我们运行app 打开 Profiler 的 Memory 然后点击返回键退出MainActivity页面, 然后点击Dump Java Heap 如下:


image.png

可以看到,MainActivity内存溢出了。这就是MVC最致命的缺点,容易导致内存溢出。

相关文章

  • MVC / MVP / MVVM 架构模式

    MVC / MVP / MVVM 架构模式Android架构,即为开发Android时使用的架构。Android的...

  • MS目录

    MS前言:经验篇 一、MS(1):Android之架构篇 一、架构相关1、MVC,MVP,MVVM;2、Rxjav...

  • MVP模式分析

    Google Sample MVP Android架构蓝图 目前Android主流的开发架构:原生开发(MVC),...

  • Android MVP简析

    MVC 说到软件的架构,最基本的就是MVC架构,并且目前为止,大多数Android APP还是采取MVC架构开发的...

  • Android的mvc架构

    Android的mvc架构 mvc架构主要是Model层,View层,Controller(控制器)。 Model...

  • Android技术博文汇总

    架构 MVC,MVP 和 MVVM 的图示 浅谈 MVP in Android Android项目重构之路:架构篇...

  • Android 架构 之 MVC

    第一次写博客,好紧张。就怕自己写不好,语言组织不好,标点符号使用错误。大家如果在阅读的过程中发现有错别字、病句、技...

  • 转载:mvc、mvp、mvvm使用关系总结

    标签:android/架构 MVC MVC全名是Model View Controller,是模型(model)-...

  • Android开发热门前沿知识,看这些就够啦

    1. Android架构设计模式 MVC架构设计模式:MVC全名是Model View Controller,是模...

  • Android开发热门前沿知识

    1. Android架构设计模式 MVC架构设计模式:MVC全名是Model View Controller,是模...

网友评论

      本文标题:Android 架构 之 MVC

      本文链接:https://www.haomeiwen.com/subject/tkutkctx.html