基础06-ViewGroup

dispatchTouchEvent

flowchart TD
    A[开始] --> B{过滤事件}
    B -->|true| C{是否ACTION_DOWN}
    B -->|false| D[返回false]
    C -->|true| E[清除TouchTargets,重置TouchState]
    C -->|false| F{111}
    E --> G[调用onInterceptTouchEvent]@{ shape: comment, label: "计算新事件的x,y,传递给child\n若child空,调用super.dispatchTouchEvent" }
    G --> J[处理hover事件]
    J --> F[遍历TouchTarget,调用dispatchTransformedTouchEvent传递event]
    F --> H[如果是up/cancel,重置TouchState]
    H --> I[返回是否handle]

过滤事件

  • 如果this存在flag:FILTER_TOUCHES_WHEN_OBSCURED,event存在flag:FLAG_WINDOW_IS_OBSCURED,就丢掉
  • window被上面的window遮住了,不管这个时间了
1
2
3
4
public void setFilterTouchesWhenObscured(boolean enabled) {
setFlags(enabled ? FILTER_TOUCHES_WHEN_OBSCURED : 0,
FILTER_TOUCHES_WHEN_OBSCURED);
}

调用view的这个函数,就会设置这个flag

阅读更多

基础05-Navigation

简介

NavController是中央导航 API。它会跟踪用户访问过的目的地,并允许用户在目的地之间移动。

获取NavController

  • fragment

如果是NavHostFragment

1
val navController = this.navController
阅读更多

基础04-LiveData

LiveData

LiveData的观察者

1
2
3
4
5
6
7
fun interface Observer<T> {

/**
* Called when the data is changed to [value].
*/
fun onChanged(value: T)
}
  • 通过onChanged函数分派数据变化

成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@SuppressWarnings("WeakerAccess") /* synthetic access */
final Object mDataLock = new Object();
static final int START_VERSION = -1;
@SuppressWarnings("WeakerAccess") /* synthetic access */
static final Object NOT_SET = new Object();

private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();

// how many observers are in active state
@SuppressWarnings("WeakerAccess") /* synthetic access */
int mActiveCount = 0;
// to handle active/inactive reentry, we guard with this boolean
private boolean mChangingActiveState;
private volatile Object mData; // 1️⃣:当前的data
// when setData is called, we set the pending data and actual data swap happens on the main
// thread
@SuppressWarnings("WeakerAccess") /* synthetic access */
volatile Object mPendingData = NOT_SET; // 2️⃣:给多线程使用的,在4️⃣mPostValueRunnable中使用
private int mVersion; // 3️⃣:mVersion是数据版本

private boolean mDispatchingValue;
@SuppressWarnings("FieldCanBeLocal")
private boolean mDispatchInvalidated;
private final Runnable mPostValueRunnable = new Runnable() {// 4️⃣mPostValueRunnable,在主线程中将mPendingData设置为当前值
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
阅读更多

基础03-Lifecycle

lifeCycle的Observer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public interface LifecycleObserver

public interface DefaultLifecycleObserver : LifecycleObserver {
/**
* Notifies that `ON_CREATE` event occurred.
*
*
* This method will be called after the [LifecycleOwner]'s `onCreate`
* method returns.
*
* @param owner the component, whose state was changed
*/
public fun onCreate(owner: LifecycleOwner) {}

/**
* Notifies that `ON_START` event occurred.
*
*
* This method will be called after the [LifecycleOwner]'s `onStart` method returns.
*
* @param owner the component, whose state was changed
*/
public fun onStart(owner: LifecycleOwner) {}

/**
* Notifies that `ON_RESUME` event occurred.
*
*
* This method will be called after the [LifecycleOwner]'s `onResume`
* method returns.
*
* @param owner the component, whose state was changed
*/
public fun onResume(owner: LifecycleOwner) {}

/**
* Notifies that `ON_PAUSE` event occurred.
*
*
* This method will be called before the [LifecycleOwner]'s `onPause` method
* is called.
*
* @param owner the component, whose state was changed
*/
public fun onPause(owner: LifecycleOwner) {}

/**
* Notifies that `ON_STOP` event occurred.
*
*
* This method will be called before the [LifecycleOwner]'s `onStop` method
* is called.
*
* @param owner the component, whose state was changed
*/
public fun onStop(owner: LifecycleOwner) {}

/**
* Notifies that `ON_DESTROY` event occurred.
*
*
* This method will be called before the [LifecycleOwner]'s `onDestroy` method
* is called.
*
* @param owner the component, whose state was changed
*/
public fun onDestroy(owner: LifecycleOwner) {}
}

public fun interface LifecycleEventObserver : LifecycleObserver {
/**
* Called when a state transition event happens.
*
* @param source The source of the event
* @param event The event
*/
public fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event)
}
  • 可以看到,我们在使用lifecycle.addObserver()时,可以传入LifecycleEventObserverDefaultLifecycleObserver,一个通过event获取当前状态,一个通过不同的回调函数获取当前状态

Activity树

1
2
3
4
5
6
7
8
9
10
11
Activity -- AccountAuthenticatorActivity
|- ActivityGroup -- TabActivity
|- ExpandableListActivity
|- LauncherActivity
|- ListActivity -- PreferenceActivity
|- NativeActivity
|- androidx.core.app.ComponentActivity -- androidx.activity.ComponentActivity -- FragmentActivity -- AppCompatActivity
|- PreviewActivity
|- BootstrapActivity
|- EmptyActivity
|- EmptyFloatingActivity

LifecycleOwner

阅读更多

基础02-viewModel

ViewModel简介

在了解ViewModel之前,我们先来了解一下MVC, MVP, MVVM的发展Difference Between MVC, MVP and MVVM Architecture Pattern in Android

ViewModelStoreOwner

1
2
3
4
5
6
7
interface ViewModelStoreOwner {

/**
* The owned [ViewModelStore]
*/
val viewModelStore: ViewModelStore
}

ViewModelStore

阅读更多

基础01-Context

大纲

  • Context类
    • 注解
      • 用于标注文件、SharedPreferences、数据库的打开方式的注解
      • 用于标注bindService时,service的flags的注解
      • 用于标注registerReceiver时,receiver的flags的注解
      • 用于标注getService时,servicesName的注解
      • 用于标注createPackageContext、createPackageContextAsUser、createContextAsUser、createApplicationContext时的flags的注解
    • 常量定义
      • 对应上面注解中限制的常量
      • WAL

Context类

Context是抽象类,具体实现在ContextImpl,Application,Service,Activity都直接或间接继承自ContextWrapper,ContextWrapper通过代理的方式调用真正的ContextImpl。

注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/** @hide */
@IntDef(flag = true, prefix = { "MODE_" }, value = {
MODE_PRIVATE,
MODE_WORLD_READABLE,
MODE_WORLD_WRITEABLE,
MODE_APPEND,
})
@Retention(RetentionPolicy.SOURCE)
public @interface FileMode {}

/** @hide */
@IntDef(flag = true, prefix = { "MODE_" }, value = {
MODE_PRIVATE,
MODE_WORLD_READABLE,
MODE_WORLD_WRITEABLE,
MODE_MULTI_PROCESS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface PreferencesMode {}

/** @hide */
@IntDef(flag = true, prefix = { "MODE_" }, value = {
MODE_PRIVATE,
MODE_WORLD_READABLE,
MODE_WORLD_WRITEABLE,
MODE_ENABLE_WRITE_AHEAD_LOGGING,
MODE_NO_LOCALIZED_COLLATORS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface DatabaseMode {}
阅读更多

01-layout

ID

创建 RelativeLayout 时,请务必为视图对象定义 ID。在相对布局中,同级视图可以定义其相对于通过唯一 ID 引用的另一个同级视图的布局。

findViewById

ID 不必在整个树状结构中具有唯一性,但在您搜索的树状结构部分中必须是唯一的。它通常可能是整个树,因此最好尽可能使其具有唯一性。

  • findViewById是View的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* Finds the first descendant view with the given ID, the view itself if
* the ID matches {@link #getId()}, or {@code null} if the ID is invalid
* (< 0) or there is no matching view in the hierarchy.
* <p>
* <strong>Note:</strong> In most cases -- depending on compiler support --
* the resulting view is automatically cast to the target class type. If
* the target class type is unconstrained, an explicit cast may be
* necessary.
*
* @param id the ID to search for
* @return a view with given ID if found, or {@code null} otherwise
* @see View#requireViewById(int)
*/
@Nullable
public final <T extends View> T findViewById(@IdRes int id) {
if (id == NO_ID) {
return null;
}
return findViewTraversal(id);
}
阅读更多

01-Flutter-快速入门实战

flutter

  • everything is a widget

widget

在flutter中,所有看得见的看不见的东西都是widget

目录结构

  • android:
  • ios:
  • lib: dart文件,业务逻辑
  • lib/main.dart: 入口
  • pubspec.yaml: 工程信息以及依赖
阅读更多

22-Gradle

核心概念

  • 项目
    • Gradle项目是一个可以构建的软件,例如应用程序或库。
    • 包括一个根项目和任意数量的子项目
  • 构建脚本
    • 构建脚本向 Gradle 详细介绍了构建项目所需采取的步骤。
    • 每个项目可以包含一个或多个构建脚本。
  • 依赖管理
    • 依赖管理是一种用于声明和解析项目所需的外部资源的自动化技术。
    • 每个项目通常都包含许多外部依赖项,Gradle 将在构建过程中解决这些依赖项。
  • 任务
    • 任务是基本的工作单元,例如编译代码或运行测试。
    • 每个项目都包含在构建脚本或插件中定义的一个或多个任务。
  • 插件
    • 插件用于扩展 Gradle 的功能,并可选择向项目贡献任务。

Gradle 项目结构

文件/目录名称 作用
gradlew/gradlew.bat Gradle 包装脚本
build.gradle(.kts) 项目的 Gradle 构建脚本
settings.gradle(.kts) Gradle 设置文件用于定义根项目名称和子项目
src 项目/子项目的源码、资源

使用gradle/gradlew编译

  • 编译

    1
    ./gradlew build
  • 编译单个任务

    1
    2
    ./gradlew :taskname
    ./gradlew taskname

    编译单个任务以及全部依赖

  • 编译多项目工程中的任务

    1
    2
    ./gradlew :subproject:taskName
    ./gradlew subproject:taskName

    :相当于分隔符,第一个冒号可以省略

  • 清理产物

    1
    ./gradlew clean
  • 执行多个任务

    1
    ./gradlew clean build
阅读更多

01-Binder

看源码的时候可以用uml图辅助理解

多进程

为什么多进程

  • 突破内存限制:Android系统在内存不足时,会优先杀占用内存多的进程
  • 功能稳定性:把一些功能放到独立的进程中,保证进程功能的纯粹性和稳定性
  • 规避系统内存泄漏:独立的WebView进程阻隔内存泄漏问题
  • 隔离风险:不稳定功能放到子进程,保证主进程的稳定性

Android中的进程间通信

  • Binder
    • aidl
  • Socket
  • 管道:handler
  • 共享内存
    • fresco,mmkv(匿名)
  • 信号:
    • ANR监控
    • matrix、xcrash、友盟apm
阅读更多