1) 安卓中开发模式的运用,为什么要使用模式?
不同的模式预示着不同的代码结构和代码拆分方法。
代码按照经典的开发模式去写,让我们的代码更加合理化了,更具备扩展性。就像搭建大楼一样,如果代码乱放,可能狗窝都搭建不出来。
A开发人员,你应该把代码写在哪里,怎么调用我架构里面的东西?通过架构限制开发人员,代码不能乱放!
最后把代码整合到一起!
对项目进行模块划分;
搭建整体的项目结构;
如果想走上管理层,就必须学一些架构上的内容!
2) 有哪些常用的开发模式?
常用的模式:mvc、mvp、mvvc
一、用户登录的实现:
新手会把所有的代码都堆砌在activity中,如果功能非常多,就会导致Activity中代码臃肿,进而可能导致线程阻塞以及可扩展性差!
把用户的输入封装成了一个user对象,这样做的好处是什么? 主要用于判断用户的输入是否为空?
进度条对话框的使用;ProgressDialog 类 new ProgressDialog();ProgressDialog.show();ProgressDialog.dismiss()
如何在子线程显示UI?runOnUIThread()方法
此时 activity中 存在联网操作,但是联网操作和对数据库的操作应该是属于模型类的!
public class MainActivity extends AppCompatActivity {
private EditText et_username;
private EditText et_password;
private ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findView();
}
private void findView() {
et_username = (EditText) findViewById(R.id.et_username);
et_password = (EditText) findViewById(R.id.et_password);
dialog=new ProgressDialog(this);
}
//执行登录操作
//修饰符不能private
public void login(View view) {
String username = et_username.getText().toString();
String password = et_password.getText().toString();
//把用户的输入封装到对象里面
final UserInfo userInfo = new UserInfo();
userInfo.name = username;
userInfo.password = password;
Boolean b = checkUserInfo(userInfo);
if (b) {
dialog.show();
//联网是耗时操作,要开启一个子线程
new Thread() {
@Override
public void run() {
//让主线程睡2s
SystemClock.sleep(2000);
if ("111111".equals(userInfo.name) && "111111".equals(userInfo.password)) {
dialog.dismiss();
//注意这里是子线程,不能更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_LONG).show();
}
});
} else {
dialog.dismiss();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_LONG).show();
}
});
}
}
}.start();
} else {
Toast.makeText(MainActivity.this, "用户名或密码为空", Toast.LENGTH_LONG).show();
}
}
//校验用户的输入
private boolean checkUserInfo(UserInfo userInfo) {
if (TextUtils.isEmpty(userInfo.name) || TextUtils.isEmpty(userInfo.password)) {
return false;
} else {
return true;
}
}
}
二、MVC模式在安卓中的体现(把网络请求拆分出去,其实应该对网络请求的结果进行接口回调到activity中):
按照MVC模式对Activity中的代码进行拆分:
把数据往上进行传递 m---->c---->v
模型 (操作数据库或者网络)---->控制层 activity---->界面 layout
比如网络操作:LoginNet 这个类中做什么事情呢:把数据发送到服务器端,并且拿到返回结果。
但是activity中并没有持有LoginNet 类的实例,要在activity中创建这个类的实例,并且调用其中的方法,传递参数(传递对象,map集合等);和界面有关系的代码不要写在网络模型类中(Activity类要持有网络请求类的实例)。
new Thread() {
@Override
public void run() {
LoginNet loginNet = new LoginNet();
boolean result = loginNet.sendLoginInfo(userInfo);
if (result){
dialog.dismiss();
//注意这里是子线程,不能更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_LONG).show();
}
});
}else{
dialog.dismiss();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_LONG).show();
}
});
}
}
}.start();
public class LoginNet {
/**
* 发送用户输入的数据
*
* @param userInfo
* @return
*/
public boolean sendLoginInfo(UserInfo userInfo) {
SystemClock.sleep(2000);
if ("111111".equals(userInfo.name) && "111111".equals(userInfo.password)) {
return true;
} else {
return false;
}
}
}
三、MVP模式在安卓中的体现:
使用mvc模式的缺点是:Activiy中存在两部分代码:业务相关+界面相关 v中的内容相对较少,反而c中的内容较多。
如果将Activity中的业务进行拆分的话: 就是mvp模式;把activity中的业务逻辑拆分出来。
mvp模式:把Activity中的业务逻辑才分出来形成p层,而模型层没有变化。
presenter包,处理和业务相关的代码,不要在activity中处理太多的业务逻辑
public class MainActivity extends AppCompatActivity implements IUserLoginListener {
private EditText et_username;
private EditText et_password;
private ProgressDialog dialog;
private UserLoginPresenter userLoginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findView();
}
private void findView() {
et_username = (EditText) findViewById(R.id.et_username);
et_password = (EditText) findViewById(R.id.et_password);
dialog = new ProgressDialog(this);
userLoginPresenter = new UserLoginPresenter(this);
}
//执行登录操作
//修饰符不能private
public void login(View view) {
String username = et_username.getText().toString();
String password = et_password.getText().toString();
//把用户的输入封装到对象里面
final UserInfo userInfo = new UserInfo();
userInfo.name = username;
userInfo.password = password;
Boolean b = userLoginPresenter.checkUserInfo(userInfo);
if (b) {
dialog.show();
//联网是耗时操作,要开启一个子线程
userLoginPresenter.login(userInfo);
} else {
Toast.makeText(MainActivity.this, "用户名或密码为空", Toast.LENGTH_LONG).show();
}
}
public void success() {
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.dismiss();
Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_LONG).show();
}
});
}
public void fail() {
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.dismiss();
Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_LONG).show();
}
});
}
}
/**
* Created by Administrator on 2016/5/5 0005.
* 主要用于处理业务逻辑
*/
public class UserLoginPresenter {
protected IUserLoginListener view;
public UserLoginPresenter(IUserLoginListener iUserLoginListener) {
this.view = iUserLoginListener;
}
//校验用户的输入
public boolean checkUserInfo(UserInfo userInfo) {
if (TextUtils.isEmpty(userInfo.name) || TextUtils.isEmpty(userInfo.password)) {
return false;
} else {
return true;
}
}
public void login(final UserInfo userInfo){
new Thread() {
@Override
public void run() {
UserLoginNet loginNet = new UserLoginNet();
boolean result = loginNet.sendLoginInfo(userInfo);
if (result) {
//这里如何获取到MainActivity对象呢,调用其中的登录成功与失败的方法
view.success();
} else {
view.fail();
}
}
}.start();
}
}
class UserLoginPresenter{
// 判断用户输入
// 处理登陆的业务逻辑
}
而在P类中,要获取activity的对象,才能调用activity中的方法:登陆成功和登陆失败; 通过P类构造函数获取.
在activity中创建p层的对象,然后调用其中的方法;先声明不去定义,定义的时候要特别注意。
四、MVVP模式异军突起: