MVC/MVP/MVVM设计模式详细讲解
在Android开发中,设计模式有助于组织代码,提高代码的可维护性和可扩展性。MVC、MVP和MVVM是三种常见的设计模式。以下是对这三种设计模式的详细讲解,包括它们的基本概念、结构图、优缺点以及在实际开发中的应用示例。
1. MVC(Model-View-Controller)
1.1 基本概念
MVC是一种将应用程序分为三部分的设计模式:
- Model:负责处理数据和业务逻辑。
- View:负责显示数据和与用户交互。
- Controller:负责处理用户输入并更新Model和View。
1.2 结构图
1 2 3
| +----------+ +----------+ +----------+ | View | <--------> |Controller| <--------> | Model | +----------+ +----------+ +----------+
|
1.3 优缺点
优点:
缺点:
- 在复杂应用中,Controller可能变得过于庞大。
1.4 示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public class UserModel { private String name; private String email;
}
public class MainActivity extends AppCompatActivity { private TextView nameTextView; private EditText emailEditText; private Button saveButton; private UserController userController;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
nameTextView = findViewById(R.id.nameTextView); emailEditText = findViewById(R.id.emailEditText); saveButton = findViewById(R.id.saveButton); userController = new UserController(this);
saveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { userController.saveUser(emailEditText.getText().toString()); } }); }
public void updateView(String name) { nameTextView.setText(name); } }
public class UserController { private UserModel userModel; private MainActivity view;
public UserController(MainActivity view) { this.view = view; userModel = new UserModel(); }
public void saveUser(String email) { userModel.setEmail(email); view.updateView(userModel.getName()); } }
|
2. MVP(Model-View-Presenter)
2.1 基本概念
MVP是MVC的一种改进,通过引入Presenter来分离View和Model,使得每个部分更清晰:
- Model:负责数据和业务逻辑。
- View:负责显示数据和与用户交互。
- Presenter:作为中间人,处理View的用户交互并更新Model和View。
2.2 结构图
1 2 3
| +----------+ +----------+ +----------+ | View | <--------> |Presenter | <--------> | Model | +----------+ +----------+ +----------+
|
2.3 优缺点
优点:
- View和Model完全分离,代码更清晰。
- Presenter更容易测试。
缺点:
2.4 示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| public class UserModel { private String name; private String email;
}
public interface UserView { void showUser(String name, String email); }
public class MainActivity extends AppCompatActivity implements UserView { private TextView nameTextView; private EditText emailEditText; private Button saveButton; private UserPresenter presenter;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
nameTextView = findViewById(R.id.nameTextView); emailEditText = findViewById(R.id.emailEditText); saveButton = findViewById(R.id.saveButton); presenter = new UserPresenter(this);
saveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { presenter.saveEmail(emailEditText.getText().toString()); } }); }
@Override public void showUser(String name, String email) { nameTextView.setText(name); } }
public class UserPresenter { private UserView view; private UserModel userModel;
public UserPresenter(UserView view) { this.view = view; userModel = new UserModel(); }
public void saveEmail(String email) { userModel.setEmail(email); view.showUser(userModel.getName(), userModel.getEmail()); } }
|
3. MVVM(Model-View-ViewModel)
3.1 基本概念
MVVM通过引入ViewModel来简化View和Model之间的交互:
- Model:负责数据和业务逻辑。
- View:负责显示数据和与用户交互。
- ViewModel:充当View的抽象,处理数据和业务逻辑,通常与数据绑定库(如Data Binding或LiveData)一起使用。
3.2 结构图
1 2 3
| +----------+ +----------+ +----------+ | View | <--------> |ViewModel | <--------> | Model | +----------+ +----------+ +----------+
|
3.3 优缺点
优点:
- View与Model完全分离,代码更清晰。
- ViewModel可以复用,且更容易测试。
缺点:
3.4 示例代码
使用LiveData
和ViewModel
的MVVM示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| public class UserModel { private String name; private String email;
}
public class MainActivity extends AppCompatActivity { private TextView nameTextView; private EditText emailEditText; private Button saveButton; private UserViewModel userViewModel;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
nameTextView = findViewById(R.id.nameTextView); emailEditText = findViewById(R.id.emailEditText); saveButton = findViewById(R.id.saveButton);
userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
userViewModel.getUser().observe(this, new Observer<UserModel>() { @Override public void onChanged(UserModel userModel) { nameTextView.setText(userModel.getName()); } });
saveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { userViewModel.saveEmail(emailEditText.getText().toString()); } }); } }
public class UserViewModel extends ViewModel { private MutableLiveData<UserModel> userLiveData; private UserModel userModel;
public UserViewModel() { userLiveData = new MutableLiveData<>(); userModel = new UserModel(); }
public LiveData<UserModel> getUser() { return userLiveData; }
public void saveEmail(String email) { userModel.setEmail(email); userLiveData.setValue(userModel); } }
|
4. 总结
三种设计模式各有优缺点,选择哪一种取决于具体的项目需求和团队的熟悉程度:
mvc与mvp的区别
mvc中view视图与model直接交互
mvp中view视图不会与model直接交互
MVC:适用于简单应用,但在大型项目中可能变得复杂。
MVP:提供了更好的分离关注点和可测试性,但需要更多样板代码。
MVVM:与数据绑定库结合使用,提供了更好的分离关注点、可复用性和可测试性
android插件化
64k限制
- 代码动态加载
- 资源动态加载 AssetsManager +反射
- 资源混淆
- 动态加载apk DexClassLoader + 反射
- 热更新 Dexposed hook
进程保活
前台进程,可见进程,服务进程,后台进程,空进程
low memory killer 策略
利用Native进程保活 5.0以后失效,使用JobScheduler
1. 基本概念
由于Android系统为了优化内存管理,会在需要时终止后台进程。因此,开发者需要采取一些策略来延长应用进程的生命周期。
2. 常见的进程保活策略
2.1 前台服务(Foreground Service)
将应用的某些功能放在前台服务中运行,使其更不容易被系统回收。
- 实现方法:
- 启动服务并调用
startForeground()
。
- 提供持续显示的通知以告知用户服务正在运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class MyForegroundService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { Notification notification = new NotificationCompat.Builder(this, "CHANNEL_ID") .setContentTitle("Service Running") .setContentText("Foreground Service") .setSmallIcon(R.drawable.ic_launcher) .build();
startForeground(1, notification); return START_STICKY; }
@Override public IBinder onBind(Intent intent) { return null; } }
|
2.2 AlarmManager定时唤醒
通过AlarmManager
定期唤醒应用,执行特定任务。
- 实现方法:
- 设置周期性闹钟,通过
PendingIntent
触发服务。
1 2 3 4 5 6
| AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(this, MyService.class); PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0); alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
|
2.3 JobScheduler
使用JobScheduler
在条件满足时执行后台任务,可以减少资源消耗。
- 实现方法:
- 定义
JobService
,并通过JobScheduler
调度任务。
1 2 3 4 5 6 7 8 9 10 11 12
| public class MyJobService extends JobService { @Override public boolean onStartJob(JobParameters params) { return true; }
@Override public boolean onStopJob(JobParameters params) { return true; } }
|
2.4 广播接收器
监听系统广播,如网络变化、设备启动等,唤醒应用。
1 2 3 4 5 6 7
| public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent serviceIntent = new Intent(context, MyService.class); context.startService(serviceIntent); } }
|
3. 进程保活的注意事项
- 电量消耗:频繁唤醒或长时间运行服务会增加电量消耗。
- 用户体验:不当的保活策略可能导致不良的用户体验。
- 系统限制:Android系统(尤其是新版本)对后台进程和任务有严格的限制。