红岩2019Android学员第一课

Android第一节正式的课

Android开发基础

什么是Android

以下来自百度百科:

安卓(Android)是一种基于Linux的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机平板电脑,由Google公司和开放手机联盟领导及开发。Android操作系统最初由[Andy Rubin](https://baike.baidu.com/item/Andy Rubin)开发,主要支持手机。2005年8月由Google收购注资。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。随后Google以Apache开源许可证的授权方式,发布了Android的源代码。第一部Android智能手机发布于2008年10月。Android逐渐扩展到平板电脑及其他领域上,如电视数码相机游戏机智能手表等。2011年第一季度,Android在全球的市场份额首次超过塞班系统,跃居全球第一。 2013年的第四季度,Android平台手机的全球市场份额已经达到78.1%。2013年09月24日谷歌开发的操作系统Android在迎来了5岁生日,全世界采用这款系统的设备数量已经达到10亿台。

一些关于Android开发的名词

  • Android SDK(Android software development kit)

    软件开发工具包。被软件开发工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具集合

  • AVD(Android Virtual Device)

    Android运行的虚拟设备,他是Android的模拟器识别。建立的Android要运行,必须创建AVD,每个AVD上可以配置很多的运行项目

  • JDK(Java development kit)

    这里写图片描述

  • JRE(Java Runtime Environment)

    这是一个软件,由太阳微系统所研发,JRE可以让计算机系统运行Java应用程序

    JRE内部有一个Java虚拟机(Java Virtual Machine, JVM),以及一些标准的类别函数库

关于一个App的开发流程

  • 口述

一些扩展

  • Android程序的设计

    Android程序的设计讲就逻辑和视图分离,所以不推荐在逻辑代码里面直接编写界面,我们目前采用的是Java(Kotlin)和xml的混编,通用做法是在布局文件中编写界面,然后在中逻辑代码引入。在 onCreat()方法的第二行调用了一个setConten()方法来引入布局。

  • xml 

    xml的全名是Extensible Markup Language,翻译成中文就是可扩展标记语言

  • Java

    • JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版)

    • JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平台企业版)

    • JavaME(J2ME)(Java 2 Platform Micro Edition,java平台微型版)。

  • Kotlin

    Kotlin是一个用于现代多平台应用的静态编程语言,由JetBrains设计开发并开源,其被称之为Android世界的Swift,可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVm的设备上运行。在Google I/O 2017中,Google宣布Kotlin成为Android官方开发语言。

    Android和Java,一个是最受欢迎的移动开源系统,一个是最流行的编程语言。一个背后是谷歌,一个背后是甲骨文,这两大巨头就Android侵犯Java的版权之战,他们之间的恩怨持续了八年之久。

    新事物和新技术的出现虽然不一定要替代旧技术,但它的到来是无可阻挡的。在以前我们讨论Android时,Java是主要的编程语言,但是其实有很多其他的语言可用于编写Android应用程序也符合JVM编程语言,而其中Kotlin成为了打破那个秩序的先行者。在谷歌的高度宣传以后,现在很多的程序员已经将Kotlin称为编写Android应用程序的高级语言。

Android四大组件

  • Activity

    • 生命周期

      Activity的四个状态

      activity生命周期

      • 常规 onCreate->onStart->onResume->onPause->onStop->onDestroy

        activity的生命周期

      • 特殊 

        1.onRestart : Activity 由不可见变为可见

        2.onSaveInstance和onRestoreInstance:横竖屏切换以及意外销毁

        o

  • Service

  • Broadcast

  • ContentProvider

Activity

