Android是由Google主导开发的一个基于Linux内核的开源操作系统,专为移动设备设计,如智能手机、平板电脑和智能穿戴设备。它提供了一个用户友好的界面,支持多种应用程序,用户可以通过Google Play商店下载和安装应用。Android的架构包括应用层、应用框架、库和Linux内核,允许开发者使用Java、Kotlin等编程语言创建应用。由于其开源特性,Android吸引了大量开发者和设备制造商,形成了一个庞大的生态系统,支持多种硬件平台和设备类型,使其成为全球最流行的移动操作系统之一。
本篇是打打基础,因为想尝试编写Android Hook,所以先补充基本的Android开发知识。
环境为windows10.
基础环境配置
安装Android Studio
先安装Jetbrains Toolbox,然后使用Toolbox安装Android Studio,非常省心,安装完成后点点点全部同意即可,新版本没有很复杂的配置选项。在Toolbox登录Jetbrains账户,会直接同步登录到对应的IDE,也不需要额外再登遍账户了。
安装JDK
windows的包管理工具已经相对成熟了,很好用。所以摒弃之前手动配置java环境的方法,直接使用scoop解决这一切,包括java的安装和java版本管理。
直接看下面几个指令即可,用过其他包管理工具的话直接就明白了。
1 2 3 4 5 6 7 8 9 10
| # 添加Buceket scoop add bucket java # 搜索openjdk scoop search openjdk # 安装jdk8 scoop install openjdk8-redhat # 安装jdk17 scoop install openjdk17 # 切换环境为jdk8 scoop reset openjdk8-redhat
|
使用Android Studio创建Demo
创建项目
New Project,选择空白项目,然后点点点Next+Finish即可。中间有个配置页,默认使用Kotlin语言,编写简单demo的话可以什么都不改,我Project Name更改为了Demo。
Finish之后弹出工作区页面完成空白项目创建。
创建虚拟机并运行demo
在介绍项目结构之前,先创建一个开发测试用的Android虚拟机,创建位置为菜单栏-Tools-Device Manager,点击后右侧开启设备管理页面,选择Medium Phone API 35创建虚拟机,稍等片刻即可。
Android Studio的虚拟机自定义程度比较高,也可以选择使用WIFI无线连接设备,这里还不急,一会儿打包应用到手机上的时候再搞,开发阶段可以先用用虚拟机。
事不宜迟,点击菜单栏-Run-Run ‘app’,可以直接将当前项目发布到手机上查看效果。
本地构建打包为apk再发布到自己手机上的流程与这个差别较大,后面再说。
empty activity项目结构介绍
.gradle
文件夹包含Gradle构建工具的相关文件,Gradle是Android项目的构建系统,负责依赖管理和构建过程。
main
:这是主要的代码和资源目录。它包含:
java
:存放Java或Kotlin源代码的目录,通常会有一个与应用包名相对应的子目录。在空项目中,默认会有一个MainActivity
类,这是应用的入口点。
res
:存放应用资源的目录,包括图像、布局文件、字符串等。常见的子目录有:
drawable
:存放图像资源。
mipmap
:存放应用图标的不同分辨率版本。
values
:存放字符串、颜色、样式等资源的XML文件。
xml
:可以存放其他XML配置文件。
test
:用于存放本地单元测试代码,这些测试通常在JVM上运行。
AndroidManifest.xml
是Android应用的核心配置文件,类似于一个注册表,定义了应用的基本信息和组件。这个文件包含了应用的包名、版本信息、权限声明、应用组件(如活动、服务、广播接收器和内容提供者)的注册,以及其他重要的配置信息。
此处提到了一个重要概念,即活动(Activity)。
在AndroidManifest.xml
中,每个活动都需要在此注册,以便系统能够识别和管理它们。注册活动时,开发者可以指定活动的名称、启动模式、主题、图标等属性。此外,开发者还可以声明应用所需的权限,例如访问网络、读取联系人等。
在Android开发中,活动是用户界面的一个重要组成部分,代表了应用中的一个单一屏幕。每个活动都可以包含用户界面元素,如按钮、文本框和图像等,用户与这些元素进行交互。活动的生命周期由系统管理,开发者可以通过重写生命周期方法(如onCreate
、onStart
、onResume
、onPause
、onStop
和onDestroy
)来处理活动的创建、显示、隐藏和销毁等状态。
活动之间可以通过意图(Intent)进行交互,意图是一种消息机制,用于启动新的活动或与其他应用组件进行通信。通过这种方式,Android应用可以实现多屏幕的用户体验,允许用户在不同的活动之间导航。
继续试探
编写app样式
Android Studio初始化的空项目中应该是没有控制页面样式的文件,简单搜了搜是main/res/layout/activity_main.xml
,手动创建,点进去后发现Android Studio提供了拖拽式可视化的编写前端页面的工具,感觉非常强大。
欸这个时候就要问了,不想用这种拖拽式的工具,想用代码写样式怎么办?点击ctrl+b
即可直接切换到code页面。在编辑区的右上角有三个按钮,分别代表code、spilit和design模式,按自己需求切换即可。
layout/activity_main.xml
文件是Android应用中用于定义用户界面的布局文件。它描述了在特定活动中显示的视图和布局结构。通过XML格式,开发者可以直观地定义界面的各个元素及其属性。我感觉很类似传统前端开发中的HTML。
这里留个示范,在布局容器里添加了文本试图和按钮,并通过layout_gravity
属性实现居中布局:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp">
<TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, World!" android:textSize="24sp" android:layout_gravity="center"/>
<Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click Me" android:layout_gravity="center"/> </LinearLayout>
|
MainActivity主活动
MainActivity
通常是Android应用的主活动,作为应用的入口点。它在应用启动时首先被创建,负责初始化应用的界面和逻辑。MainActivity
的地位非常重要,因为它通常是用户首次与应用交互的地方,承载着应用的主要功能和内容。
而我们创建的安卓应用的入口就是main/java/xxx/MainActivity.kt
,这里列出代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package com.example.demo import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.example.demo.ui.theme.DemoTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { DemoTheme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> Greeting( name = "Android", modifier = Modifier.padding(innerPadding) ) } } } } } @Composable fun Greeting(name: String, modifier: Modifier = Modifier) { Text( text = "Hello $name!", modifier = modifier ) } @Preview(showBackground = true) @Composable fun GreetingPreview() { DemoTheme { Greeting("Android") } }
|
MainActivity.kt
是Android应用的主要活动文件,负责定义应用的行为和用户界面。在这个文件中,使用了Jetpack Compose,这是Android的现代UI工具包,允许开发者使用Kotlin代码构建用户界面,而不是传统的XML布局。
在MainActivity
类中,onCreate
方法是活动的入口点,主要作用是设置活动的内容。在这里,调用了setContent
方法来定义用户界面。通过DemoTheme
,应用了主题样式。Scaffold
是一个布局组件,提供了基本的应用结构,如顶部应用栏、底部导航等。innerPadding
用于处理内容的内边距,以避免与系统UI重叠。
像上个小标题中我列出的文本试图+按钮的代码,可以使用如下kotlin实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.example.demo
import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.* import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.demo.ui.theme.DemoTheme
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DemoTheme { MainScreen() } } } }
@Composable fun MainScreen() { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( text = "Hello, World!", fontSize = 24.sp )
Button(onClick = { }) { Text(text = "Click Me") } } }
|
看起来也差不多。但现在好像都更推荐使用Jetpack Compose。
主要原因是Hetpack Compose支持响应式编程,能够自动根据数据变化更新界面,简化了手动更新UI的过程。这种方式提高了开发效率,特别是在处理动态内容时,开发者可以更专注于业务逻辑而不是视图的状态管理。此外,Compose的可组合性使得开发者能够创建可重用的组件,增强了代码的可维护性和可读性。通过组合不同的UI元素,开发者可以快速构建复杂的界面,同时保持代码的清晰和结构化。
虽然我的java依托,但搜搜语法也能直接上手试试。我编写了一个入门常见案例:点击后+1的按钮。常用前端框架都喜欢把这个小组件用在初始项目中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| package com.example.demo
import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.* import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.demo.ui.theme.DemoTheme
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DemoTheme { MainScreen() } } } }
@Composable fun MainScreen() { var count by remember { mutableStateOf(0) }
Column( modifier = Modifier .fillMaxSize() .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( text = count.toString(), fontSize = 48.sp )
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { count++ }) { Text(text = "Click Me") }
Spacer(modifier = Modifier.weight(1f))
Text( text = "Hello Kinoko", modifier = Modifier.align(Alignment.CenterHorizontally) ) } }
|
打包为apk并安装在真实设备
有两种方式,命令行打包和IDE打包,先尝试后者。
Android Studio菜单栏Build-Build App Bundle(s)/APK(s)-Build APK(s),稍等片刻就会自动打包,打包可以获得debug版本的apk安装包,路径为app/build/outputs/apk/debug/app-debug.apk
,usb数据线连接手机后使用adb安装即可。
1
| adb -s xxx install C:\Users\xxx\AndroidStudioProjects\Demo\app\build\outputs\apk\debug\app-debug.apk
|
我这里因为同时连接了显示器和手机,所以用-s
指定设备
经检验,debug版本的app在手机上也可以正常安装使用。