安卓面试基础4

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
// Model
public class UserModel {
private String name;
private String email;

// Getters and setters
}

// View
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);
}
}

// Controller
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
// Model
public class UserModel {
private String name;
private String email;

// Getters and setters
}

// View Interface
public interface UserView {
void showUser(String name, String email);
}

// View (Activity)
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);
}
}

// Presenter
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 示例代码

使用LiveDataViewModel的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
// Model
public class UserModel {
private String name;
private String email;

// Getters and setters
}

// View (Activity)
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());
}
});
}
}

// ViewModel
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限制

  1. 代码动态加载
  2. 资源动态加载 AssetsManager +反射
  3. 资源混淆
  4. 动态加载apk DexClassLoader + 反射
  5. 热更新 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系统(尤其是新版本)对后台进程和任务有严格的限制。