Android-1-基础入门

1.Android系统结构

(1)Linux内核:为Android设备的各种硬件提供了底层的驱动,如显示驱动、蓝牙驱动、Wi-Fi驱动。

(2)核心类库:包含系统库和Android运行时库。

         系统库主要是通过C/C++库来为Android系统提供主要的特性支持,如SQLite库提供了数据库的支持,Webkit库提供了浏览器内核的支持等。

         Android运行时库主要提供了一些核心库,能够允许开发者使用Java语言来编写Android应用。Android运行时库还包含了Dalvik虚拟机,它使得每一个Android应用都能运行在独立的进程中,并且拥有一个自己的Dalvik虚拟机实例。

(3)应用框架层:提供了构建应用程序时用到的各种API,例如视图(View),活动管理器(Activity Manager)

(4)应用层:就是一个软件应用。

2.四大组件

(1)Activity(活动):是所有Android应用程序的门面,凡是在应用中你看得到的东西,都是放在活动中的。

(2)Service(服务):服务就比较低调了,你无法看到它,但它一直在后台默默的运行,即使用户退出了应用,服务仍然可以继续运行。

(3)BroadcastReeiver(广播接收者):允许你的应用接收来自各处的广播消息,比如电话、短信等,你的应用也可以向外发出广播消息。

(4)ContentProvider(内容提供者):为应用程序之间共享数据提供了可能,比如你想要读取电话薄中的联系人,就需要通过内容提供器来实现。

3.SQLite数据库

Android系统自带了轻量级、运行速度极快的嵌入式关系型数据库。它不仅支持标准的SQL语法,还可以通过Android封装好的API进行操作。

4.强大的多媒体

Android系统还提供了丰富的多媒体服务如音乐,拍照,闹铃等等,这些你都可以在在程序中,通过代码进行控制。

5.地理位置定位

Android手机都内置有GPS

6.JDK

JDK是java语言的软件开发包,它包含了java的运行环境、工具集合、基础类库等内容。

7.Android SDK

是谷歌提供的Android开发工具包,需要引入该工具包,来使用Android相关的API

8.AndroidManifest.xml中的

<activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

其中intent-filter里的两行代码非常重要,<action android:name="android.intent.action.MAIN"/> 和<category android:name="android.intent.category.LAUNCHER" />表示MainActivity是这个项目的主Activity,在手机上点击应用图标,首先启动的就是这个Activity。

9.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

AppCompatActivity是AndroidX中提供的一种向下兼容的Activity,可以使Activity在不同系统版本中的功能保持一致性。而Activity类是Android系统提供的一个基类,我们项目中所有自定义的Activity都必须继承它或者它的子类才能拥有Activity的特性(AppCompatActivity是Activity的子类)。然后可以看到MainActivity中有一个onCreate()方法,这个方法是一个Activity被创建时必定要执行的方法。

10.res文件目录

(1)drawable:用来存放图片的

(2)mipmap:用来存放图标的

(3)values:用来存放字符串、样式、颜色等配置

(4)layout:用来存放布局文件

“mipmap”开头的目录,里面包含不同分辨率的相同的文件,其实主要是为了让程序能够更好地兼容各种设备。drawable目录也是相同的道理,虽然Android Studio没有帮我们自动生成,但是我们应该自己创建drawable-hdpi、drawable-xhdpi、drawable-xxhdpi等目录。在制作程序的时候,最好能够给同一张图片提供几个不同分辨率的版本,分别放在这些目录下,然后程序运行的时候,会自动根据当前运行设备分辨率的高低选择加载哪个目录下的图片。当然这只是理想情况,更多的时候美工只会提供给我们一份图片,这时你把所有图片都放在drawable-xxhdpi目录下就好了,因为这是最主流的设备分辨率目录。

11.res/values/strings.xml文件

<resources>
    <string name="app_name">HelloWorld</string>
</resources>

可以看到,这里定义了一个应用程序名的字符串,我们有以下两种方式来引用它。

  • 在代码中通过R.string.app_name可以获得该字符串的引用。
  • 在XML中通过@string/app_name可以获得该字符串的引用。

基本的语法就是上面这两种方式,其中string部分是可以替换的,如果是引用的图片资源就可以替换成drawable,如果是引用的应用图标就可以替换成mipmap,如果是引用的布局文件就可以替换成layout,以此类推。

