# DAY1 快速入门

## 0.一些概念

- 四大组件
- SQLite数据库
- Android系统架构
- 地理位置定位

## 1.DVM和JVM的区别

DVM(Dalvik VM) 安卓程序都在DVM里跑

| 区别           | jvm                 | dalvik vm                 |
 | -------------- | ------------------- | :------------------------ |
 | 编译后文件格式 | .java->.class->.jar | .java->.class->.dex->.apk |![1](E:\BLOG\source\_posts\android-DAY1快速入门\1.png)

在.jar中有许多.class,在.class中有头文件header,存有一些头信息,所以文件数越多加载会越慢

在.apk中只有一个.dex,也只有一个header,加载时速度快一点

在android5.0上使用了新的虚拟机ART

Dalvik: 应用每次运行的时候,字节码都需要通过即时编译器转换为机器码,这会拖慢应用的运行效率

ART: 应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用,应用的启动和执行速度都会显著提升

## 2.android开发环境搭建

 android studio + android SDK 

[官网]: developer.android.com

下载整合包一键安装即可

## 3.第一个Helloworld程序

- 启动模拟器

  android studio非常智能,你不需要编写任何代码,HelloWorld项目就已经可以运行了

  点击最左边的按钮![2.1](E:\BLOG\source\_posts\android-DAY1快速入门\2.1.png)

  ![2.2](E:\BLOG\source\_posts\android-DAY1快速入门\2.2.png)

选择Nexus 5X,点击绿色三角启动设备。

- 运行HelloWorld

  点击顶部工具栏中的运行按钮![2.3](E:\BLOG\source\_posts\android-DAY1快速入门\2.3.png) ,会弹出一个选择运行设备的对话框

  ![2.4](E:\BLOG\source\_posts\android-DAY1快速入门\2.4.png) 

      选择设备(这里没有启动模拟器因为它实在是太卡了),点击OK,等待一会儿,项目就会运行到模拟器上了

      ![helloworld](E:\BLOG\source\_posts\android-DAY1快速入门\helloworld.png)

- 使用第三方模拟器

  由于as自带的模拟器实在太卡太慢了,于是我决定换一个模拟器使用。这里我选择了夜神模拟器

  - 下载

    下载网址:https://www.yeshen.com/

    下载安装(傻瓜式安装)

  - 连接as

    同时启动as和夜神,cmd进入安装的bin目录下,输入nox_adb.exe connect 127.0.0.1:62001

    会显示连接成功![2.5](E:\BLOG\source\_posts\android-DAY1快速入门\2.5.png) 

             每次启动都需要执行一次以上操作,所以可以写成bat:新建txt文件输入:

> 你的夜神安装的bin目录>nox_adb.exe connect 127.0.0.1:62001  

保存成.bat

那么来启动试试看

这里的connected devices就是连接的第三方模拟器

![2.6](E:\BLOG\source\_posts\android-DAY1快速入门\2.6.png)
成功运行
![helloworld_yeshen](E:\BLOG\source\_posts\android-DAY1快速入门\helloworld_yeshen.png)

- 分析第一个android程序

首先展开项目

![2.8](E:\BLOG\source\_posts\android-DAY1快速入门\2.8.png)

任何一个新建的项目都会默认使用Android模式的项目结构,但这并不是项目真实的目录结构,而是被as转换过的,点击Android区域,切换成Project,这就是项目真实的目录结构了

![2.9](E:\BLOG\source\_posts\android-DAY1快速入门\2.9.png)

- 项目结构

  - 1. .gradle和.idea

      这两个目录下放置的是as自动生成的一些文件

  - 1. app

  项目中的代码、资源都放在这里

  - 1. build

  包含在编译时生成的文件

  - 1. gradle

  包含了gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle

