中级程序员的写法
/**
* 跳转到待收货页面
*/
public void jumpWaitReceiving() {
// 判断当前有没有网络
if(CheckNetUtil.isNetworkAvailable(this)) {
// 当前有网络我才跳转,进入待收货页面
Intent intent = new Intent(this, WaitReceivingActivity.class);
startActivity(intent);
}
}
/**
* 跳转到我的钱包页面
*/
public void jumpMineWallet() {
if(CheckNetUtil.isNetworkAvailable(this)) {
Intent intent = new Intent(this, MineWalletActivity.class);
startActivity(intent);
}
}
高级程序员的写法
通过一行注解实现
/**
* 跳转到待收货页面
*/
@CheckNet
public void jumpWaitReceiving() {
Intent intent = new Intent(this, WaitReceivingActivity.class);
startActivity(intent);
}
/**
* 跳转到我的钱包页面
*/
@CheckNet
public void jumpMineWallet() {
Intent intent = new Intent(this, MineWalletActivity.class);
startActivity(intent);
}
AOP
全称“Aspect Oriented Programming”,面向切面编程,由于面向对象的思想要求高内聚,低耦合的风格,使模块代码间的可见性变差,对于埋点,日志输出等需求,就会变的十分复杂,如果手动编写代码,入侵性很大,不利于扩展,AOP应运而生
二、使用场景
当我们需要在某个方法运行前和运行后做一些处理时,便可使用AOP技术。具体有:
- 统计埋点
- 日志打印/打点
- 数据校验
- 行为拦截
- 性能监控
- 动态权限控制
AOP使用场景
1>:动态代理:比如MVP里面的 每次都要判断 M层是否为空;
2>:比如我们经常在Application中做一些 Activity的生命周期的监听;
3>:基于第三方的一些编译工具 AspectJ
实现原理:
不是用系统的编译器,用di san fAjpectJ的编译器
实现步骤:
第一步:添加AspectJ依赖
根目录下
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">classpath 'org.aspectj:aspectjtools:1.8.9' classpath 'org.aspectj:aspectjweaver:1.8.9'</pre>
项目下:
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">implementation 'org.aspectj:aspectjrt:1.8.13'</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">第二步: 定义注解 </pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">第二三:</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">切点:从那个入口</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">切面:切点之后会形成切面</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">具体:</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">1.获取注解</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">2.是否有网络</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">3.没有网络返回</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">注意:如何获取context?如何获取方法签名?</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">为什么要获取函数的签名?
</pre>
<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;"> <pre style="margin: 8px 0px; font-family: "JetBrains Mono", monospace;">/**
-
Created by peng on 2021/12/27. * 处理网络检测切面 */ @Aspect public class SectionAspect {
/**
-
找到处理的切点 * 因为有一个项目可以有多个切点 * * *(..) 可以处理所有的方法 */ @Pointcut("execution(@com.example.gavin.apttest.CheckNet * *(..))")
public void checkNetBehavior() {}
/**
-
处理切面 * 就是上面的方法checkNetBehavior() */ @Around("checkNetBehavior()")
public Object checkNet(ProceedingJoinPoint joinPoint) throws Throwable {
Log.e("TAG", "checkNet");
// 做埋点 日志上传 权限检测, 网络检测
// 网络检测 // 1.获取 CheckNet 注解 NDK 图片压缩 C++ 调用Java 方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法的签名
CheckNet checkNet = signature.getMethod().getAnnotation(CheckNet.class);
if (checkNet != null) {
// 2.判断有没有网络 怎么样获取 context? //获取context,通过getThis()
Object object = joinPoint.getThis();// View Activity Fragment ; getThis() 当前切点方法所在的类
Context context = getContext(object);
if (context != null) {
if (!isNetworkAvailable(context)) {
// 3.没有网络不要往下执行
Toast.makeText(context,"请检查您的网络",Toast.LENGTH_LONG).show();
return null; }
}
}
return joinPoint.proceed(); //调用proceed,和ASM一样
}/**
-
通过对象获取上下文 * * @param object
-
@return
*/
private Context getContext(Object object) {
if (object instanceof Activity) {
return (Activity) object;
} else if (object instanceof Fragment) {
Fragment fragment = (Fragment) object;
return fragment.getActivity();
} else if (object instanceof View) {
View view = (View) object;
return view.getContext();
}
return null;
}/**
-
检查当前网络是否可用 * * @return
*/
private static boolean isNetworkAvailable(Context context) {
// 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
// 获取NetworkInfo对象
NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo(); if (networkInfo != null && networkInfo.length > 0) {
for (int i = 0; i < networkInfo.length; i++) {
// 判断当前网络状态是否为连接状态
if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
}</pre> </pre>
网友评论