下面举一个简单的例子来帮助你理解,打开AndroidManifest.xml文件,找到如下代码:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ...
</application>

12.Project:build.gradle

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.1.1"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

两处repositories的闭包中都声明了google()jcenter()这两行配置,那么它们是什么意思呢?其实它们分别对应了一个代码仓库,google仓库中包含的主要是Google自家的扩展依赖库,而jcenter仓库中包含的大多是一些第三方的开源库。声明了这两行配置之后,我们就可以在项目中轻松引用任何google和jcenter仓库中的依赖库了。

dependencies闭包中使用classpath声明了一个Gradle插件。为什么要声明Gradle插件呢?因为Gradle并不是专门为构建Android项目而开发的,Java、C++等很多种项目也可以使用Gradle来构建,因此如果我们要想使用它来构建Android项目,则需要声明com.android.tools.build:gradle:3.5.2这个插件。其中,最后面的部分是插件的版本号,它通常和当前Android Studio的版本是对应的,比如我现在使用的是Android Studio 3.5.2版本,那么这里的插件版本号就应该是3.5.2。

13.Module:build.gradle

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 16
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

这个文件中的内容就要相对复杂一些了,下面我们一行行地进行分析。首先第一行应用了一个插件,一般有两种值可选:com.android.application表示这是一个应用程序模块,com.android.library表示这是一个库模块。二者最大的区别在于,应用程序模块是可以直接运行的,库模块只能作为代码库依附于别的应用程序模块来运行。

紧接着是一个大的android闭包,在这个闭包中我们可以配置项目构建的各种属性。其中,compileSdkVersion用于指定项目的编译版本,这里指表示使用Android系统的SDK编译。buildToolsVersion用于指定项目构建工具的版本。

然后我们看到,android闭包中又嵌套了一个defaultConfig闭包,defaultConfig闭包中可以对项目的更多细节进行配置。其中,applicationId是每一个应用的唯一标识符,绝对不能重复,默认会使用我们在创建项目时指定的包名,如果你想在后面对其进行修改,那么就是在这里修改的。minSdkVersion用于指定项目最低兼容的Android系统版本,这里指定成21表示最低兼容到Android 5.0系统。targetSdkVersion指定的值表示你在该目标版本上已经做过了充分的测试,系统将会为你的应用程序启用一些最新的功能和特性。比如Android 6.0系统中引入了运行时权限这个功能,如果你将targetSdkVersion指定成23或者更高,那么系统就会为你的程序启用运行时权限功能,而如果你将targetSdkVersion指定成22,那么就说明你的程序最高只在Android 5.1系统上做过充分的测试,Android 6.0系统中引入的新功能自然就不会启用了。接下来的两个属性都比较简单,versionCode用于指定项目的版本号,versionName用于指定项目的版本名。最后,testInstrumentationRunner用于在当前项目中启用JUnit测试,你可以为当前项目编写测试用例,以保证功能的正确性和稳定性。

分析完了defaultConfig闭包,接下来我们看一下buildTypes闭包。buildTypes闭包中用于指定生成安装文件的相关配置,通常只会有两个子闭包:一个是debug,一个是releasedebug闭包用于指定生成测试版安装文件的配置,release闭包用于指定生成正式版安装文件的配置。另外,debug闭包是可以忽略不写的,因此我们看到上面的代码中就只有一个release闭包。下面来看一下release闭包中的具体内容吧,minifyEnabled用于指定是否对项目的代码进行混淆,true表示混淆,false表示不混淆。proguardFiles用于指定混淆时使用的规则文件,这里指定了两个文件:第一个proguard-android-optimize.txt是在<Android SDK>/tools/proguard目录下的,里面是所有项目通用的混淆规则;第二个proguard-rules.pro是在当前项目的根目录下的,里面可以编写当前项目特有的混淆规则。需要注意的是,通过Android Studio直接运行项目生成的都是测试版安装文件,关于如何生成正式版安装文件,我们将会在第15章中学习。

这样整个android闭包中的内容就都分析完了,接下来还剩一个dependencies闭包。这个闭包的功能非常强大,它可以指定当前项目所有的依赖关系。通常Android Studio项目一共有3种依赖方式:本地依赖、库依赖和远程依赖。本地依赖可以对本地的jar包或目录添加依赖关系,库依赖可以对项目中的库模块添加依赖关系,远程依赖则可以对jcenter仓库上的开源项目添加依赖关系。

