Basics of Android Development - Introduction to Android

This series of articles mainly introduces Android 10(Q).

Android system architecture

Android can be roughly divided into 4 layers of architecture:

  • Linux kernel layer
  • System runtime layer
  • Application framework layer
  • application layer

Linux kernel layer

The Android system is based on the Linux kernel. This layer provides underlying drivers for various hardware of Android devices, such as display drivers, audio drivers, camera drivers, Bluetooth drivers, Wi-Fi drivers, power management, etc.

System runtime layer

This layer provides the main feature support for the Android system through a layer of C/C++ library. For example, the SQLite library provides support for databases, OpenGL|ES provides support for 3D graphics, and the Webkit library provides support for browser kernels.

There is also an Android runtime library at this layer, which mainly provides some core libraries that allow developers to use the Java language to write Android applications. In addition, the Android runtime library also includes the Dalvik virtual machine (changed to the ART runtime environment after the 5.0 system), which enables each Android application to run in an independent process and has its own virtual machine example. Compared with the Java virtual machine, Dalvik and ART are specially customized for mobile devices. They are optimized for mobile phone memory and limited CPU performance.

Application framework layer

This layer mainly provides various APIs that may be used when building applications. Some core applications that come with Android are completed using these APIs. Developers can use these APIs to build their own applications.

application layer

All applications installed on the mobile phone belong to this layer, such as contacts, text messages and other programs that come with the system, or software downloaded from Google Play, self-developed programs, etc.

Features of Android application development

The Android system provides many convenient functions for developing excellent applications.

four major components

The four major components of the Android system are Activity, Service, BroadcastReceiver and ContentProvider.

  • Activity is the facade of all applications, as long as it can be seen in the application, it is placed in the Activity
  • Service runs in the background, even if the user exits the application, the Service can still continue to run
  • BroadcastReceiver allows applications to receive broadcast information from everywhere, such as phone calls, messages, etc., and applications can also send out broadcast information
  • ContentProvider provides the possibility to share data between applications. For example, if you want to read contacts in the system address book, you need to use ContentProvider to achieve

system controls

The Android system provides a rich system space for developers, so that users can easily write beautiful interfaces. At the same time, users can also customize their own controls.

SQLite database

The Android system also comes with this lightweight, extremely fast embedded relational database. It not only supports standard SQL syntax, but also can be operated through the API packaged by Android, making it very convenient to store and read data.

powerful multimedia

The Android system also provides a wealth of multimedia services, such as music, video, recording, photographing, etc. These functions can be controlled using codes in the program, thereby enriching the functions of the application.

Build a development environment

Early preparation

There are three main tools needed to develop Android programs:

JDK: JDK is a Java language software development kit, which includes the Java operating environment, tool collection, basic class library, etc.

Android SDK: Android SDK is an Android development toolkit provided by Google. When developing an Android program, you need to introduce the toolkit to use Android-related APIs

Android Studio: Previously, Android projects were developed using Eclipse, which can be used to develop Android programs by installing the ADT plug-in. Android Studio is an official IDE tool launched by Google, which is more convenient to use.

Environment build

Google has integrated the construction of the development environment, and downloading the latest development tools can complete the construction of the entire environment. The download site for the tool is:

Download Android Studio & App Tools - Android Developers

Android Studio Application Community-Android Application Download Center: Android Games/Android Software/Game Collection/Software Collection/Android Game Download/Android Software Download

HelloWorld

project creation

After the environment is set up, of course it is time to write HelloWorld.

First create a new project: 

As can be seen from the project creation above, you can choose to create mobile phones, tablets, wearable devices, TV and other types of projects, but here we only focus on mobile phones and tablets.

 The meanings of each field in project creation are:

  • Name: Indicates the project name, here is HelloWorld
  • Package name: Indicates the project package name. The Android system distinguishes different applications through the package name, so the package name must be unique. Android Studio will automatically generate a suitable package name according to the application name, or you can modify it yourself
  • Save location: project code storage location
  • Lanuage: Select the development language, Java and Kotlin are optional, here choose Kotlin (recommended by Google)
  • Minimum SDK: Set the minimum compatible version of the project

After that, the project was created successfully.

 Start the emulator

 Android Studio automatically generates a lot of things, and you don't need to write any code at this time, and the project can run. But before that, there needs to be a running carrier, which can be a real mobile phone or an Android emulator. Here first use the emulator to run the program.

The emulator can be created on the interface of Android Studio, select the device, download the corresponding image, and then start it. After that, the emulator will be like a real mobile phone, with a boot process, and the emulator after booting is as follows:

 run project