生命周期

  • Activity切换时,生命周期的变化

    当A_activity切换B_activity的时候,程序的执行流程如下

    A_activity: onCreate() -> onStart() -> onResume ->onPause()

    B_activity: onCreate() -> onStart() -> onResume()

    A_activity: onStop() -> onDestory()

  • Activity的进程优先级(从高到低排列)

    1. 前台进程(ps:目前你们只用看第一点就行了,第二点暂时不用管)

      1)当前Activity正在与用户交互)

      2)当前进程service正在与activity进行交互或者当前service调用了startForground()属于前台进程或者当进程持有一个BroadcostReciver, 这个BroadcostReceiver正在执行onReceive()方法

    2. 可见进程(ps:目前你们只用看第一点就行了,第二点暂时不用管)

      1)进程持有一个activity,这个activity不在前台,处于onPouse()状态下,当前覆盖的activity是以弹窗形式存在的。

      2)进程持有一个service,这个service是和一个可见的activity进行绑定的

    3. 后台进程

      activity的onStop()被调用,但是onDestroy()没有被调用的状态

    4. 空进程

      该进程没有任何运行的数据了,且保留内存空间,并没有被系统killed,属于空进程

Activity的四种启动模式

  1. standard

    Activity的默认的起动模式。在这个模式下,每启动一个新的Activity,它就会进入返回栈,并处于栈顶位置。对于使用本模式的Activity,系统不会在乎这个Activity是否已经处于返回栈的栈顶。每次启动都会创建一个新的Activity

  2. singleTop

    当一个Activity的启动模式被指定为本模式时,在启动该Activity的时候,,如果发现返回栈的栈顶已经是该Activity,则认为直接使用它,不会再创建新的Activity实例。

  3. singleTask

    让被标记的Activity在整个程序的上下文中只存在一个实例。当一个Activity启动方式被指定为singleTask后,每次启动该Activity的时候系统会首先在返回栈中检查是否有该Activity的实例,如果发现存在则直接使用该实例,并把在这个Activity之上的所有Activity通通出栈,如果没有发现则创建一个该Activity的实例。

  4. singleInstance

    被指定为singleInstance模式的Activity会启用一个新的栈来管理这个Activity。意义所在,假如我们的一个Activity是允许被其他程序屌用的,如果我们想实现其他程序和我们的程序共享这个Activity的实例,其他三种模式是肯定做不到的,因为每一个应用程序都会有自己的返回栈,用一个Activity在不痛的返回栈中入栈时必定是创建了新的实例。而本模式下则会有一个单独的栈来管理这个Activity,不管是那个应用程序来访问这个Activity,都用的同一个返回栈,也就解决了前面提出的问题。

Activity之间的通信

  • Intent

    显示跳转、隐式跳转

  • intent.putExtra()

  • startActivityForResult

Context

我们知道,Android应用都是使用Java语言来编写的,那么大家可以思考一下,一个Android程序和一个Java程序,他们最大的区别在哪里?划分界限又是什么呢?其实简单点分析,Android程序不像Java程序一样,随便创建一个类,写个main()方法就能跑了,而是要有一个完整的Android工程环境,在这个环境下,我们有像Activity、Service、BroadcastReceiver等系统组件,而这些组件并不是像一个普通的Java对象new一下就能创建实例的了,而是要有它们各自的上下文环境,也就是我们这里讨论的Context。可以这样讲,Context是维持Android程序中各组件能够正常工作的一个核心功能类。

从系统的角度来理解:Context是一个场景,代表与操作系统的交互的一种过程。
Context是一个抽象类;
ActivityServiceApplication是它的子类