观察一下dependencies闭包中的配置,第一行的implementation fileTree就是一个本地依赖声明,它表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径中。而implementation则是远程依赖声明,androidx.appcompat:appcompat:1.1.0就是一个标准的远程依赖库格式,其中androidx.appcompat是域名部分,用于和其他公司的库做区分;appcompat是工程名部分,用于和同一个公司中不同的库工程做区分;1.1.0是版本号,用于和同一个库不同的版本做区分。加上这句声明后,Gradle在构建项目时会首先检查一下本地是否已经有这个库的缓存,如果没有的话则会自动联网下载,然后再添加到项目的构建路径中。至于库依赖声明这里没有用到,它的基本格式是implementation project后面加上要依赖的库的名称,比如有一个库模块的名字叫helper,那么添加这个库的依赖关系只需要加入implementation project(':helper')这句声明即可。关于这部分内容,我们将在本书的最后一章学习。另外剩下的testImplementationandroidTestImplementation都是用于声明测试用例库的,这个我们暂时用不到,先忽略它就可以了。

14.日志工具Log

  • Log.v()。用于打印那些最为琐碎的、意义最小的日志信息。对应级别verbose,是Android日志里面级别最低的一种。
  • Log.d()。用于打印一些调试信息,这些信息对你调试程序和分析问题应该是有帮助的。对应级别debug,比verbose高一级。
  • Log.i()。用于打印一些比较重要的数据,这些数据应该是你非常想看到的、可以帮你分析用户行为的数据。对应级别info,比debug高一级。
  • Log.w()。用于打印一些警告信息,提示程序在这个地方可能会有潜在的风险,最好去修复一下这些出现警告的地方。对应级别warn,比info高一级。
  • Log.e()。用于打印程序中的错误信息,比如程序进入了catch语句中。当有错误信息打印出来的时候,一般代表你的程序出现严重问题了,必须尽快修复。对应级别error,比warn高一级。
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d("MainActivity", "onCreate execute")
    }

}

Log.d()方法中传入了两个参数:第一个参数是tag,一般传入当前的类名就好,主要用于对打印信息进行过滤;第二个参数是msg,即想要打印的具体内容。

Logcat中可以很轻松地添加过滤器,你可以在图1.28中看到我们目前所有的过滤器。

{%}

目前只有3个过滤器,Show only selected application表示只显示当前选中程序的日志; Firebase是Google提供的一个开发者工具和基础架构平台,我们可以不用管它;No Filters相当于没有过滤器,会把所有的日志都显示出来。那可不可以自定义过滤器呢?当然可以,我们现在就来添加一个过滤器试试。

点击图1.28中的“Edit Filter Configuration”,会弹出一个过滤器配置界面。我们给过滤器起名叫data,并且让它对名为data的tag进行过滤,如图1.29所示

点击“OK”,你会发现多出了一个data过滤器。当选中这个过滤器的时候,刚才在onCreate()方法里打印的日志就不见了,这是因为data这个过滤器只会显示tag名称为data的日志。你可以尝试在onCreate()方法中把打印日志的语句改成Log.d("data", "onCreate execute"),然后再次运行程序,你就会在data过滤器下看到这行日志了。

Logcat中的日志级别

当前我们选中的级别是Verbose,也就是最低等级。这意味着不管我们使用哪一个方法打印日志,这条日志都一定会显示出来。而如果我们将级别选中为Debug,这时只有我们使用Debug及以上级别方法打印的日志才会显示出来,以此类推。你可以做一下实验,当你把Logcat中的级别选中为Info、Warn或者Error时,我们在onCreate()方法中打印的语句是不会显示的,因为我们打印日志时使用的是Log.d()方法。

日志级别控制的好处就是,你可以很快地找到你所关心的那些日志。

关键字输入框

我们可以在输入框里输入关键字的内容,这样只有符合关键字条件的日志才会显示出来,从而能够快速定位到任何你想查看的日志。另外,还有一点需要注意,关键字过滤是支持正则表达式的,有了这个特性,我们就可以构建出更加丰富的过滤条件。

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值