-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
从零开始学习 Android (笔记) #47
Comments
厉害了老哥 |
二、Android 编程1. IDE 和创建第一个项目下载 AndroidStudio,创建一个项目并编译,了解基本的流程。 2. Layout 与 Res 文件夹3. GradleGradle 是一个基于 JVM 的构建工具,基于 groovy,有强大的依赖管理,支持多工程构建。 Gradle 构建基础projects 和 tasks是 Gradle 中最重要的两个概念。
1、创建任务 1.1、创建一个最简单的task(build.gradle文件): task hello {
doLast {
println 'Hello world!'
}
} 我们可以执行 $ gradle -q hello
Hello world! 1.2、快速定义task: task hello << {
println 'Hello world!'
}
// << 等同于 doLast 1.3、使用groovy task upper << {
String someString = 'mY_nAmE'
println "Original: " + someString
println "Upper case: " + someString.toUpperCase()
} $ gradle -q upper
Original: mY_nAmE
Upper case: MY_NAME 2、任务依赖 2.1、 在两个任务之间指明依赖关系 task hello << {
println 'Hello world!'
}
task intro(dependsOn: hello) << {
println "I'm Gradle"
} $ gradle -q intro
Hello world!
I'm Gradle 2.2、延迟依赖 taskX 是可以在 taskY 之前定义的。 task taskX(dependsOn: 'taskY') << {
println 'taskX'
}
task taskY << {
println 'taskY'
} 3、动态任务 4.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}
// gradle -q task1 4、任务操纵 4.1、通过 API 进行任务之间的通信 - 增加依赖 4.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}
task0.dependsOn task2, task3 4.2、通过 API 进行任务之间的通信 - 增加任务行为 task hello << {
println 'Hello Earth'
}
hello.doFirst {
println 'Hello Venus'
}
hello.doLast {
println 'Hello Mars'
}
hello << {
println 'Hello Jupiter'
} doFirst 和 doLast 可以进行多次调用。他们分别被添加在任务的开头和结尾。当任务开始执行时这些动作会按照既定顺序进行。 5、短标记法 每个任务都是一个脚本的属性,你可以访问它。 以属性的方式访问任务: task hello << {
println 'Hello world!'
}
hello.doLast {
println "Greetings from the $hello.name task."
}
// $hello.name 就是 “hello” 6、增加自定义属性 task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties << {
println myTask.myProperty
} 7、调用 Ant 任务 Ant 任务是 Gradle 中的一等公民。Gradle 自带了一个 AntBuilder,可以通过它来调用一个 Ant 任务以及与 Ant 中的属性进行通信。 task loadfile << {
def files = file('../antLoadfileResources').listFiles().sort()
files.each { File file ->
if (file.isFile()) {
ant.loadfile(srcFile: file, property: file.name)
println " *** $file.name ***"
println "${ant.properties[file.name]}"
}
}
} 8、方法抽取 task checksum << {
fileList('../antLoadfileResources').each {File file ->
ant.checksum(file: file, property: "cs_$file.name")
println "$file.name Checksum: ${ant.properties["cs_$file.name"]}"
}
}
task loadfile << {
fileList('../antLoadfileResources').each {File file ->
ant.loadfile(srcFile: file, property: file.name)
println "I'm fond of $file.name"
}
}
File[] fileList(String dir) {
file(dir).listFiles({file -> file.isFile() } as FileFilter).sort()
} 9、定义默认任务 defaultTasks 'clean', 'run'
task clean << {
println 'Default Cleaning!'
}
task run << {
println 'Default Running!'
}
task other << {
println "I'm not a default task!"
} $ gradle -q
Default Cleaning!
Default Running!
Building Android Apps |
一、前置Java知识
Java 是一门强类型的面向对象的解释型语言,通过JVM可以在多平台运行。
1. 基础类型
8种内置类型,六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型:
byte
:8位,有符号整数,-128(-2^7)-- 127(2^7-1);short
:16位,有符号整数,-32768(-2^15)-- 32767(2^15 - 1);int
:32位,有符号整数,-2,147,483,648(-2^31)-- 2,147,483,647(2^31 - 1);long
:64位,有符号整数,-9,223,372,036,854,775,808(-2^63)-- 9,223,372,036,854,775,807(2^63 -1);float
:32位、单精度、符合IEEE 754标准的浮点数,不能表示精确的值,如货币;double
:64位、双精度、符合IEEE 754标准的浮点数,不能表示精确的值,如货币;boolean
:1位,只有两个取值:true和false;char
:16位,表示Unicode字符,最小值是’\u0000’(即为0),最大值是’\uffff’(即为65,535)。引用类型
对象、数组都是引用数据类型,所有引用类型的默认值都是null。
对前端而言,需要额外注意两点:
变量一旦声明,则类型确定,且不能更改(不能赋值其它类型)。
char 和 String 的区别:char是基本类型,对应一个字符;String 是引用类型,对应0或多个字符。
char a = 'a'; String x = "hi!";
2. 基本语法
MyFirstJavaClass
。public static void main(String args[])
**方法开始执行。总的来说,Java基本语法和一般程序语言的语法一致。相比JS,我们可能要注意 修饰符,接口等概念。
循环
和JS基本一致;不过可以注意下增强的for循环:
for(声明语句 : 表达式)
中表达式为数组。分支
与JS一致。
3. 类和对象
对象是类的一个实例,有状态和行为。类可以看成是创建Java对象的模板。一个类可以包含以下类型变量:
每个类都有构造方法。如果没有显式为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。
源文件声明规则
Java包
包主要用来对类和接口进行分类。我们用
package pkgName
来声明包,用import java.io.*
来引入包。4. 修饰符(访问控制及其它)
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java支持4种不同的访问权限。
默认的,也称为default,在同一包内可见,不使用任何修饰符。
接口里的变量都隐式声明为public static final,而接口里的方法默认情况下访问权限为public。
私有的,以private修饰符指定,在同一类内可见。
私有访问修饰符是最严格的访问级别,所以被声明为private的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为private。
公有的,以public修饰符指定,对所有类可见。
被声明为public的类、方法、构造方法和接口能够被任何其他类访问。
受保护的,以protected修饰符指定,对同一包内的类和所有子类可见。
被声明为protected的变量、方法和构造器能被同一个包中的任何其他类访问,也能够被不同包中的子类访问。
protected访问修饰符不能修饰类和接口,方法和成员变量能够声明为protected,但是接口的成员变量和成员方法不能声明为protected。
子类能访问protected修饰符声明的方法和变量。
访问控制和继承
父类中声明为public的方法在子类中也必须为public。
父类中声明为protected的方法在子类中要么声明为protected,要么声明为public。不能声明为private。
父类中默认修饰符声明的方法,能够在子类中声明为private。
父类中声明为private的方法,不能够被继承。
非访问修饰符
为了实现一些其他的功能,Java也提供了许多非访问修饰符。
static修饰符,用来创建类方法和类变量。
final修饰符,用来修饰类、方法和变量,final修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract修饰符,用来创建抽象类和抽象方法。
synchronized和volatile修饰符,主要用于线程的编程。
5. Java 的继承与接口
Java是完全面向对象的语言,继承是最重要的topic。Java只有单继承(相比多继承,减少复杂度和潜在的一些问题(比如函数重写)),但通过接口来保留多继承的一些优点。
典型的继承语法:
子类可以从父类继承所有的 protected/public 属性和方法。
我们知道,JS 中,基于原型链的继承机制,所有实例的方法调用的方法最终都指向原型(链)的某个方法,即方法在内存中只有一份,那在Java中一样吗?
答案是:是。
在Java中 new 一个对象时,为类的成员(包括(继承的)父类的成员)分配了内存空间,然后执行构造函数,初始化这些属性的值。
但对象并不会为方法分配内存,当调用对象的方法时,实质上是去方法区查找到对应的方法执行。
静态方法和私有方法在解析阶段确定唯一的调用版本,而其它实例方法,会去动态查找(沿继承链)。
参考:
6. Java 泛型
泛型类
泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。最典型的就是各种容器类,如:List、Set、Map。
泛型类的定义:
例子:
泛型的类型参数只能代表引用型类型,不能是原始类型(像int,double,char等)
泛型接口
泛型方法
泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型 。
有界的类型参数:
可能有时候,你会想限制那些被允许传递到一个类型参数的类型种类范围。例如,一个操作数字的方法可能只希望接受Number或者Number子类的实例。这就是有界类型参数的目的。
要声明一个有界的类型参数,首先列出类型参数的名称,后跟extends关键字,最后紧跟它的上界。
7. Java 多线程编程
8. Java 内存模型
源于同事的一次分享,查阅资料了解了Java虚拟机和内存管理相关知识。利于深入了解Java,对比JS可能有更大收获。
Run-Time Data Areas
堆区:存放所有类实例(对象)和数组,虚拟机启动时创建。由GC自动管理。
方法区(Method area and runtime constant pool):存放类的结构信息,虚拟机启动时创建。类似于传统语言中存放编译后代码的地方,它存放类的 (1)run-time constant pool(类似传统语言的符号表+其它),(2)成员和方法信息,(3)静态变量,(4)方法的代码等等。
虽然逻辑上来说,方法区也是堆的一部分,不过方法区一般不被GC管理(取决于JVM的具体实现)。
JVM Stack:每个Java线程创建时都会创建一个私有的JVM Stack,存储局部变量和部分结果,参与函数调用和返回。Stack本身只负责存储(push/pop)frames,frame 对应方法,负责存数据和部分结果,执行动态链接,返回方法的值或者dispatch异常。
Native Method Stacks:线程私有,但不是所有JVM都实现了。类似JVM Stack,用于执行 Native 方法服务。
frame通常包含:
PC register:线程私有。每个JVM线程都有自己的pc register,在任意时刻,每个线程都是在执行一个方法(记作 current method)。如果这个方法不是native的,那么pc register存着当前执行的JVM指令的地址;否则pc register的值是undefined。
The text was updated successfully, but these errors were encountered: