深度揭秘!从源码级剖析 Android 基础知识体系

深度揭秘!从源码级剖析 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 事件分发机制

事件分发涉及 dispatchTouchEventonInterceptTouchEventonTouchEvent 三个方法。

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 方法用于计算当前动画的值,它会根据插值器计算出当前的进度,并调用 PropertyValuesHoldercalculateValue 方法来计算属性值。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 对象。RealCallenqueue 方法用于发起异步请求,它会将请求交给 Dispatcher 处理。AsyncCallexecute 方法会执行请求并处理响应。getResponseWithInterceptorChain 方法会构建一个拦截器链,通过拦截器链处理请求和响应。

相关推荐
uhakadotcom27 分钟前
如何用AI打造高效招聘系统,HR效率提升100%!
后端·算法·面试
louisgeek1 小时前
Android NSD 网络服务发现
android
秋天的一阵风1 小时前
Vue3探秘系列— 路由:vue-router的实现原理(十六-上)
前端·vue.js·面试
秋天的一阵风1 小时前
Vue3探秘系列— 路由:vue-router的实现原理(十六-下)
前端·vue.js·面试
工呈士1 小时前
CSS布局实战:Flexbox 与 Grid 精髓解析
css·面试·flexbox
海底火旺1 小时前
JavaScript中的Object方法完全指南:从基础到高级应用
前端·javascript·面试
海底火旺1 小时前
JavaScript中的Symbol:解锁对象属性的新维度
前端·javascript·面试
天天扭码1 小时前
一文吃透 ES6新特性——解构语法
前端·javascript·面试
张可2 小时前
历时两年半开发,Fread 项目现在决定开源,基于 Kotlin Multiplatform 和 Compose Multiplatform 实现
android·前端·kotlin
余辉zmh2 小时前
【Linux系统篇】:信号的生命周期---从触发到保存与捕捉的底层逻辑
android·java·linux