Now that the emulator has started, the project can be run on the emulator.

 The meaning of each icon is:

  • The hammer on the left: used to compile the project
  • app drop-down list: used to select which project to run, usually app is the current main project
  • Device drop-down list: used to select which device to run to
  • Triangle on the right: run the project
  • Box on the right: stop project

After the project runs, the display on the emulator is as follows:

 After that, you can also see an additional HelloWorld application in the launcher list:

project directory

In fact, no code was written during the whole process, but the project can still run because Android Studio has automatically generated it. Here is a look at the entire project code structure:

Here is a look at the meaning of the content displayed above.

 .gradle和.idle

These two directories are placed in some files automatically generated by Android Studio, no need to care about, no need to manually edit.

app

The code, resources and other content in the project are placed in this directory.

 build

This directory mainly contains some files that are automatically generated during compilation, and you don't need to care about it.

gradle

This directory contains the configuration file of the gradle wrapper. The way of using the gradle wrapper does not need to download the gradle in advance, but will automatically decide whether to download the gradle online according to the local cache situation. By default, Android Studio starts the gradle wrapper mode. If you need to change to offline mode, you can make configuration changes in Settings.

.gitignore

This file is used to exclude specified directories or files from version control.

build.gradle

This is the global gradle build script for the project, and usually the contents of this file do not need to be changed.

gradle.properties

This file is a global gradle configuration file, and the properties configured here will affect all gradle compilation scripts in the project.

gradles and gradlew.bat

These two files are used to execute the gradle command in the command line interface, where gradlew is used in the Linux or Mac system, and gradlew.bat is used in the Windows system.

local.properties

This file is used to specify the path of the Android SDK in the machine, and usually the content is automatically generated and does not need to be changed. If the location of the Android SDK in the machine has changed, just change the path in the file to the new location.

settings.gradle

This file is used to specify all imported modules in the project. Since there is only one app module in the HelloWorld project, only the app module is introduced in this file. Normally, the import of modules is done automatically.

Most of the files and directories mentioned above are automatically generated and do not need to be changed. The content in the app directory is the focus of the project. Its structure is:

 Here is a look at the meaning of the content displayed above.

 build

This directory is similar to the previous build directory, and also contains some files that are automatically generated during compilation, and its content is more complicated, but you don't need to worry about it.

libs

If the project contains third-party jar packages, these jar packages need to be placed in the libs directory, and the jar packages placed in this directory will be automatically added to the project's build path.

androidTest

This is used to write Android Test test cases, and some automated tests can be performed on the project.

java

This directory is where all the Java code is placed, and also contains Kotlin code. In this directory, the system has actively generated a MainActivity file.

res

The contents of this directory include all the images, layouts, strings and other resources used in the project. This directory also contains many subdirectories. Pictures are placed in the drawable directory, layouts are placed in the layout directory, and strings are placed in the values ​​directory.

AndroidManifest.xml

This is the configuration file of the entire project. All the four major components defined in the program need to be registered in this file. In addition, permission statements can be added to the application in this file.

test

It is used here to write Unit Test test cases, which is another form of automated testing for projects.

.gitignore

This file is used to exclude the specified directory or file in the app module from version control, and its role is the same as the outer layer. gitignore

The files are similar.

build.gradle

Here is the gradle build script of the app module, which specifies many project build-related configurations.

proguard-rules.pro

This file is used to specify the obfuscation rules of the project code. When the code development is completed, it is packaged into an installation package file. If you do not want the code to be cracked by others, the code is usually obfuscated.

Project operation rules

Here's a look at how the HelloWorld project works. The first is the AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloworld">

    <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/Theme.HelloWorld">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

In the above file, the code segment in the activity node indicates the registration of MainActivity, and the Activity that is not registered in the AndroidManifest.xml file cannot be used. Among them, the two lines of code in the intent-filter are more important, indicating that MainActivity is the main Activity of the project. When you click the application icon on the mobile phone, the Activity will be started first.

And MainActivity is actually the interface that appeared after starting the project before, and its code is:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

As can be seen from the above, MainActivity inherits from AppCompatActivity. AppCompatActivity is a backward compatible Activity provided in AndroidX, which can keep the functions of Activity in different system versions consistent.

The Activity class is a base class provided by the Android system. All custom Activities in the project must inherit from it or its subclasses to have the characteristics of Activity (AppCompatActivity is a subclass of Activity).

