深度揭秘!从源码级剖析 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 方法会构建一个拦截器链,通过拦截器链处理请求和响应。

相关推荐
踢球的打工仔14 小时前
PHP面向对象(7)
android·开发语言·php
安卓理事人14 小时前
安卓socket
android
程序员小寒19 小时前
前端高频面试题之CSS篇(一)
前端·css·面试·css3
安卓理事人20 小时前
安卓LinkedBlockingQueue消息队列
android
万能的小裴同学21 小时前
Android M3U8视频播放器
android·音视频
进击的野人21 小时前
深入理解 JavaScript Promise:原理、用法与实践
javascript·面试·ecmascript 6
q***577421 小时前
MySql的慢查询(慢日志)
android·mysql·adb
JavaNoober1 天前
Android 前台服务 "Bad Notification" 崩溃机制分析文档
android
有意义1 天前
JavaScript 词法作用域与闭包:从底层原理到实战理解
前端·javascript·面试
AY呀1 天前
黑马喽大闹天宫与JavaScript的寻亲记:作用域与作用域链全解析
前端·javascript·面试