MVC
mvc model view controller 模式视图控制器
M: 业务逻辑处理
V:处理数据显示的部分
C:Activity处理用户交互的问题,中间桥梁的作用,解耦的作用。
特点:
耦合性低
扩展性好,利于维护
模块职责划分明确
Model层:
//状态的回调
public interface LoginResultListener {
void result(boolean status);
}
//接口
public interface UserModel {
public void login(String name, String password, LoginResultListener listener);
}
//实现类,进行具体的业务操作
public class UserModelImp implements UserModel {
@Override
public void login(String name, String password, LoginResultListener listener) {
//todo进行相关的操作
}
}
view层:
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="rao.com.mvc.MvcDemoActivity">
android:id="@+id/til_username"
android:layout_width="368dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:hint="用户名"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
android:id="@+id/til_password"
android:layout_width="368dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_username">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"/>
android:id="@+id/bt_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="login"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_password"/>
controller:
public class MvcDemoActivity extends AppCompatActivity {
private TextInputLayout mTilUserName;
private TextInputLayout mTilPassword;
private Button mBtLogin;
private UserModelImp mUserModelImp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvc_demo);
mTilUserName = findViewById(R.id.til_username);
mTilPassword = findViewById(R.id.til_password);
mBtLogin = findViewById(R.id.bt_login);
mUserModelImp = new UserModelImp();
mBtLogin.setOnClickListener(view -> {
mUserModelImp.login(mTilUserName.getEditText().getText().toString(), mTilPassword.getEditText().getText().toString(), new LoginResultListener() {
@Override
public void result(boolean status) {
}
});
});
}
}
在实际的使用过程中xml布局起的作用是十分的有限的,同时Activty需要操作ui和业务逻辑,造成冗余。
MVP
M:依然是业务逻辑和实体类型模型
V:对应于Activity,负责View的绘制以及与用户交互
P:负责完成View于Model间的交互。
mvp和mvc.png
定义model层:
//接口回调
public interface OnLoginListener {
void onLoginResult(int status, User user);
}
//定义业务
public interface IUserBiz {
void login(String username, String password, OnLoginListener listener);
}
//具体的实现类
public class UserBiz implements IUserBiz {
@Override
public void login(String username, String password, OnLoginListener listener) {
// TODO: 2018/3/18 ,进行登录,网络数据等操作
boolean status = true;
if (status) {
listener.onLoginResult(1, new User(username, password));
} else {
listener.onLoginResult(0, null);
}
}
}
view层:
//view相关
public interface IUserLoginView {
String getUsername();
String getPassword();
void showLoading();
void dismissLoading();
void loginStatus(int status);
}
//activity
public class MVPActivity extends AppCompatActivity implements IUserLoginView {
private TextInputLayout mTilUserName;
private TextInputLayout mTilPassword;
private Button mBtLogin;
private ProgressDialog mProgressDialog;
private UserLoginPresenter mUserLoginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
mTilUserName = findViewById(R.id.til_username);
mTilPassword = findViewById(R.id.til_password);
mBtLogin = findViewById(R.id.bt_login);
mProgressDialog = new ProgressDialog(this);
mUserLoginPresenter = new UserLoginPresenter(this);
mBtLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mUserLoginPresenter.login();
}
});
}
@Override
public String getUsername() {
return mTilUserName.getEditText().getText().toString();
}
@Override
public String getPassword() {
return mTilPassword.getEditText().getText().toString();
}
@Override
public void showLoading() {
mProgressDialog.show();
}
@Override
public void dismissLoading() {
mProgressDialog.dismiss();
}
@Override
public void loginStatus(int status) {
//todo,根据操作,去进行响应的跳转
}
}
presenter层:
public class UserLoginPresenter {
private IUserBiz mIUserBiz;
private IUserLoginView mIUserLoginView;
public UserLoginPresenter(IUserLoginView IUserLoginView) {
mIUserLoginView = IUserLoginView;
mIUserBiz = new UserBiz();
}
public void login() {
mIUserLoginView.showLoading();
mIUserBiz.login(mIUserLoginView.getUsername(), mIUserLoginView.getPassword(), new OnLoginListener() {
@Override
public void onLoginResult(int status, User user) {
if (status == 1) {
mIUserLoginView.loginStatus(1);
} else {
mIUserLoginView.loginStatus(0);
}
}
});
}
}
MVVM
View: 对应于Activity和xml,负责View的绘制,以及用户交互。
Model:实体模型,数据存取
ViewModel:负责完成View与Model间的交互,负责业务逻辑。
一把配套使用DataBinding使用,Model与ViewModel双向通信,一般使用数据驱动的方式来实现。view只负责UI操作。
mvvm.png
Android插件化
当业务量大的时候,android的65536方法数的限制。
apk大的时候,动态加载apk:一个宿主的apk,到sd卡中动态的加载apk,
资源加载:通过AssertManagerr类
代码加载 :java中类加载机制
动态加载APk:类加载器,就是将java的字节码加载到虚拟机当中android中有两个重要的
DexClassLoader: 可以从dex文件加载字节码文件,用于动态加载和热更新等。
PathClassLoader:只能加载文件目录下的apk
资源加载:AssertManager反射来加载的
代码加载:反射绑定到activity的生命期,之后在加载
Android热更新
线上检测到严重的 crash
拉出bugfix分支并在分支上修复问题
jenkins构建和补丁生成
app推送或主动拉取文件
将bugfix代码合并到master上
热更新框架:
Dexposed :阿里,基于aop的思想,无需重启,即可修复,通过hook技术,不仅可以修改java方法,还能hook修改android方法,日志记录,性能统计,安全控制,事物处理。(hook基本的方法就是通过hook“接触”到需要修改的api函数入口点,改变它的地址指向新的自定义的函数)
AndFix:阿里,更纯粹的热修护技术,性能较好,工具较完善。
Nuwa:基于dex分包的技术,将dex文件拆分多个dex,编上号,依次加载。
原理:
Android类加载机制
PathClassLoader 加载系统的类,应用类
DexClassLoader 加载Dex文件,apk包
热修复机制
dexElements 会创建dex数组
ClassLoader 会遍历这个数据,根据线上的carch定位到这个dex,将修复好的dex的位置靠前,优先加载这个dex文件。
进程保活
使用场景:定位,推送等等
进程优先级:
前台进程
可见进程(没有前台组件,但是会影响前台界面的进程)
服务进程
后台进程
空进程(缓存)
回收策略:
low memory killer:通过一系列的评分机制,定义进程进行打分,将分数搞的进程判定为bad进程,杀死并释放缓存。(定时检查)
OOM_ODJ:这个阀值,判断进程的优先级,越大进程优先级越低。
保活方案:
系统广播拉活,开机,网络数据变化,不可控制(容易被系统软件禁用)
系统Service机制拉活 :利用的是当系统内存不足而杀掉该Service,可以拉活。杀死Service后,第一5秒拉活,二次10秒后拉活,三次20秒拉活,当Serice被系统拉活三次之后,就不会在被系统进行拉活了。当被安全软件或系统软件静止之后,是不能拉活的。
利用native进程拉活:利用linux的fork机制创建一个进程,监控主进程的存活,这是可以立即对主进程进行拉活。(失效了)
JobScheduler机制拉活,跟native类是,android5.0之后提供的。
帐号同步机制拉活 (不再生效)
UIL
Universe Image Loader图片加载框架
Lint检查
Android Lint是一个静态的代码分析工具,它能够对android项目潜在的bug,可优化的代码,安全性,性能,可用性,可访问性国际化等进行检查。
Lint工作流程:通过配置lint.xml配置,运用lintTool工具,进行相关的额检查
在Src文件目录下,创建lint.xml文件
Lint.png
如果确定java代码写的没有问题,你可以以下的方式使用
//在java代码中的使用,忽略这警告,检查,这是在lint.xml中配置了属性的
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView(savedInstanceState);
}
//在xml文件中的使用,当代码执行到这里的时候就会忽略未使用的资源的问题,不会对编译尽心检查
tools:ingnore="UnusedResources"
自定义lint
使用默认的lint检查不能满足需求,在自定义库的使用,某些属性没有配置 BuiltinlssueRegistry
Kotlin
Kotlin一种基于JVM的编程语言
是对java的一种扩展
Kotlin支持函数式编程
Kotlin类与Java类互相调用
定位carch定位的堆栈的问题
安装Kotlin 插件 在android studio安装