At the same time, there is an onCreate() method in the above code, which is a method that must be executed when an Activity is created. There are only two lines of code in it, and there is no "Hello World!" word. So where does the display come from?

In fact, Android program design pays attention to the separation of logic and view, so the more general approach is to write the interface in the layout file, and then introduce it in the Activity. You can see that the second line of the onCreate() method calls the setContentView() method, which introduces an activity_main layout to the current Activity:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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" />

</androidx.constraintlayout.widget.ConstraintLayout>

As mentioned earlier, pictures, layouts, strings and other content are placed in the res directory, and the above files are also located in the res/layout directory, and the content in the TextView above is "Hello World!".

resources in the project

 Since all resources are in the res directory, take a look at its directory structure:

Of the content shown above:

  • drawable: All directories starting with drawable are used to store pictures
  • mipmap: All directories starting with mipmap are used to store application icons
  • values: All directories starting with values ​​are used to store strings, styles, colors and other configurations
  • layout: All directories starting with layout are used to store layout files

 The reason why there are many directories starting with mipmap is to make the program better compatible with various devices. Other directories have similar functions. Although Android Studio does not automatically generate them, users can also manually create drawable-hdpi, drawable- xhdpi, drawable-xxhdpi and other directories. During application development, it is best to prepare versions with different resolutions for the same picture and place them in the corresponding directory. When the program is running, it will automatically select which directory to load the picture according to the resolution of the current running device. It’s just that this is the best situation. Most of the time, there will only be one picture. At this time, just put all the pictures in the drawable-xxhdpi directory, because this is the most mainstream device resolution directory.

For example res/values/strings.xml file:

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

app_name is defined in the above file, which corresponds to the string of the application name, which can be applied in two ways:

  • Reference the string in code via R.string.app_name
  • Reference the string in XML via @string/app_name

The above mentioned is the basic syntax, where the string part can be replaced by drawable to refer to image resources, mipmap to refer to application icons, and layout to refer to layout files.

For example, the icon, lable, and roundIcon in the AndroidManifest.xml file mentioned above all use the above reference form:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloworld">

    <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/Theme.HelloWorld">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

build.gradle file

Android Studio uses Gradle for project construction, which is based on Groovy's domain-specific language (DSL) for project setup, which is different from XML-based cumbersome configuration.

In the previous directory structure, it is mentioned that there are two build.gradle files, one in the outermost project directory and the other in the app directory, both of which play an important role in project construction. Here's a look at these two files, the first is the outermost build.gradle file:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.0"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20"

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

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

The above code is automatically generated:

  • repositories declares two lines of configuration, google() and mavenCentral(), which correspond to a code warehouse respectively. After declaring these two lines of configuration, you can use the relevant dependent libraries in the project
  • dependencies declare Gradle and Kotlin plug-ins using classpath, because Gradle plug-ins are not specially developed for creating Android projects, and other projects such as Java/C++ can also be built using Gradle, so they need to be declared. The last part of the statement indicates the version number of the plug-in, which generally corresponds to the current version of Android Studio. The Kotlin plugin indicates that the current project is developed using Kotlin.