> **Gradle**是一个基于[Apache Ant](https://link.zhihu.com/?target=http%3A//zh.wikipedia.org/wiki/Apache_Ant)和[Apache Maven](https://link.zhihu.com/?target=http%3A//zh.wikipedia.org/wiki/Apache_Maven)概念的项目[自动化建构](https://link.zhihu.com/?target=http%3A//zh.wikipedia.org/wiki/%25E8%2587%25AA%25E5%258B%2595%25E5%258C%2596%25E5%25BB%25BA%25E6%25A7%258B)工具。它使用一种基于[Groovy](https://link.zhihu.com/?target=http%3A//zh.wikipedia.org/wiki/Groovy)的[特定领域语言](https://link.zhihu.com/?target=http%3A//zh.wikipedia.org/w/index.php%3Ftitle%3D%25E7%2589%25B9%25E5%25AE%259A%25E9%25A2%2586%25E5%259F%259F%25E8%25AF%25AD%25E8%25A8%2580%26action%3Dedit%26redlink%3D1)来声明项目设置,而不是传统的[XML](https://link.zhihu.com/?target=http%3A//zh.wikipedia.org/wiki/XML)。当前其支持的语言限于[Java](https://link.zhihu.com/?target=http%3A//zh.wikipedia.org/wiki/Java)、[Groovy](https://link.zhihu.com/?target=http%3A//zh.wikipedia.org/wiki/Groovy)和[Scala](https://link.zhihu.com/?target=http%3A//zh.wikipedia.org/wiki/Scala),计划未来将支持更多的语言。
  以上是wiki对gradle的解释,看起来不好理解,在知乎上找到了这个回答: https://www.zhihu.com/question/30432152
  > 1. Gradle**是一种构建工具**,它可以帮你管理项目中的差异,依赖,编译,打包,部署......,你可以定义满足自己需要的构建逻辑,写入到build.gradle中供日后复用.
   > 2. Gradle**不是一种编程语言**,它不能帮你实现软件中的任何实际功能  - 1. gitignore
       用来将指定的陌路或文件排除在版本控制之外的
  - 1. build.gradle
       这是项目全局的gradle构建脚本,通常这个文件中的内容是不需要修改的
  - 1. gradle.properties
       这是全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本
  - 1. gradlew和gradlew.bat
       用来在命令行下执行gradle命令 gradlew用于mac/linux,gradlew.bat用于windows
  - 1. 项目名.iml
       iml文件是所有Intellij IDEA项目都会自动生成的文件,as是基于IDEA开发的
  - 1. local.properties
       用于指定本机中的Android SDK路径
  - 1. settings.gradle
       用于指定项目中所有引入的模块
  - 12.app目录下的结构
    - 1. build
         编译文件
    - 1. libs
         库文件
    - 1. res
         引用的资源,图片放在drawable目录下,布局放在layout目录下,字符串放在values目录下
    - 1. AndroidManifest.xml
         整个Android项目的配置文件,程序中定义的所有组件都要在这个文件里注册
    - 1. proguard-rules.pro
         指定项目代码的混淆规则
接下来打开AndroidManifest.xml,从中可以找到如下代码
```xml
 <activity android:name=".MainActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
 ```这段代码表示对MainActivity这个活动进行注册,没有在AndroidManifest.xml里注册的活动是不能使用的。在<intent-filter></intent-filter>标签中的两句代码表示MainActivity是这个项目的主活动,在手机上启动应用,首先显示的就是这个活动。活动是应用程序的门面,凡是应用中看得到的东西,都是放在活动中的。打开MainActivity,代码如下所示:
```java
 public class MainActivity extends AppCompatActivity {    @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
     }
 }
 ```MainActivity是继承自AppCompatActivity的,AppCompatActivity是Activity的一个子类。Activity是Android提供的一个活动基类。还可以看到有一个onCreate()方法,这个方法是一个活动被创建时必须要执行的方法。但是没有输出Helloworld的字样。在Android程序中讲究逻辑和界面分离,不推荐在活动中直接编写界面,更通用的方法是在布局文件中编写界面,然后在活动中引入进来。可以看到在onCreate()方法中调用了 setContentView()方法,就是给当前活动引入了一个activity_main的布局,进入layout目录,打开activity_main.xml,代码如下所示:
```xml
 <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     tools:context=".MainActivity">    <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="Hello World!"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent" /></android.support.constraint.ConstraintLayout>
 ```TextView是一个控件
- 项目中的资源
  res文件夹中,mipmap开头的文件夹是放应用图标的,以values开头的文件夹是放字符串、样式、颜色等配置文件的,layout文件夹是放布局文件的,drawable文件夹是用来放图片的。
  打开res/values/string.xml文件
  ```xml
   <resources>
       <string name="app_name">MyFirstApplication</string>
   </resources>
   ```  定义了一个app_name的字符串,可以通过R.string.app_name(代码中)/@string.app_name(xml中)引用。
- build.gradle文件
  不同于eclipse,as使用Gradle构建项目。Gradle使用了基于Groovy的语言DSL声明项目设置。在项目中我们可以看到两个build.gradle文件。先打开最外层的gradle文件
  ```groovy
   buildscript {
       
       repositories {
           google()
           jcenter()
       }
       dependencies {
           classpath 'com.android.tools.build:gradle:3.2.0'
           
   
           // NOTE: Do not place your application dependencies here; they belong
           // in the individual module build.gradle files
       }
   }
   
   allprojects {
       repositories {
           google()
           jcenter()
       }
   }
   ```  jcenter()是一个代码托管仓库,声明这行配置可以引用任何在jcenter上开源的项目
  dependencies闭包中有这样一行:classpath 'com.android.tools.build:gradle:3.2.0'  因为Gradle不是针对android项目开发的,Java、C++项目也可以用Gradle。所以需要声明。最后的数字是gradle插件的版本号。
  再来看app目录下的build.gradle
  ```groovy
   apply plugin: 'com.android.application'
   
   android {
       compileSdkVersion 28
       defaultConfig {
           applicationId "com.example.gordan.myfirstapplication"
           minSdkVersion 15
           targetSdkVersion 28
           versionCode 1
           versionName "1.0"
           testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
       }
       buildTypes {
           release {
               minifyEnabled false
               proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
           }
       }
   }
   
   dependencies {
       implementation fileTree(dir: 'libs', include: ['*.jar'])
       implementation 'com.android.support:appcompat-v7:28.0.0'
       implementation 'com.android.support.constraint:constraint-layout:1.1.3'
       testImplementation 'junit:junit:4.12'
       androidTestImplementation 'com.android.support.test:runner:1.0.2'
       androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
   }
   
   ```

  第一行应用了插件com.android.application,表示这是一个应用程序模块,这行一般有两种值选择,还有一种com.android.library表示这是一个库模块。

  在android闭包中是项目构建的各种属性。compileSdkVersion表示项目编译版本。

  在defaultConfig闭包中,applicationId用于指定项目的包名,minSdkVersion为最低兼容的系统版本,15表示最低兼容到4.0系统。targetSdkVersion表示在该目标版本上已经做过充分测试。versionCode、versionName表示项目版本号和版本名。

  buildTypes闭包用于指定生成安装文件的相关配置。minifyEnabled用于指定是否对代码进行混淆,默认false。proguardFiles指定混淆时使用的规则文件,proguard-android.txt是位于SDK目录的,内容是所有项目通用的混淆规则,proguard-rules.pro位于本项目根目录,用于指定本项目特有的混淆规则。

  dependencies闭包指定当前项目所有的依赖关系。as项目通常有本地依赖、库依赖、远程依赖三种方式。

  第一行将libs目录下所有.jar文件都引用进来。第二行是远程依赖声明。

- 日志工具Log

  Android的日志工具类是Log      (android.util.log)    Log的方法如下:

  1. Log.v() 用于打印最琐碎的,意义最小的日志信息。是日志中级别最低的,对应级别verbose
  2. Log.d() 用于打印调试信息,对应级别debug,比verbose高一级
  3. Log.i() 打印一些比较重要的数据,对应级别info,比debug高一级
  4. Log.w() 打印一些警告信息,对应warn,比info高一级
  5. Log.e() 打印错误信息 一般进到catch语句中打印。对应error,比warn高一级

  在MainActivity.java的onCreate中加一行Log.d("MainActivity","execute"),运行app,在底部logcat窗口可以看到打印了execute。

- SDKManager介绍

  adb全称android debug bridge 是安卓的调试工具(命令行)

  dx.bat 把所有.class文件变成-dex文件

  aapt Android应用打包工具