UI

  • 什么是UI

    UI即User Interface(用户界面)的简称。 UI设计是指对软件的人机交互、操作逻辑、界面美观的整体设计。好的UI设计不仅是让软件变得有个性有品位,还要让软件的操作变得舒适简单、自由,充分体现软件的定位和特点。 软件设计可分为两个部分:编码设计与UI设计。UI的本意是用户界面,是英文User和 Interface的缩写。从字面上看是用户与界面2个部分组成,但实际上还包括用户与界面之间的交互关系。(来自百度)

  • 如何编写程序界面

    Android Studio是给我们提供了可视化编辑器的,允许我们通过拖放控件的方式来编写布局,但是这种方式做出来的界面通常不具有很好的适配性(ps:也不是说不能有适配,只是相对来说比较麻烦,个人还是认为用代码编写布局的更加舒服),我们还可以通过xml代码的方式来编写布局界面。

  • Material Design

    Google的官方设计语言。在Material Design未发布时,它有另外一个名字:Quantum Paper(量子纸)。“量子”代表的是物理、变幻、科技。概括来讲,Material Design是这样一种设计语言:它从物理世界的纸墨中得到灵感,期望通过还原物理世界的规则,并在物理世界的基础上进行抽象简化,进而提炼出一套跨平台的设计规范,让用户更容易理解并更自然地与电子产品进行交互。它强调映射现实世界、强调光影和动画,让内容以纸张的质感,呈现给用户。

    《第一行代码》p407的讲解更加浅显易懂

  • 几个单位

    1. dp

      安卓中的相对大小

      • 其实dp就是为了使得开发者设置的长度能够根据不同屏幕(分辨率/尺寸也就是dpi)获得不同的像素(px)数量。比如:我将一个控件设置长度为1dp,那么在160dpi屏幕上该控件长度为1px,在240dpi的屏幕上该控件的长度为1*240/160=1.5个像素点。
      • 也就是dp会随着不同屏幕而改变控件长度的像素数量。
      • 关于dp的官方叙述为当屏幕每英寸有160个像素时(也就是160dpi),dp与px等价的。那如果每英寸240个像素呢?1dp—>1*240/160=1.5px,即1dp与1.5px等价了。
      • 其实记住一点,dp最终都要化为像素数量来衡量大小的,因为只有像素数量最直观。
    2. dpi(dot per inch)

      每英寸像素多少

      要想判别手机屏幕的显示好坏,还要考虑屏幕的宽高(英寸),也就是用dpi即每英寸多少像素来评价屏幕的显示效果。(不然假如手机分辨率是1920×1080,但是屏幕是几十寸的,那显示效果将不会很好,甚至你有可能看到小的像素块,那将更影响视觉效果。)

    3. px

      像素点

      平常所说的1920×1080只是像素数量,也就是1920px×1080px,代表手机高度上有1920个像素点,宽度上有1080个像素点。

    4. sp

      sp除了能够像dp一样可以适应屏幕密度的变化,还可以随着系统字体的大小设置改变作出变化。如果不想文字随着手机设置中字体的大小发生改变(例如标题),可以使用dp代替。

  • xml中的一些东西

    首先我们需要知道xmlns是xml namespace的缩写,意思是sml命名空间

    1. android前缀

      1
      xmlns:android="http://schemas.android.com/apk/res/android"
      • 这句话的意思是,声明这个命名空间引用的是Android系统的,而其中的android作为前缀,是这个引用别称的意思(ps:换成其他的也不是不行)
      • 后面的schemas的意思是xml文件的约束(也就是xml的抒写规范),还有一种xml的约束是DTD,但是被DTD取代了
      • 有了这个,Android Studio就会在我们编写布局文件的时候给出提示,提示我们可以输入什么,不可以输入什么。也可以理解为语法文件吗.,或者语法判断器
    2. app前缀

      1
      xmlns:app="http://schemas.android.com/apk/res-auto"
      • 在项目需求中,我们往往使用系统自带的属性和控件是不够的,我们可能需要导入自定义控件的一些属性,或者support支持包之类的
      • 为了引入自定义属性,我们以xmlns:前缀=http://schemas.android.com/apk/res/你的应用程序包路径,将其导入,但是现在的普遍走法是使用xmlns:app=”http://schemas.android.com/apk/res-auto“,因为res-auto可以引用所有的自定义包名。
    3. tool前缀

      1
      xmlns:tools="http://schemas.android.com/tools"
      • tools可以告诉Android Studio,那些属性在运行的时候是被忽略的,只是在设计布局的时候有效果
      • tools可以覆盖android所有的标准属性,将android:换成tools:即可,而且在运行的时候连tools本身都是被忽略的,不会被带进apk
    4. 一些普遍的属性

      1
      2
      3
      4
      5
      android:layout_width
      android:id
      android:layout_height
      android:margin
      android:padding
  • 图片

    1. 位图

      位图图像(bitmap),亦称为点阵图像或栅格图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样。当放大位图时,可以看见赖以构成整个图像的无数单个方块。扩大位图尺寸的效果是增大单个像素,从而使线条和形状显得参差不齐

    2. 矢量图

      矢量图,也称为面向对象图像或绘图图像,在数学上定义为一系列由线连接的点。矢量文件中的图形元素称为对象。每个对象都是一个自成一体的实体,它具有颜色、形状、轮廓、大小和屏幕位置等属性。

      矢量图是根据几何特性来绘制图形,矢量可以是一个点或一条线,矢量图只能靠软件生成,文件占用内在空间较小,因为这种类型的图像文件包含独立的分离图像,可以自由无限制的重新组合。它的特点是放大后图像不会失真,和分辨率无关

  • 下面讲解一些常用的控件和一些常用的属性

    • TextView
    • Button
    • EditText
    • ImageView
    • ProgressBar
    • AlertDialog
  • 布局

    • LinearLayout(线性布局)

      一种非常常用的布局,这个布局中的控件会在线性方向排列,通过android:orientation这个属性来指定线性排列的方向是垂直的(vertical)还是水平的(horizental)

      这里讲一下android:layout_gravityandroid:gravity。这两个都是设置对齐方式的属性,内部的值都相同

      img
      • android:layout_gravity是设置自身相当于父容器的对齐方式。比如一个TextView设置layout_gravity属性,则表示这个TextView本身相对于父容器的对齐方式。

        需要注意,如果要使用gravity属性的话,该组件的layout_widthlayout_height不能设置为wrap_content,此时设置的gravity属性没有效果,因为组件包裹着内容,无论设置什么,也不能有改变

      • android:gravity是设置自身内部元素的对齐方式。比如一个TextView,则是设置的内部文字的对齐方式。如果是ViewGroup组件是LinearLayout的话,则设置它内部view组件的对齐方式。(但是如果在FrameLayout中,这个属性就没有任何的作用)

        layout_gravity属性不是什么情况下都能设置的属性(比如LinearLayout的排列方向是horizental时,只有在垂直的方向上才会生效,因为水平方向上的长度是不固定的,每添加一个控件,水平方向上的长度都会改变,因而无法指定该方向上的对齐方式),而且在不同的ViewGroup中也会产生的效果也会不同

    • RelativeLayout(相对布局)

      它可以通过相对定位的方式让控件出现在布局的任何位置,属性非常多。不过她的属性十分有规律

    • FrameLayout(帧布局)

      这种布局,所有的控件都会默认摆在布局的左上角

    • PercentFrameLayout(百分比布局)

      这种布局最大的特点就是我们不可以使用wrap_content、match_parent等方式来指定控件的大小,而是允许直接使用控件在布局中所占的百分比,

    • ConstraintLayout(约束布局)

      在2016年之前,如果我们要写一些设计很复杂的页面,我们可能会借助于嵌套实现,但是我们嵌套的越多,性能就越低。为了提升开发者的可视化编程,谷歌官方在2016年的I/O大会上提出了新的组件ConstrainLayout(约束布局)

      下面是ConstraintLayout的几个重要的点

      • 1
        app:layout_constraintHorizontal_bias=".3" //数值范围:0~1
  如果控件约束了左右边缘且定义了bias为0.3,则意味着控件与左边缘的距离占控件左右边缘间距的30%。![img](https://upload-images.jianshu.io/upload_images/1929170-ec9cb35605c719da.png?imageMogr2/auto-orient/strip|imageView2/2/w/996/format/webp)

* 角度定位

  以以一个角度和距离来约束两个控件的中心

  
1
2
3
4
5
6
7
8
9
10
11
12
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintCircle="@+id/TextView1"
app:layout_constraintCircleAngle="120"
app:layout_constraintCircleRadius="150dp" />
![img](https://upload-images.jianshu.io/upload_images/2787721-8e87f3b229af0add.png?imageMogr2/auto-orient/strip|imageView2/2/w/221/format/webp) * 宽高比 当宽或者高至少有一个尺寸被设置为0dp时,可以通过属性layout_constraintDimensionRatio设置宽高比
1
2
3
4
5
6
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
上面这个TextView出现的效果就是宽高比1:1,即一个正方形 * 链 如果两个或以上控件通过下图的方式约束在一起,就可以认为是他们是一条链(图为横向的链,纵向同理)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/TextView2" />

<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintRight_toLeftOf="@+id/TextView3"
app:layout_constraintRight_toRightOf="parent" />

<TextView
android:id="@+id/TextView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/TextView2"
app:layout_constraintRight_toRightOf="parent" />
一条链的第一个控件是这条链的链头,我们可以在链头中设置 layout_constraintHorizontal_chainStyle来改变整条链的样式。chains提供了3种样式,分别是: CHAIN_SPREAD —— 展开元素 (默认); CHAIN_SPREAD_INSIDE —— 展开元素,但链的两端贴近parent; CHAIN_PACKED —— 链的元素将被打包在一起。 ![img](https://upload-images.jianshu.io/upload_images/2787721-6d3fd9ce0f0cfd75.png?imageMogr2/auto-orient/strip|imageView2/2/w/477/format/webp) * Guideline 暂时不讲,请自行了解 * baseline 当你两个控件高度不一致,但是你又想让他们的文字对齐 ![img](https://upload-images.jianshu.io/upload_images/2787721-815cc21cdfaa018c.png?imageMogr2/auto-orient/strip|imageView2/2/w/177/format/webp) ![640?wx_fmt=png](https://ss.csdn.net/p?https://mmbiz.qpic.cn/mmbiz_png/zKFJDM5V3Wx34xNNyyKwibbLdalqu4ibVMTth8ByiaQAichKd3hD4tWA4C3KPRpUn0WTE60UJlLBExFTgmsAlN7ghA/640?wx_fmt=png)
1
2
3
4
5
6
7
8
9
<TextView
android:id="@+id/TextView1"
.../>

<TextView
android:id="@+id/TextView2"
...
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintBaseline_toBaselineOf="@+id/TextView1"/>
![img](https://upload-images.jianshu.io/upload_images/2787721-aebcad66710f4d48.png?imageMogr2/auto-orient/strip|imageView2/2/w/213/format/webp)

一些奇奇怪怪的东西

Log/Toast

  1. Log和sout的区别
  2. Toast的使用

写在最后

大家已经坚持了大半学期了,接下来就是Android的世界,希望大家不要放弃。既然选择了远方,便只顾风雨兼程。要知道太阳背后也不是光,当你因为困难想放弃的时候,即使你看不到未来,即使你的眼前一片漆黑,但是请记住,人最怕的不应该是黑暗,而是习惯黑暗。当时我刚接触这些东西的时候,这就是一片汪洋,我差点淹死在里面(虽然现在还是很菜,但是泡了这么久,还是有了一点水性,你们只要认真学,一定可以在Android的世界自由遨游)。你们这一届,真的很多人都很优秀,绝大部分人已经超越大一时候的我太多太多。

就算有些同学现目前进度跟不太上也没有关系,你们还有这学期剩下的时间和一整个寒假的时间来弥补。你们一定要努力学习啊,既然都已经来到了红岩,来到了移动开发,我们都希望你们真的能够学到点东西,可能目前还体现不出来好处。但是多学点东西总是没有错的,当丰富自己的大学经历不也挺好的嘛。就算以后毕业了,想起这段刻苦学习的日子,我觉得心中也会泛起一丝温暖的。

如果你能做到的东西,别人 都能做到,那么以后真的出了社会、升了学,你就缺乏核心竞争力,你就注定只能给别人当背景板,千万不要让本来努力就可以得到的东西,因为懈怠而失去了机会。我觉得人一定不能有傲气,但是人一定要有傲骨,就为了以后不给别人当背景板,现在咬咬牙,多坚持一下,雪总会化,花总会开。

最后的最后。爱自己的最好的方式,就是让自己变得优秀起来。

Created by Irving