/** * Calls the specified function [block] and returns its result. */ @kotlin.internal.InlineOnly public inline fun <R> run(block: () -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() }
示例
1 2 3 4 5 6 7 8
fun runTest1() { varname="AA" run { valname="BB" Log.e(TAG, name) // BB } Log.d(TAG, name) // AA }
fun runTest2() { varsuccess=true varresult= run { if (success) { "200" } else { "404" } } Log.d(TAG, result) // 200 }
run() 返回作用域中的最后一个对象。
T.run()
定义
1 2 3 4 5 6 7 8 9 10
/** * Calls the specified function [block] with `this` value as its receiver and returns its result. */ @kotlin.internal.InlineOnly public inline fun <T, R> T.run(block: T.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() }
T.run() 中通过 this 来获取 “ABCDEF” 对象,然后输出 length . T.run() 返回作用域中的最后一个对象。
with()
定义
1 2 3 4 5 6 7 8 9 10
/** * Calls the specified function [block] with the given [receiver] as its receiver and returns its result. */ @kotlin.internal.InlineOnly public inline fun <T, R> with(receiver: T, block: T.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return receiver.block() }
/** * Calls the specified function [block] with `this` value as its argument and returns its result. */ @kotlin.internal.InlineOnly public inline fun <T, R> T.let(block: (T) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block(this) }
示例
1 2 3 4 5 6
fun letTest() { valresult="ABCDEF".let { it.substring(2) // it 代表 "ABCDEF" } Log.d(TAG, result) // CDEF }
T.let() 返回作用域中的最后一个对象。
T.also()
定义
1 2 3 4 5 6 7 8 9 10 11 12
/** * Calls the specified function [block] with `this` value as its argument and returns `this` value. */ @kotlin.internal.InlineOnly @SinceKotlin("1.1") public inline fun <T> T.also(block: (T) -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block(this) returnthis }
示例
1 2 3 4 5 6
fun alsoTest() { valresult="ABCDEF".also { it.substring(2) // it 代表 "ABCDEF" } Log.d(TAG, result) // ABCDEF }
T.also() 返回原来的对象不变。
T.apply()
定义
1 2 3 4 5 6 7 8 9 10 11
/** * Calls the specified function [block] with `this` value as its receiver and returns `this` value. */ @kotlin.internal.InlineOnly public inline fun <T> T.apply(block: T.() -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block() returnthis }
示例
1 2 3 4 5 6
fun applyTest() { valresult="ABCDEF".apply { this.substring(2) // this 代表 "ABCDEF" } Log.d(TAG, result) // ABCDEF }
Fragment 可视为 Activity 的模块化组成部分,它具有自己的生命周期。Fragment 必须始终嵌入在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。
每个 Fragment 都可设计为可重复使用的模块化 Activity 组件,可以将一个 Fragment 加入多个 Activity . 因此,应该采用可复用式设计,避免直接从某个 Fragment 直接操纵另一个 Fragment . 因为模块化 Fragment 可以通过更改 Fragment 的组合方式来适应不同的屏幕尺寸。在设计可同时支持平板电脑和手机的应用时,可以在不同的布局配置中重复使用 Fragment , 以根据可用的屏幕空间优化用户体验。 例如,在手机上,如果不能在同一 Activity 内储存多个 Fragment , 可能必须利用单独 Fragment 来实现单窗格 UI .
当 Activity 正在运行(处于已恢复生命周期状态)时,可独立操纵每个 Fragment , 如添加或移除它们。当执行此类 Fragment 事务时,也可以将其添加到由 Activity 管理的返回栈 — Activity 中的每个返回栈条目都是一条已发生 Fragment 事务的记录。返回栈让用户可以通过按返回按钮撤消 Fragment 事务(后退)。
创建Fragment
要创建一个 Fragment 必须扩展 Fragment 类(或已有的其子类 DialogFragment、ListFragment、PreferenceFragment)。
Fragment 通常用作 Activity 用户界面的一部分,将其自己的布局融入 Activity . 要想为 Fragment 提供布局,必须实现 onCreateView() 回调方法,Android 系统会在 Fragment 需要绘制其布局时调用该方法。此方法返回的 View 必须是 Fragment 布局的根视图。
getSupportFragmentManager().popBackStack(String name, int flags) // 根据 name 立刻弹出栈顶的 Fragment
getSupportFragmentManager().popBackStack(int id, int flags) // 根据 id 立刻弹出栈顶的 Fragment
Fragment常用的API
android.support.v4.app.Fragment 主要用于定义 Fragment
android.support.v4.app.FragmentManager 主要用于在 Activity 中操作 Fragment , 可以使用 FragmentManager.findFragmenById、FragmentManager.findFragmentByTag 等方法去找到一个 Fragment
android.support.v4.app.FragmentTransaction 保证一系列 Fragment 操作的原子性
栈内复用模式。这是一种单实例模式,如果在栈中已经有该 Activity 的实例,就重用该实例(会调用实例的 **onNewIntent()**)。具体地说,当一个具有 singleTask 模式的 Activity 请求启动后,如 Activity A , 系统首先会寻找是否存在 A 想要的任务栈,若不存在,则重新创建一个任务栈,然后创建 A 的实例后把 A 放入栈中。若存在,这时要看 A 是否在栈中有实例存在,若有实例存在,那么系统就会把 A 调到栈顶(此时还会把 A 上面的实例移除出栈)并调用它的 onNewIntent 方法,若没有实例存在,则创建 A 的实例并把 A 压入栈中。
子类中所有的构造方法默认都会先去调用父类中的无参构造方法。因为子类继承了父类的数据,可能还会使用到父类的数据,因此,子类初始化前需先完成父类数据的初始化。父类的初始化是通过调用方法区中的构造方法进行的,不会创建父类对象,对象需要通过 new 关键字创建。
new 关键字有两个作用。①、分配内存,创建对象;②、调用构造方法,完成对象的初始化工作。完成这两步后,才算创建了一个完整的 Java 对象。 所以 new 子类的时候,调用父类的构造方法不是创建了一个父类对象,而是只对它的数据进行初始化,那么父类这些数据存储在哪里呢?通俗地说,子类对象内存区域中会划一部分区域给父类的数据做存储,即子类对象内存中封装了父类的初始化数据,创建子类对象时,父类的数据就是子类的对象的一部分,不存在独立的父类的对象,所有的东西在一起才是一个完整的子类的对象。