The build.gradle file under the inner app is:

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdk 33

    defaultConfig {
        applicationId "com.example.helloworld"
        minSdk 21
        targetSdk 33
        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
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {

    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    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'
}

In the above content:

  • plugins: describes the related plugins
    • com.android.application: indicates that this is an application module (com.android.library indicates that this is a library module, the difference between the two is that the application module can be run directly, and the library module can only be attached to other applications as a code library module to run)
    • kotlin-android: Indicates that the plugin is applied
  • android: configure various properties of project construction
    • compileSdk: used to specify the compiled version of the project
    • defaultConfig: You can configure the relevant details of the project
      • applicationId: is the unique identifier of each application. By default, the package name specified when the project is created is used. If you need to change the package name later, you can modify it here
      • minSdk: Specifies the minimum compatible Android system version of the project
      • targetSdk: Indicates that the target version has been fully tested, and the system will enable some of the latest functions and features for the application
      • versionCode: the version number used to specify the project
      • versionName: the version name used to specify the project
      • testInstrumentationRunner: Used to enable JUnit testing in the current project, you can write test cases for the current project to ensure the correctness and stability of the function
    • buildTypes: It is used to specify the relevant configuration for generating installation files, usually there are only two subitems, release and debug
      • release: Used to specify the configuration for generating the official version of the installation file
        • minifyEnabled: used to specify whether to confuse the code of the project, true means confuse, false means not confuse
        • proguardFiles: It is used to specify the rule file used for confusion. Two files are specified here. proguard-android-optimize.txt is in the Android SDK/tools/prouard directory, which contains common confusion rules for all projects, proguard- rules.pro is in the root directory of the current project, where you can write the confusion rules unique to the current project
      • debug: It is used to specify the configuration for generating the test version installation file, which can be ignored. However, running the project through Android Studio generates beta installation files.
    • compileOptions: Specify compile option configuration
      • sourceCompatibility: Specify the jdk version for compiling and compiling the .java file

      • targetCompatibility: Ensure that the class file is compatible with the version specified by targetCompatibility, or a newer Java virtual machine

    • kotlinOptions: Specify Kotlin related options

      • jvmTarget: Specify kotlin-related compilation configuration

  • dependencies: Specify all the dependencies of the current project, usually there may be three dependencies in the project: local dependencies, library dependencies and remote dependencies. Local dependencies can add dependencies to local jar packages or directories, library dependencies can add dependencies to library modules in the project, and remote dependencies can add dependencies to open source projects on the aforementioned warehouse

    • implementation fileTree(): Indicates local dependency declaration, not used here

    • implementation: Indicates remote dependencies, such as androidx.appcompat:appcompat:1.2.0 is a standard remote dependency library format, androidx.appcompat indicates the domain name part, which is used to distinguish it from other companies' libraries, and appcompat indicates the project name part, which is used for To distinguish it from different library projects in the same company, 1.2.0 represents the version number, which is used to distinguish it from different versions of the same library. After adding this statement, Gradle will first check whether there is a local cache of the library when the project is built, and if not, it will automatically download it online, and then add it to the project's build path.

    • implementation project(): Indicates library dependency declaration, not used here

    • testImplementation: used to declare the test case library

    • androidTestImplementation: used to declare the test case library

log tool

log tools

The log tool class in Android is Log(Android.util.log), which provides 5 methods to print logs:

  • Log.v(): corresponds to verbose level, the lowest level, used to print trivial and least important log information
  • Log.d(): corresponds to the level of debug, the second lowest level, used to print some debugging information for program debugging and problem analysis
  • Log.i(): Corresponds to level info, medium level, used to print some important data to help analyze user behavior
  • Log.w(): corresponds to the level of warn, the second highest level, used to print some warning information to remind users that there may be potential risks
  • Log.e(): Corresponds to level error, the highest level, used to print error information, such as the content in the catch statement

In order to verify the printed content, the previous MainActivity can be modified to:

package com.example.helloworld

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

There are two parameters in Log.d():

  • tag: Generally, the current class name is passed in, which is mainly used to filter the print information
  • msg: what you actually want to print

After running the project, you can see the print information in Logcat:

2022-09-04 20:05:49.382 11550-11550/com.example.helloworld D/MainActivity: Hello World

The printed content includes date, time, process number, package name, log level, class name, and print information, which can be said to be very detailed.

Log and println()

In fact, from the above content, the function of the Log class is to print information, and its function is similar to that of println. Here, modify the above code and compare:

package com.example.helloworld

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d("MainActivity","Hello World")
        println("MainActivity" + " " + "Hello World")
    }
}

The relevant print results are:

2022-09-04 20:17:06.043 11854-11854/com.example.helloworld D/MainActivity: Hello World
2022-09-04 20:17:06.043 11854-11854/com.example.helloworld I/System.out: MainActivity Hello World

From the above printing results, although the MainActivity class can be located, its form is not as convenient as using the Log class. At the same time, there are two advantages of using the Log class. One is that the importance of the printed content can be graded, and the other is that the printed content can be filtered during debugging.

 The content shown in the above figure is:

  • Show only selected application: Indicates that only the logs of the currently selected program are displayed
  • Firebase: is a developer tool and infrastructure platform provided by Google, which can be ignored
  • No Filters: equivalent to no filter
  • Edit Filter Configuration: You can configure the filter

For example, add the following filter:

 In this way, all logs tagged as MainActivity can be filtered in Logcat.

And Logcat can also perform log level control:

The content shown in the above figure is:

  • Verbose: show all class logs
  • Debug: Display logs of Debug level and above
  • Info: Displays logs of Info level and above
  • Warn: Display logs of Warn level and above
  • Error: Display logs of Error level and above
  • Assert: related to Assert

At the same time, Logcat also supports keyword search, which is similar to the content search in a text editor, but the keyword search in Logcat supports regular expressions.

Guess you like

Origin blog.csdn.net/SAKURASANN/article/details/126685824
Recommended