1、Model
新建一个base 文件,在里面创建一个BaseModel
这里的其实就是一个空的类,后期的话,我们根据项目需求,再添加内容
package com.traveleasy.electricity.Base;
public abstract class BaseModel {
}
2、View 层
我们的IBaseView 是一个接口类,这里现在就只干一件事情,获取上下文
package com.traveleasy.electricity.Base;
import android.content.Context;
public interface IBaseView {
Context getContext();
}
看到这里,很多人会问,你的View 层就这些吗?答案肯定不是啦,各位看官,请别着急,视图层,我在后面会写。
3、presenter
重点来了,其实在我个人看来,整个MVP 框架中,presenter算是最辛苦的了,因为它要统筹大局,调兵遣将不是。
我先创建一个 IBasePresenter 接口类,这里我们定义一个IBaseView 的泛型,里面定义两个方法,绑定view 和解绑view 。
package com.traveleasy.electricity.Base;
public interface IBasePresenter {
// 绑定
void attachView(V view);
// 解绑
void detechView();
}
下面是重点,BasePresenter 的实现类
这这里,我使用了软引用的方式,来处理presenter 在获取activity 和销毁的时候,造成的内存泄漏的问题。
也运用了一些aop 的思想,即通过动态代理,做统一的逻辑判断。
package com.traveleasy.electricity.Base;
import androidx.lifecycle.LifecycleObserver;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
/**
-
使用软引用的方式让 P 层持有 V 层的引用,并且提供了 getView() 方法给 P 层调用,
-
父类 View 变量进行私有化,防止子类对其进行更改造成的其他错误。我们的 MainPresenter
-
获取 Activity 的引用就可以使用 getView() 方法获得。软引用在内存降到不足的情况下,
-
GC 就会进行优先回收释放那些以软引用方式引用的对象,一定程度上去避免内存溢出(OOM)。
-
@param
*/
public abstract class BasePresenter<V extends IBaseView, M extends BaseModel> implements IBasePresenter {
// 使用软引用,避免内存泄漏,导致OOM 情况发送
protected SoftReference mReferenceView;
protected V mProxyView;
protected M mModel;
@SuppressWarnings(“unchecked”)
@Override
public void attachView(IBaseView view) {
// 使用软引用创建对象
mReferenceView = new SoftReference<>(view);
// 通过使用动态代理,做统一的逻辑判断,aop 思想
mProxyView = (V) Proxy.newProxyInstance(view.getClass().getClassLoader(), view.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
if (mReferenceView == null || mReferenceView.get() == null) {
return null;
}
return method.invoke(mReferenceView.get(), objects);
}
});
// 通过获得泛型类的父类,拿到泛型的接口实例,通过反射来实例化 model
ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
if (type != null) {
Type[] types = type.getActualTypeArguments();
try {
mModel = (M) ((Class<?>) types[1]).newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
@SuppressWarnings(“unchecked”)
public V getView() {
return mProxyView;
}
@SuppressWarnings(“unchecked”)
public M getModel() {
return mModel;
}
@Override
public void detechView() {
mReferenceView.clear();
mReferenceView = null;
}
}
由于Java 单继承的特性,会造成我们在封装BaseActivity 和BaseFragment 时,会有很多的重复代码,BaseActivity 必须继承 Activity 才能启动,而 BaseFragment 又必须继承 Fragment 。
在讲解BaseActivity和BaseFragment 之前,我们先看一下代理模块的代码。
1、新建一个Proxy 接口类
package com.traveleasy.electricity.proxy;
/**
-
由于Java 单继承的特性,这里我们使用proxy 代理,来实现 BaseActivity 和 BaseFragment 重复代码的封装实现
-
这里封装两个接口,一个绑定Presenter, 一个解绑Presenter
*/
public interface IProxy {
void bindPresenter();
void unBindPresenter();
}
2、创建proxyIml 实现类
package com.traveleasy.electricity.proxy;
import com.traveleasy.electricity.Base.BasePresenter;
import com.traveleasy.electricity.Base.IBaseView;
import com.traveleasy.electricity.inject.InjectPresenter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
-
前面我们创建了proxy 代理,里面有解绑和绑定Presenter 的抽象方法
-
这里我们创建一个proxyIml 接口实现类,用来统一代理重复的代码
*/
public class ProxyImpl implements IProxy {
private IBaseView mView;
// 定义一个数组,保存使用过的presenter,用于解绑
private List mInjectPresenters;
public ProxyImpl(IBaseView view) {
this.mView = view;
mInjectPresenters = new ArrayList<>();
}
/**
- 绑定 presenter 的实现
*/
@Override
public void bindPresenter() {
// 获得已经声明的变量,包括私有的
Field[] fields = mView.getClass().getDeclaredFields();
for (Field field : fields) {
// 获取变量上面的注解类型
InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
if (injectPresenter != null) {
try {
Class<? extends BasePresenter> type = (Class<? extends BasePresenter>) field.getType();
BasePresenter mInjectPresenter = type.newInstance();
mInjectPresenter.attachView(mView);
field.setAccessible(true);
field.set(mView, mInjectPresenter);
mInjectPresenters.add(mInjectPresenter);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
throw new RuntimeException(“SubClass must extends Class:BasePresenter”);
}
}
}
}
/**
-
解绑 presenter 的实现
-
避免内存泄漏
*/
@Override
public void unBindPresenter() {
for (BasePresenter presenter : mInjectPresenters) {
presenter.detechView();
}
mInjectPresenters.clear();
mInjectPresenters = null;
}
}
3、再分别创建proxyActivity和 proxyFragment 类
package com.traveleasy.electricity.proxy;
import com.traveleasy.electricity.Base.IBaseView;
/**
- 新建proxyActivity 代理实现类,用来代理activity 中重复的代码
*/
public class ProxyActivity extends ProxyImpl {
public ProxyActivity(IBaseView view) {
super(view);
}
}
package com.traveleasy.electricity.proxy;
import com.traveleasy.electricity.Base.IBaseView;
/**
- 新建proxyFragment 实现类,用于处理fragment 中重复的代码
*/
public class ProxyFragment extends ProxyImpl {
public ProxyFragment(IBaseView view) {
super(view);
}
}
如何做好面试突击,规划学习方向?
面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。
学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。
同时我还搜集整理2020年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。
在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。
[外链图片转存中…(img-aKn3BKeu-1714285084276)]
在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多。
[外链图片转存中…(img-DBODOQhm-1714285084277)]
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!