Android AOP方案对比
什么是面向切面编程(Aop)面向切面编程(AOP,Aspect-Oriented Programming)是一种编程范式,它允许开发者通过切面(Aspect)来模块化横切关注点,并将它们封装成可重用的组件。横切关注点是指那些存在于应用程序中多个模块中的功能,它们通常与应用程序的核心业务逻辑无关,例如日志记录、事务管理、安全性等。
在面向切面编程中,切面是一个模块化的单元,它横跨一个或多个对象,提供了在应用程序中的多个位置进行代码重用的机制。切面可以定义一组横切关注点,并将它们与应用程序的核心业务逻辑分离开来。这样,当需要修改或者添加新的横切关注点时,只需要修改或者添加对应的切面,而不需要修改核心业务逻辑代码。
面向切面编程的核心概念是切面、连接点、通知、切点和增强。其中,切面是关注点的模块化单元,连接点是在应用程序中可以插入切面的点,通知是切面在连接点处执行的代码,切点是一组连接点的集合,而增强是在切点处执行的通知的行为。
总的来说,面向切面编程通过将横切关注点与核心业务逻辑进行解耦,提高了代码的模块化性、可维护性和可重用性,使得应用程序更易于理解、扩展和维护。
主流AOP技术分类首先 ...
Android Binder机制解析
在Android中跨进程通信被频繁使用,比如当用户点击按钮跳转到一个新的Activity页面,这时我们的app进程会和SystemServer进程频繁通信来创建一个新的Activity,这种例子不胜枚举。所以作为一个Android应用的开发者,理应理解其原理。在讨论Binder前,我们先列举下Linux支持的进程通信方式都有哪些。
Android进程间通信场景
Linux进程通信方式
为什么要自己实现ipc
通过对比,分别介绍优点
使用?
上层拓展?
Linux进程通信方式
管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
命名管道 (named pipe) : 命名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
消息队列( message queue ) ...
自定义View流程
Android系统提供了丰富的视图组件,如TextView、ImageView、Button等,以及一些容器组件,如ConstraintLayout、LinearLayout、FrameLayout等,使用这些组件可以实现各种常见的视图效果。然而,在某些情况下,我们可能需要实现更加个性化和独特的展示效果,而系统提供的组件很难满足这种需求。这时候,就需要使用自定义View来实现了。
自定义View的实现流程大致分为以下几方面:
创建自定义View类继承自View/现有控件类
View的测量过程onMeasure
View的绘制过程onDraw
下面将依序实现各流程
创建自定义View类继承View创建一个自定义View类自定义View类可以直接继承自View实现,也可以根据业务场景直接继承自特定的控件。
重写构造方法1234567891011public class MyView extends View { public MyView(Context context) { super(context, null); i ...
WebView加载提速方案
以公司的新闻资讯类产品为例,总结一下加载提速方案。首先对于新闻资讯页面来说,不同的页面之间有很多重复的资源,这些资源可以直接保存在本地复用:将css、js和图片文件放到Assets中,应用可以拦截这部分的请求转而加载这些文件。其次,WebView的新建与初始化也是比较耗时的,因此可以使用WebView缓存池进行复用。再次是预加载,在浏览信息流时,详情页url的主要html内容已经被下载到了内存中,可以直接通过WebView.loadDataWithBaseUrl()加载。接下来介绍这3种方案的具体实现。
资源缓存WebView 请求任何资源时都会回调shouldInterceptRequest()方法,此时可以将 WebView 需要请求的资源替换为本地资源以提升加载速度。 本地资源可以保存在Assets或文件系统中,如果保存在Assets中,文件的安全性会得到保证,没有出错或者被修改的风险,但是无法实时更新,只能依赖客户端发版更新文件;如果保存在文件系统中,可以做到实时更新,但是下载文件时可能出错,使用时需要对文件进行校验。
这里以保存在Assets中为例,当WebView回调sho ...
Android中Context的说明
简单来说,Context 是一个接口,它包含有关应用程序环境的全局信息。Context 允许访问特定于应用程序的资源(例如字符串、主题、资产等)和类。同样,它处理应用程序级别的操作,如启动Activity、发送和接收广播。简而言之,Context 表示获取环境数据的句柄。
在这里你可以看到 Context 的常见用法。
同样地,下面列表中是一些 Context 的示例方法。正如我们在开始时所说的,你可以使用 Context 访问应用程序特定的资源。
getAssets() 获取资源管理器
getResources() 获取资源
getPackageManager() 获取包管理器
getString() 获取字符串
getSharedPrefsFile() 获取共享首选项文件
有两种主要类型的上下文。
1- Application Context
这种类型的上下文直接与应用的生命周期相关联。你可以通过 getApplicationContext() 方法访问它。
2- Activity Context
这种类型的上下文与Activity的生命周期相关联。你可以通过 ge ...
Activity启动流程
Activity是一种展示型组件,用于展示给用户一个可以交互的页面。Activity是Android中最重要的组件,对用户来说,所有的Activity就是一个App的全部,而其他组件用户是不能直接感知的。在开发层面,要启动一个Activity可以使用Intent,分显式和隐式,并且还可以设置Activity的启动模式。
Activity启动的发起下面我们就来对Activity的工作流程进行梳理,达到对Activity整体流程的掌握。从startActivity方法开始,会走到startActivityForResult方法:
12345678910111213141516171819202122 1 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, 2 @Nullable Bundle options) { 3 if (mParent == null) { 4 options = ...
RecyclerView缓存机制
A flexible view for providing a limited window into a large data set.
缓存层级12345678public final class Recycler { final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>(); ArrayList<ViewHolder> mChangedScrap = null; final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>(); RecycledViewPool mRecyclerPool; private ViewCacheExtension mViewCacheExtension; }
从上面的代码片段我们可以看到这个类声明了五个成员变量:
mAttachedScrap:我们可 ...
浅析Handler原理
Android的异步消息处理模型主要是由Handler、Looper、MessageQueue组成的。通过Handler我们很容易的实现在UI线程与其他线程之间的消息传递。
基本概念Handler一个Handler用于发送或者处理与一个线程的消息队列(MessageQueue)相关联的消息或者可执行对象(Runnable)。每个Handler实例跟一个线程以及线程消息队列相关联。当新建一个Handler实例时,该Handler就跟创建它的线程以及线程队列绑定在一起。此后,它就会将消息以及可执行对象传送到消息队列中,并且处理从消息队列中出来的消息。
Handler有两个用途:(1)对消息以及可执行对象进行调度,以便未来某个时间点执行之;(2)向另一个线程发送一个消息或者执行对象。
当应用程序进程创建完成后,主线程负责运行一个用于管理应用内的对象,如activities,broadcast receivers的消息队列。用户可以创建自己的线程,通过一个Handler跟主线程进行通信。
LooperLooper用于为线程运行一个消息循环;线程默认是没有消息循环的,要建立一个新的Looper, ...
浅谈JVM原理
JVM运行时内存区域JVM 管理的内存被划分为以下运行时数据区域:程序计数器、虚拟机栈、本地方法栈、堆、方法区。
这6块区域按是否被线程共享,可以分为二大类:
一类是每个线程所独享的:
PC Register:也称为程序计数器, 记录每个线程当前执行的指令信息(eg:当前执行到哪一条指令,下一条该取哪条指令)
JVM Stack: 也称为虚拟机栈,记录每个栈帧(Frame)中的局部变量、方法返回地址等。它的结构如下:
线程中每次有方法调用时,会创建Frame,方法调用结束时Frame销毁。
Native Method Stack: 本地(原生)方法栈,顾名思义就是调用操作系统原生本地方法时,所需要的内存区域。
上述3类区域,生命周期与Thread相同,即:线程创建时,相应的内存区创建,线程销毁时,释放相应内存。
另一类是所有线程共享的:
Heap:即鼎鼎大名的堆内存区,也是GC垃圾回收的主站场,用于存放类的实例对象及Arrays实例等。
注:Heap被所有线程共享,如果严格意义上抠字眼的话,也不完正确,事实上,由于TLAB的存在,为了防止并发对象分配时,多个对象分 ...
详解Java类加载机制
Java 虚拟机的启动是通过引导类加载器 ( Bootstrap Class Loader ) 创建一个初始类 (Initial Class ) 来完成,这个类是由虚拟机的具体实现指定。紧接着,Java虚拟机链接这个初始类,初始化并调用它的 public void main(String[])方法。之后的整个执行过程都是由对此方法的调用开始。执行 main 方法中的 Java 虚拟机指令可能会导致 Java 虚拟机链接另外的一些类或接口,也可能会调用另外的方法。
可能在某种 Java 虚拟机的实现上,初始类会作为命令行参数被提供给虚拟机。当然,虚拟机实现也可以利用一个初始类让类加载器依次加载整个应用。初始类当然也可以选择组合上述的方式来工作。
类的加载流程当 Java 虚拟机将 Java 源码编译为字节码之后,虚拟机便可以将字节码读取进内存,从而进行解析、运行等整个过程,这个过程我们叫:Java 虚拟机的类加载机制。JVM 虚拟机执行 class 字节码的过程可以分为七个阶段:加载、验证、准备、解析、初始化、使用、卸载。其中加载、检验、准备、初始化和卸载这个五个阶段的顺序是固定的,而解 ...










