深度揭秘!从源码级剖析 Android 基础知识体系
一、Android 系统架构总览
1.1 四层架构模型解析
Android 系统采用分层架构设计,从下到上分别为Linux 内核层 、系统运行库层 、应用框架层 和应用层。这种设计模式保证了系统的稳定性与可扩展性。
1.1.1 Linux 内核层
Linux 内核为 Android 提供底层驱动支持,包括内存管理、进程管理、网络协议栈等核心功能。其源码路径位于 /kernel
目录,以 KVM
虚拟化技术为例:
c
// drivers/kvm/kvm_main.c
// KVM 模块初始化函数
static int __init kvm_init(void)
{
// 注册 KVM 设备驱动
if (register_chrdev(KVM_DEV_MAJOR, "kvm", &kvm_fops)) {
pr_err(KVM_MODULE_NAME " could not register char major %d\n", KVM_DEV_MAJOR);
return -EBUSY;
}
// 创建 KVM 设备节点
kvm_dev = device_create_kvm(KVM_DEV_NAME);
if (IS_ERR(kvm_dev)) {
unregister_chrdev(KVM_DEV_MAJOR, "kvm");
return PTR_ERR(kvm_dev);
}
return 0;
}
module_init(kvm_init); // 模块加载时调用初始化函数
1.1.2 系统运行库层
包含 C/C++ 库和 Android 运行时(ART)。以 SQLite 数据库为例,其源码实现:
c
// sqlite3.c
// 打开 SQLite 数据库文件
int sqlite3_open(
const char *zName, /* 数据库文件名 */
sqlite3 **ppDb /* 用于返回数据库句柄的指针 */
){
return sqlite3_open_v2(zName, ppDb, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
}
// 执行 SQL 查询
int sqlite3_exec(
sqlite3 *db, /* 数据库句柄 */
const char *sql, /* SQL 语句 */
sqlite_callback xCallback, /* 回调函数 */
void *arg, /* 传递给回调函数的参数 */
char **pErrMsg /* 用于返回错误信息 */
){
// 解析 SQL 语句
sqlite3_stmt *pStmt;
int rc = sqlite3_prepare_v2(db, sql, -1, &pStmt, 0);
if( rc==SQLITE_OK ){
do{
// 执行 SQL 语句
rc = sqlite3_step(pStmt);
if( rc==SQLITE_ROW && xCallback ){
// 调用回调函数处理查询结果
xCallback(arg, sqlite3_column_count(pStmt), sqlite3_column_value(pStmt, 0));
}
}while( rc==SQLITE_ROW );
}
// 最终处理
sqlite3_finalize(pStmt);
return rc;
}
1.1.3 应用框架层
为开发者提供核心 API,如四大组件、资源管理等。以 Activity 框架为例:
java
// Activity.java
// Activity 创建时调用
protected void onCreate(Bundle savedInstanceState) {
// 调用父类 onCreate 方法
super.onCreate(savedInstanceState);
// 检查 Activity 是否包含主题样式
if (getTheme() == null) {
setTheme(android.R.style.Theme);
}
// 初始化 Window 对象
getWindow().setWindowControllerCallback(mWindowControllerCallback);
// 加载布局文件
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
// 设置 Activity 布局
public void setContentView(int layoutResID) {
// 通过 LayoutInflater 解析布局文件
getWindow().setContentView(layoutResID);
// 初始化 ActionBar
initWindowDecorActionBar();
}
1.1.4 应用层
即用户安装和使用的各类 APP,通过调用应用框架层 API 实现功能。
二、Java 与 Android 运行时
2.1 Java 语言特性适配
Android 基于 Java 语言开发,但并非完全兼容标准 Java。以类加载机制为例:
java
// PathClassLoader.java
// 路径类加载器
public class PathClassLoader extends BaseDexClassLoader {
// 构造函数
public PathClassLoader(String dexPath, ClassLoader parent) {
// 调用父类构造函数,传入 dex 路径、系统库路径、null 表示无优化 dex 路径、父类加载器
super(dexPath, null, null, parent);
}
// 加载类的核心方法
protected Class<?> findClass(String name) throws ClassNotFoundException {
// 从 DexPathList 中查找类
Class c = pathList.findClass(name);
if (c == null) {
throw new ClassNotFoundException(name);
}
return c;
}
}
2.2 Android 运行时(ART)
ART 替代了早期的 Dalvik 虚拟机,采用预编译技术提升性能。以方法调用机制为例:
c
// art_method.cc
// 方法调用入口
mirror::ArtMethod* ArtMethod::Invoke(
const ArrayRef<mirror::Object*>& parameters, // 方法参数
mirror::Object* receiver, // 调用对象
JValue* result) { // 结果存储
// 检查方法是否可调用
if (!IsInvocable()) {
// 抛出异常
ThrowNoSuchMethodError(name_, declaring_class_);
return nullptr;
}
// 执行方法调用
return InvokeWithArgArray(parameters, receiver, result);
}
// 实际执行方法调用
mirror::ArtMethod* ArtMethod::InvokeWithArgArray(
const ArrayRef<mirror::Object*>& parameters,
mirror::Object* receiver,
JValue* result) {
// 根据方法类型选择调用方式
if (IsNative()) {
// 调用本地方法
return InvokeNative(parameters, receiver, result);
} else {
// 调用 Java 方法
return InvokeNonNative(parameters, receiver, result);
}
}
三、四大组件核心原理
3.1 Activity 生命周期管理
Activity 生命周期包含创建、启动、暂停、停止、销毁等状态。
java
// ActivityThread.java
// 处理 Activity 创建
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 初始化 Activity
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
// 处理 Activity 启动
handleResumeActivity(r.token, false, r.isForward,
"LAUNCH_ACTIVITY", r.overrideConfig);
}
}
// 执行 Activity 创建
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 获取 Activity 类加载器
ClassLoader cl = r.packageInfo.getClassLoader();
// 实例化 Activity
Activity activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
try {
// 创建 Application 对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
// 调用 Activity 的 attach 方法
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
// 调用 Activity 的 onCreate 方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
r.activity = activity;
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
// 异常处理
}
return activity;
}
3.2 Service 运行机制
Service 分为前台服务和后台服务,以启动模式为例:
java
// ContextImpl.java
// 启动 Service
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
// 检查权限
if (service == null) {
throw new IllegalArgumentException("Service Intent must not be null");
}
// 调用 ActivityManagerService 启动 Service
return startServiceCommon(service, false, mUserHandle);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
// 获取 ActivityManagerService 代理对象
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), user);
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service + " without permission");
}
}
return cn;
} catch (RemoteException e) {
// 远程调用异常处理
}
return null;
}
3.3 BroadcastReceiver 消息传递
广播分为有序广播和无序广播,以注册和接收为例:
java
// ContextImpl.java
// 注册广播接收器
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
warnIfCallingFromSystemProcess();
// 检查权限
if (receiver == null) {
throw new IllegalArgumentException("receiver is null");
}
if (mPackageInfo != null) {
// 保存广播接收器和过滤器
mPackageInfo.registerReceiver(receiver, filter, broadcastPermission, scheduler);
}
try {
// 调用 ActivityManagerService 注册广播
return ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, receiver,
filter, broadcastPermission, AppOpsManager.OP_NONE, null, false);
} catch (RemoteException e) {
// 异常处理
}
return null;
}
// BroadcastReceiver.java
// 接收广播
public abstract void onReceive(Context context, Intent intent);
3.4 ContentProvider 数据共享
ContentProvider 用于不同应用间的数据共享,以查询操作为例:
java
// ContentProvider.java
// 查询数据
public final Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// 检查权限
enforceReadPermission(uri);
// 处理查询请求
Cursor c = query(uri, projection, selection, selectionArgs, sortOrder, null);
if (c == null) {
throw new android.database.SQLException("Query failed");
}
return c;
}
// 抽象查询方法,由子类实现
public abstract Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal);
四、UI 绘制与事件处理
4.1 View 绘制流程
View 绘制分为测量、布局和绘制三个阶段。
4.1.1 测量阶段
java
// View.java
// 测量方法
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 设置测量后的宽高
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
// 获取默认大小
public static int getDefaultSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
// 未指定模式,使用默认大小
case MeasureSpec.UNSPECIFIED:
result = size;
break;
// 精确模式或最大模式,使用测量规格中的大小
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
4.1.2 布局阶段
java
// ViewGroup.java
// 布局方法
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// 由具体 ViewGroup 子类实现
}
// LinearLayout.java
// 垂直方向布局
void layoutVertical(int left, int top, int right, int bottom) {
final int count = getChildCount();
// 遍历子视图
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final LinearLayout.LayoutParams lp =
(LinearLayout.LayoutParams) child.getLayoutParams();
// 计算子视图的布局参数
int childLeft = getPaddingLeftWithForeground() + lp.leftMargin;
int childRight = childLeft + child.getMeasuredWidth();
int childTop = top + getPaddingTopWithForeground() + lp.topMargin;
int childBottom = childTop + child.getMeasuredHeight();
// 设置子视图的布局
child.layout(childLeft, childTop, childRight, childBottom);
top = childBottom + lp.bottomMargin;
}
}
}
4.1.3 绘制阶段
java
// View.java
// 绘制方法
public void draw(Canvas canvas) {
// 绘制背景
drawBackground(canvas);
// 保存画布状态
int saveCount;
if (!dirtyOpaque) {
saveCount = canvas.saveLayer(left, top, right, bottom, null,
Canvas.ALL_SAVE_FLAG);
}
// 绘制视图内容
onDraw(canvas);
// 绘制子视图
dispatchDraw(canvas);
// 恢复画布状态
if (!dirtyOpaque) {
canvas.restoreToCount(saveCount);
}
// 绘制前景
onDrawForeground(canvas);
}
4.2 事件分发机制
事件分发涉及 dispatchTouchEvent
、onInterceptTouchEvent
和 onTouchEvent
三个方法。
java
// ViewGroup.java
// 事件分发
public boolean dispatchTouchEvent(MotionEvent ev) {
// 检查是否取消事件
if (ev.isTargetAccessibilityFocus() && isAccessibilityFocused()) {
ev.setTargetAccessibilityFocus(false);
}
boolean handled = false;
if (onFilterTouchEventForSecurity(ev)) {
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
// 处理 ACTION_DOWN 事件
if (actionMasked == MotionEvent.ACTION_DOWN) {
onNestedPreScroll(ev, 0, 0, mTempNestedScrollConsumed);
}
// 尝试拦截事件
final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action);
} else {
intercepted = false;
}
} else {
intercepted = true;
}
// 处理取消事件
if (actionMasked == MotionEvent.ACTION_CANCEL || actionMasked == MotionEvent.ACTION_UP) {
resetTouchState();
}
// 分发事件给子视图
if (!intercepted || mFirstTouchTarget != null) {
if (actionMasked == MotionEvent.ACTION_DOWN) {
// 重置触摸目标
mLastTouchDownTime = ev.getDownTime();
mLastTouchDownX = ev.getX();
mLastTouchDownY = ev.getY();
}
// 分发事件给子视图
final ArrayList<View> preorderedList = buildTouchDispatchChildList();
final boolean customOrder = preorderedList == null
&& isChildrenDrawingOrderEnabled();
final View[] children = mChildren;
for (int i = childrenCount - 1; i >= 0; i--) {
final int childIndex = getAndVerifyPreorderedIndex(
childrenCount, i, customOrder);
final View child = getAndVerifyPreorderedView(
preorderedList, children, childIndex);
if (childWithAccessibilityFocus != null) {
if (childWithAccessibilityFocus != child) {
continue;
}
childWithAccessibilityFocus = null;
i = childrenCount - 1;
}
if (!child.canReceivePointerEvents()
|| !isTransformedTouchPointInView(ev.getX(), ev.getY(), null)) {
ev.setTarget
java
continue;
}
// 尝试将事件分发给子视图
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
// 记录触摸目标
mLastTouchDownTime = ev.getDownTime();
if (preorderedList != null) {
for (int j = 0; j < childrenCount; j++) {
if (children[childIndex] == mChildren[j]) {
mLastTouchDownIndex = j;
break;
}
}
} else {
mLastTouchDownIndex = childIndex;
}
mLastTouchDownX = ev.getX();
mLastTouchDownY = ev.getY();
// 添加触摸目标
newTouchTarget = addTouchTarget(child, idBitsToAssign);
alreadyDispatchedToNewTouchTarget = true;
break;
}
}
}
if (preorderedList != null) preorderedList.clear();
}
// 如果没有子视图处理事件,自己处理
if (mFirstTouchTarget == null) {
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);
} else {
TouchTarget predecessor = null;
TouchTarget target = mFirstTouchTarget;
while (target != null) {
final TouchTarget next = target.next;
if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
handled = true;
} else {
final boolean cancelChild = resetCancelNextUpFlag(target.child)
|| intercepted;
if (dispatchTransformedTouchEvent(ev, cancelChild,
target.child, target.pointerIdBits)) {
handled = true;
}
if (cancelChild) {
if (predecessor == null) {
mFirstTouchTarget = next;
} else {
predecessor.next = next;
}
target.recycle();
target = next;
continue;
}
}
predecessor = target;
target = next;
}
}
// 处理 ACTION_UP 和 ACTION_CANCEL 事件
if (canceled
|| actionMasked == MotionEvent.ACTION_UP
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
resetTouchState();
} else if (split && actionMasked == MotionEvent.ACTION_POINTER_UP) {
final int actionIndex = ev.getActionIndex();
final int idBitsToRemove = 1 << ev.getPointerId(actionIndex);
removePointersFromTouchTargets(idBitsToRemove);
}
}
if (!handled && mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(ev, 1);
}
return handled;
}
// 拦截事件
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.isFromSource(InputDevice.SOURCE_MOUSE)
&& ev.getAction() == MotionEvent.ACTION_DOWN
&& ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
&& isOnScrollbarThumb(ev.getX(), ev.getY())) {
return true;
}
return false;
}
// 处理触摸事件
public boolean onTouchEvent(MotionEvent event) {
final float x = event.getX();
final float y = event.getY();
final int viewFlags = mViewFlags;
final int action = event.getAction();
if ((viewFlags & ENABLED_MASK) == DISABLED) {
if (action == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
setPressed(false);
}
return (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) ||
(viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE);
}
if (mTouchDelegate != null) {
if (mTouchDelegate.onTouchEvent(event)) {
return true;
}
}
if (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) ||
(viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE) {
switch (action) {
case MotionEvent.ACTION_UP:
boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
boolean focusTaken = false;
if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
focusTaken = requestFocus();
}
if (prepressed) {
setPressed(true, x, y);
}
if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
removeLongPressCallback();
if (!focusTaken) {
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClickInternal();
}
}
}
if (mUnsetPressedState == null) {
mUnsetPressedState = new UnsetPressedState();
}
if (prepressed) {
postDelayed(mUnsetPressedState,
ViewConfiguration.getPressedStateDuration());
} else if (!post(mUnsetPressedState)) {
mUnsetPressedState.run();
}
removeTapCallback();
}
mIgnoreNextUpEvent = false;
break;
case MotionEvent.ACTION_DOWN:
mHasPerformedLongPress = false;
if (performButtonActionOnTouchDown(event)) {
break;
}
boolean isInScrollingContainer = isInScrollingContainer();
if (isInScrollingContainer) {
mPrivateFlags |= PFLAG_PREPRESSED;
if (mPendingCheckForTap == null) {
mPendingCheckForTap = new CheckForTap();
}
mPendingCheckForTap.x = event.getX();
mPendingCheckForTap.y = event.getY();
postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
} else {
setPressed(true, x, y);
checkForLongClick(0, x, y);
}
break;
case MotionEvent.ACTION_CANCEL:
setPressed(false);
removeTapCallback();
removeLongPressCallback();
mIgnoreNextUpEvent = false;
break;
case MotionEvent.ACTION_MOVE:
drawableHotspotChanged(x, y);
if (!pointInView(x, y, mTouchSlop)) {
removeTapCallback();
if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
removeLongPressCallback();
setPressed(false);
}
}
break;
}
return true;
}
return false;
}
// 转换并分发触摸事件
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits) {
final boolean handled;
final int oldAction = event.getAction();
if (cancel || oldAction == MotionEvent.ACTION_CANCEL) {
event.setAction(MotionEvent.ACTION_CANCEL);
if (child == null) {
handled = super.dispatchTouchEvent(event);
} else {
handled = child.dispatchTouchEvent(event);
}
event.setAction(oldAction);
return handled;
}
final int oldPointerIdBits = event.getPointerIdBits();
final int newPointerIdBits = oldPointerIdBits & desiredPointerIdBits;
if (newPointerIdBits == 0) {
return false;
}
final MotionEvent transformedEvent;
if (newPointerIdBits == oldPointerIdBits) {
if (child == null || child.hasIdentityMatrix()) {
if (child == null) {
handled = super.dispatchTouchEvent(event);
} else {
final float offsetX = mScrollX - child.mLeft;
final float offsetY = mScrollY - child.mTop;
event.offsetLocation(offsetX, offsetY);
handled = child.dispatchTouchEvent(event);
event.offsetLocation(-offsetX, -offsetY);
}
return handled;
}
transformedEvent = MotionEvent.obtain(event);
} else {
transformedEvent = event.split(newPointerIdBits);
}
if (child == null) {
handled = super.dispatchTouchEvent(transformedEvent);
} else {
final float offsetX = mScrollX - child.mLeft;
final float offsetY = mScrollY - child.mTop;
transformedEvent.offsetLocation(offsetX, offsetY);
if (! child.hasIdentityMatrix()) {
transformedEvent.transform(child.getInverseMatrix());
}
handled = child.dispatchTouchEvent(transformedEvent);
}
transformedEvent.recycle();
return handled;
}
在上述代码中,dispatchTouchEvent
方法负责事件的分发,它会先判断是否要拦截事件,如果不拦截则尝试将事件分发给子视图。onInterceptTouchEvent
方法用于判断是否拦截事件,默认情况下不拦截。onTouchEvent
方法用于处理触摸事件,包括点击、长按等操作。dispatchTransformedTouchEvent
方法用于转换并分发触摸事件,它会根据子视图的情况对事件进行处理。
4.3 动画系统原理
Android 动画系统主要分为视图动画、属性动画和帧动画。这里以属性动画为例进行分析。
java
// ValueAnimator.java
// 创建一个 ValueAnimator 实例
public static ValueAnimator ofFloat(float... values) {
ValueAnimator anim = new ValueAnimator();
anim.setFloatValues(values);
return anim;
}
// 设置动画的值
public void setFloatValues(float... values) {
if (values == null || values.length == 0) {
return;
}
if (mValues == null || mValues.length == 0) {
setValues(new PropertyValuesHolder[] {PropertyValuesHolder.ofFloat("", values)});
} else {
PropertyValuesHolder valuesHolder = mValues[0];
valuesHolder.setFloatValues(values);
}
// 设置动画的初始值和结束值
if (mCurrentValues == null) {
mCurrentValues = new float[values.length];
}
mNumValues = values.length;
mEvaluator = new FloatEvaluator();
mStartValues = values.clone();
mEndValues = values.clone();
}
// 启动动画
public void start() {
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
mReversing = false;
mSelfPulse = !mSuppressSelfPulseRequested;
// 如果动画正在运行,先取消
if (DBG) {
Log.d(LOG_TAG, "Anim target, duration: " + getTarget() + ", " + getDuration());
for (int i = 0; i < mValues.length; ++i) {
PropertyValuesHolder pvh = mValues[i];
Log.d(LOG_TAG, " Values[" + i + "]: " +
pvh.getPropertyName() + ": " +
pvh.mKeyframes.getValue(0) + " - " +
pvh.mKeyframes.getValue(1));
}
}
// 通知动画开始
AnimationHandler animationHandler = AnimationHandler.getInstance();
animationHandler.addAnimationFrameCallback(this, getStartDelay());
if (mStartDelay == 0) {
// 立即开始动画
setCurrentPlayTime(0);
}
mStarted = true;
mPaused = false;
mRunning = false;
notifyStartListeners();
}
// 计算当前动画的值
void animateValue(float fraction) {
fraction = mInterpolator.getInterpolation(fraction);
mCurrentFraction = fraction;
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
mValues[i].calculateValue(fraction);
}
if (mUpdateListeners != null) {
int numListeners = mUpdateListeners.size();
for (int i = 0; i < numListeners; ++i) {
mUpdateListeners.get(i).onAnimationUpdate(this);
}
}
}
// 计算属性值
public void calculateValue(float fraction) {
Object value = mKeyframes.getValue(fraction);
mAnimatedValue = value;
if (mProperty != null) {
mProperty.set(mTarget, value);
}
}
在属性动画中,ValueAnimator
是核心类。ofFloat
方法用于创建一个 ValueAnimator
实例并设置动画的值。start
方法用于启动动画,它会将动画添加到 AnimationHandler
中,并在合适的时机开始动画。animateValue
方法用于计算当前动画的值,它会根据插值器计算出当前的进度,并调用 PropertyValuesHolder
的 calculateValue
方法来计算属性值。calculateValue
方法会根据关键帧和当前进度计算出属性值,并通过 Property
对象将值设置到目标对象上。
五、数据存储与网络通信
5.1 数据存储方式
5.1.1 SharedPreferences
java
// SharedPreferencesImpl.java
// 获取 SharedPreferences 实例
public SharedPreferencesImpl(File file, int mode) {
mFile = file;
mBackupFile = makeBackupFile(file);
mMode = mode;
mLoaded = false;
mMap = null;
mThrowable = null;
startLoadFromDisk();
}
// 从磁盘加载数据
private void startLoadFromDisk() {
synchronized (this) {
mLoaded = false;
}
new Thread("SharedPreferencesImpl-load") {
public void run() {
loadFromDisk();
}
}.start();
}
// 加载数据
private void loadFromDisk() {
synchronized (SharedPreferencesImpl.this) {
if (mLoaded) {
return;
}
if (mBackupFile.exists()) {
mFile.delete();
mBackupFile.renameTo(mFile);
}
}
Map<String, Object> map = null;
StructStat stat = null;
try {
stat = Os.stat(mFile.getPath());
if (mFile.canRead()) {
BufferedInputStream str = null;
try {
str = new BufferedInputStream(
new FileInputStream(mFile), 16 * 1024);
map = XmlUtils.readMapXml(str);
} catch (Exception e) {
Log.w(TAG, "Cannot read " + mFile.getAbsolutePath(), e);
} finally {
IoUtils.closeQuietly(str);
}
}
} catch (ErrnoException e) {
// 处理异常
}
synchronized (SharedPreferencesImpl.this) {
mLoaded = true;
mThrowable = null;
try {
if (map != null) {
mMap = map;
mStatTimestamp = stat.st_mtime;
mStatSize = stat.st_size;
} else {
mMap = new HashMap<>();
}
} catch (Throwable t) {
mThrowable = t;
} finally {
notifyAll();
}
}
}
// 获取数据
public String getString(String key, String defValue) {
synchronized (this) {
awaitLoadedLocked();
String v = (String)mMap.get(key);
return v != null ? v : defValue;
}
}
// 编辑器类
public final class EditorImpl implements Editor {
private final Map<String, Object> mModified = new HashMap<>();
private boolean mClear = false;
public Editor putString(String key, String value) {
synchronized (this) {
mModified.put(key, value);
return this;
}
}
public Editor clear() {
synchronized (this) {
mClear = true;
mModified.clear();
return this;
}
}
public boolean commit() {
MemoryCommitResult mcr = commitToMemory();
SharedPreferencesImpl.this.enqueueDiskWrite(
mcr, null /* sync write on this thread okay */);
try {
mcr.writtenToDiskLatch.await();
} catch (InterruptedException e) {
return false;
}
notifyListeners(mcr);
return mcr.writeToDiskResult;
}
private MemoryCommitResult commitToMemory() {
MemoryCommitResult mcr = new MemoryCommitResult();
synchronized (SharedPreferencesImpl.this) {
if (mDiskWritesInFlight > 0) {
mMap = new HashMap<String, Object>(mMap);
}
mcr.mapToWriteToDisk = mMap;
mDiskWritesInFlight++;
boolean hasListeners = mListeners.size() > 0;
if (hasListeners) {
mcr.keysModified = new ArrayList<String>();
mcr.listeners =
new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
}
synchronized (this) {
if (mClear) {
if (!mMap.isEmpty()) {
mcr.changesMade = true;
mMap.clear();
}
mClear = false;
}
for (Map.Entry<String, Object> e : mModified.entrySet()) {
String k = e.getKey();
Object v = e.getValue();
if (v == this || v == null) {
if (!mMap.containsKey(k)) {
continue;
}
mMap.remove(k);
} else {
if (mMap.containsKey(k) && TextUtils.equals(mMap.get(k), v)) {
continue;
}
mMap.put(k, v);
}
mcr.changesMade = true;
if (hasListeners) {
mcr.keysModified.add(k);
}
}
mModified.clear();
}
}
return mcr;
}
}
SharedPreferences
是一种轻量级的数据存储方式,用于存储键值对。SharedPreferencesImpl
是其实现类,startLoadFromDisk
方法会启动一个线程从磁盘加载数据。loadFromDisk
方法会读取文件并将数据存储在 mMap
中。getString
方法用于获取存储的数据。EditorImpl
是编辑器类,putString
方法用于存储数据,commit
方法用于将数据写入磁盘。
5.1.2 SQLite 数据库
java
// SQLiteDatabase.java
// 打开或创建数据库
public static SQLiteDatabase openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory,
DatabaseErrorHandler errorHandler) {
SQLiteDatabase db = new SQLiteDatabase(path, OPEN_READWRITE | CREATE_IF_NECESSARY,
factory, errorHandler);
db.open();
return db;
}
// 执行 SQL 语句
public void execSQL(String sql) throws SQLException {
execSQL(sql, null);
}
public void execSQL(String sql, Object[] bindArgs) throws SQLException {
acquireReference();
try {
mConnectionPool.executeForChangedRowCount(sql, bindArgs);
} catch (SQLException e) {
onCorruption();
throw e;
} finally {
releaseReference();
}
}
// 查询数据
public Cursor query(String table, String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy) {
return query(false, table, columns, selection, selectionArgs, groupBy, having,
orderBy, null);
}
public Cursor query(boolean distinct, String table, String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy, String limit) {
acquireReference();
try {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(table);
qb.setDistinct(distinct);
SQLiteCursorDriver driver = mConnectionPool.query(sql, bindArgs,
mCancellationSignal, this);
Cursor cursor = driver.query(mCursorFactory,
qb.buildQuery(columns, selection, selectionArgs, groupBy, having, orderBy, limit));
cursor.setDatabase(this);
return cursor;
} catch (SQLException e) {
onCorruption();
throw e;
} finally {
releaseReference();
}
}
SQLiteDatabase
用于操作 SQLite 数据库。openOrCreateDatabase
方法用于打开或创建数据库。execSQL
方法用于执行 SQL 语句。query
方法用于查询数据,它会构建查询语句并通过 SQLiteQueryBuilder
进行查询。
5.2 网络通信
5.2.1 HttpURLConnection
java
// HttpURLConnection.java
// 创建 HttpURLConnection 实例
public static URLConnection openConnection(URL url) throws IOException {
return url.openConnection();
}
// 设置请求方法
public void setRequestMethod(String method) throws ProtocolException {
if (method == null) {
throw new NullPointerException("Request method must not be null");
}
method = method.trim();
if (method.length() == 0) {
throw new ProtocolException("Request method must not be empty");
}
if (!ALLOWED_METHODS.contains(method)) {
throw new ProtocolException("Invalid HTTP method: " + method);
}
mRequestMethod = method;
}
// 获取输入流
public InputStream getInputStream() throws IOException {
if (usingProxy()) {
if (mRequestMethod.equals("CONNECT")) {
return mSocket.getInputStream();
}
}
if (mResponseCode < 0) {
getResponseCode();
}
if (mResponseCode >= 400) {
throw new HttpRetryException("HTTP request failed", mResponseCode);
}
return mInputStream;
}
// 获取响应码
public int getResponseCode() throws IOException {
if (mResponseCode < 0) {
connect();
parseHTTP();
}
return mResponseCode;
}
HttpURLConnection
是 Java 提供的用于 HTTP 通信的类。openConnection
方法用于创建 HttpURLConnection
实例。setRequestMethod
方法用于设置请求方法。getInputStream
方法用于获取输入流,getResponseCode
方法用于获取响应码。
5.2.2 OkHttp
java
// OkHttpClient.java
// 创建 OkHttpClient 实例
public OkHttpClient() {
this(new Builder());
}
OkHttpClient(Builder builder) {
this.dispatcher = builder.dispatcher;
this.proxy = builder.proxy;
this.protocols = builder.protocols;
this.connectionSpecs = builder.connectionSpecs;
this.interceptors = Util.immutableList(builder.interceptors);
this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
this.eventListenerFactory = builder.eventListenerFactory;
this.proxySelector = builder.proxySelector;
this.cookieJar = builder.cookieJar;
this.cache = builder.cache;
this.internalCache = builder.internalCache;
this.socketFactory = builder.socketFactory;
if (builder.sslSocketFactory != null || builder.hostnameVerifier != null) {
this.sslSocketFactory = builder.sslSocketFactory;
this.certificateChainCleaner = builder.certificateChainCleaner;
this.hostnameVerifier = builder.hostnameVerifier;
} else {
X509TrustManager trustManager = Util.platformTrustManager();
SSLSocketFactory sslSocketFactory = sslSocketFactory(trustManager);
this.sslSocketFactory = sslSocketFactory;
this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
this.hostnameVerifier = OkHostnameVerifier.INSTANCE;
}
this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
certificateChainCleaner);
this.proxyAuthenticator = builder.proxyAuthenticator;
this.authenticator = builder.authenticator;
this.connectionPool = builder.connectionPool;
this.dns = builder.dns;
this.followSslRedirects = builder.followSslRedirects;
this.followRedirects = builder.followRedirects;
this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
this.connectTimeout = builder.connectTimeout;
this.readTimeout = builder.readTimeout;
this.writeTimeout = builder.writeTimeout;
this.pingInterval = builder.pingInterval;
this.reverseProxy = builder.reverseProxy;
this.reverseProxySelector = builder.reverseProxySelector;
this.reverseProxyAuthenticator = builder.reverseProxyAuthenticator;
this.reverseProxyChainCleaner = builder.reverseProxyChainCleaner;
this.reverseProxyHostnameVerifier = builder.reverseProxyHostnameVerifier;
this.reverseProxyPinner = builder.reverseProxyPinner;
this.reverseProxyFollowSslRedirects = builder.reverseProxyFollowSslRedirects;
this.reverseProxyFollowRedirects = builder.reverseProxyFollowRedirects;
this.reverseProxyRetryOnConnectionFailure = builder.reverseProxyRetryOnConnectionFailure;
this.reverseProxyConnectTimeout = builder.reverseProxyConnectTimeout;
this.reverseProxyReadTimeout = builder.reverseProxyReadTimeout;
this.reverseProxyWriteTimeout = builder.reverseProxyWriteTimeout;
this.reverseProxyPingInterval = builder.reverseProxyPingInterval;
}
// 发起异步请求
public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
// RealCall.java
// 发起异步请求
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
// AsyncCall.java
@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
// 获取响应
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
OkHttp
是一个高效的 HTTP 客户端。OkHttpClient
用于创建客户端实例,newCall
方法用于创建 Call
对象。RealCall
的 enqueue
方法用于发起异步请求,它会将请求交给 Dispatcher
处理。AsyncCall
的 execute
方法会执行请求并处理响应。getResponseWithInterceptorChain
方法会构建一个拦截器链,通过拦截器链处理请求和响应。