android mvc例子,Android MVC

概念

MVC 全名 Model View Controller即Model(模型) View(视图) Controller(控制器),一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

注:mvc、mvp、mvvm等是框架,工厂模式策略模式等是设计模式,两者不要混淆。

这里推荐笔者另一文MVP for Android

3e7573126514

示意图1

MVC for Android

理解MVC:

我们通过示意图1来理解MVC是如何在Android上运作起来的。

View:与用户交互,响应用户的操作;

Control:接收View的事件请求、数据等,通知Model;

Model:Model接收到Control指令后,独立运作,将结果通知给View;

例如:User现在要搜索联系人名字为Jack的号码是多少

View:在EditTextView中填写了Jack,点击搜索按钮Button;

Control:接收到交互View发出的搜索请求,和字符串Jack,通知Model进行数据查询;

Model:Model接受到关键字Jack,进行名字匹配,完毕后,通过接口给View发送号码,通知View显示;

MVC特点:

1、通常Android中Activity充当Control,布局中的各种View控件充当View;因为Activity既有Control又有View,所以Control和View有少量的耦合性;

2、MVC把View和Model层很好的分离,启到了很好的解耦作用,耦合性低,减少代码模块之间的相互影响;

3、耦合性低,可方便添加需求,扩展代码,减少代码的修改量;

3、M、V、C三层模块分明,利于代码维护;

实例代码

就以上述搜索联系人例子,看MVC在Android的具体用法

3e7573126514

例子就三个控件,EditText输入名字,Button搜索联系人,TextView显示搜索结果,布局如下:

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/activity_main"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:orientation="vertical"

tools:context="example.yink.mvc.MainActivity">

android:id="@+id/et_name"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@string/et_name"/>

android:id="@+id/bt_search"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/btn_search"/>

android:id="@+id/tv_numbere"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@string/tv_num"/>

那么布局里面的这些控件就可以视为View了。接下来是Control

public class MainActivity extends AppCompatActivity implements SearchNumListener, View.OnClickListener{

private EditText mEditTextName;

private Button mButtonSearch;

private TextView mTExtViewNum;

private SearchNumModelImpl mSearchNumModelImpl;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

mSearchNumModelImpl = new SearchNumModelImpl(this);

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1);

}

@Override

public void onSuccess(String num) {

mTExtViewNum.setText(num);

}

@Override

public void onError() {

Toast.makeText(this,"no number",Toast.LENGTH_SHORT).show();

}

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.bt_search:

mSearchNumModelImpl.getNum(mEditTextName.getText().toString(),this);

break;

}

}

private void initView() {

mEditTextName = (EditText) findViewById(R.id.et_name);

mButtonSearch = (Button) findViewById(R.id.bt_search);

mTExtViewNum = (TextView) findViewById(R.id.tv_numbere);

mButtonSearch.setOnClickListener(this);

}

}

MainActivity先初始化加载好要显示的View,EditText、Button、TextView;然后 new了一个SearchNumModelImpl搜索联系人的Model。

User输入完名字Jack后,点击搜索,Activity作为Control得到交互信息,Jack,通过SearchNumModelImpl的getNum获得号码。

public class SearchNumModelImpl implements SearchNumInterface {

private Context mContext;

public SearchNumModelImpl(Context context) {

mContext = context;

}

@Override

public void getNum(String name, SearchNumListener listener) {

if (isEmptyString(name) || isEmptyString(number(name))) {

listener.onError();

} else {

listener.onSuccess(number(name));

}

}

public String number(String name) {

Cursor cursor = mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

while (cursor.moveToNext()) {

String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));

String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));

if (name.equals(contactName)) {

Cursor phone = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);

if (phone.moveToNext()) {

String phoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

return phoneNumber;

}

}

}

return null;

}

public static boolean isEmptyString(String str) {

return str == null || str.trim().length() == 0;

}

}

SearchNumModelImpl就进行了联系人的查询操作,并返回查询到的号码;如果查询成功调用接口 listener.onSuccess返回number,如果查询失败listener.onError通知view查询失败;

这里我们看下这两个接口

public interface SearchNumListener {

void onSuccess(String num);

void onError();

}

SearchNumListener有两个方法,作用就是model进行一系列操作后方便通知View结果,可以是查询联系人,也可以是网络请求,也可以是算法等等;是和View的一个桥梁

public interface SearchNumInterface {

void getNum(String name, SearchNumListener listener);

}

SearchNumInterface的作用是对getNum方法的一个封装,具体的实现是通过SearchNumModelImpl

比如我后期要对查询联系人进行修改,不是从系统的数据库里进行查找,需要到第三方联系人Abc.apk数据库里去匹配联系人,那么我只需要新写一个AbcSearchNumModelImpl的实现类继承SearchNumInterface这个接口就可以了。

3e7573126514

整个过程如下:

View交互:User点击button

Control:响应点击,发送name给Model;

Model:通过名字查询号码,返回给View显示;

这就是MVC模型的简单例子。

思考

一个好的框架可以让我们在开发当中更高效的开发和维护,MVC就是常用的框架之一,但是若是一个很简单的apk则不必试用框架反而显得代码过于冗余。而在实际开发中,则需要我们更多的思考,比如Control,是哪些操作应该放在Control里呢?如果处理不当,那么View和Control过多耦合,就不能达到我们预期想要的结果。那么开发当中又有哪些方法能够避免这些问题?

笔者另外一文例子和本文相同Android MVP,方便区分和理解两种框架

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值