Android学习19 -- 手搓App
1 前言
之前工作中,很多时候要搞一个简单的app去验证底层功能,Android studio又过于重型,之前用gradle,被版本匹配和下载外网包折腾的堪称噩梦。所以搞app都只有找应用的同事帮忙。一直想知道一些简单的app怎么能手搓一下,简单快速的搞出来。趁着现在有时间,终于体验了一把。
我的环境是windows10,终端设备没有用虚拟机,用了一个安卓平板,荣耀平板5。

2 代码结构
代码架构如下:

其中要自己写的就是两个文件,MainActivity.java和AndroidManifest.xml。如下:

MainActivity.java
package com.example.simpleapp;import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);TextView tv = new TextView(this);tv.setText("Hello, Android!");setContentView(tv);}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.simpleapp"android:versionCode="1"android:versionName="1.0"><application android:label="SimpleApp"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>
</manifest>
关于这个文件,简单的介绍如下:
`AndroidManifest.xml` 是 Android 应用开发中的核心配置文件,为系统和开发者提供应用的关键信息,以下是简要介绍:
1. **基本信息声明** - 定义应用包名,作为应用唯一标识。 - 包含版本号,`versionCode` 供系统识别版本新旧,`versionName` 面向用户展示。
2. **组件声明** - **Activity**:代表应用界面,可设置为启动界面。 - **Service**:用于后台长时间运行任务。 - **Broadcast Receiver**:接收系统或应用广播消息。 - **Content Provider**:实现不同应用间的数据共享。
3. **权限声明**:列出应用正常运行所需权限,部分危险权限需运行时动态请求。
4. **其他配置** - 配置应用图标、名称、主题,决定应用外观展示。 - 声明应用对硬件特性和 Android 系统版本的要求。
3 环境配置
之后就是要配置一大堆组件了。

其中platform-tools,cmdline-tools,jdk-23.0.1都要自己下载,前面两个可以去安卓官网下,jdk去甲骨文网站下。Adnroid_SDK可以用过cmdline-tools里面的sdkmanager.bat自动下载。
platform-tools里面主要是adb,fastboot这些工具。
cmdline-tools主要就是开发中的工具,是一堆bat文件。sdkmanager管理SDK的,avdmanager管理虚拟机的,lint是代码静态检查,apkanalyzer是APK文件分析。
撸apk,主要要用sdkmanager。使用list命令可以看现在可以下载哪些。
sdkmanager --list --sdk_root=D:\Tools\Adnroid_SDK
先安装build tool
sdkmanager --install "build-tools;35.0.0"
我的目标设备是荣耀平板5,很老的一个7寸平板。看了一下设备的OS是Android9, Android9对应的SDK版本是28,安装的命令是:
sdkmanager --install "platforms;android-28" --sdk_root=D:\Tools\Adnroid_SDK
之后就是设置环境变量,主要是ANDROID_HOME,JAVA_HOME,然后jdk的bin,build-tools,platform-tools这几个都要加到PATH之中。
4 操作步骤
然后就可以开撸。
4.1 编译java文件
首先是编译java文件
javac -d bin -classpath "D:\Tools\Adnroid_SDK\platforms\android-28\android.jar" src/com/example/simpleapp/MainActivity.java
之后会在bin下面生成com/example/simpleapp/MainActivity.class。
4.2 生成dex
然后生成classes.dex,输入就是上一步的class文件。
d8 --output=out/ bin/com/example/simpleapp/MainActivity.class
之后会在out下生成classes.dex。看了一下介绍,安卓的虚拟机的字节码是DEX bytecode,和一般的虚拟机还有不同,所以这里要处理下。
d8: This tool is the DEX compiler. It takes Java bytecode (.class files) and converts it into DEX bytecode (.dex files), which is what the Android Runtime (ART) executes.
4.3 生成apk
之后使用aapt生成apk,这一步的输入参数就是那个AndroidManifest.xml,还有Android9的运行库jar。
aapt package -f -m -F out/app.unsigned.apk -M AndroidManifest.xml -I D:\Tools\Adnroid_SDK\platforms\android-28\android.jar
此时会生成一个基础的app.unsigned.apk。
然后将之前的class.dex加到apk之中。这里貌似直接用zip拖进去也行。。
aapt add out/app.unsigned.apk out/classes.dex
aapt (Android Asset Packaging Tool): This tool is used to package resources (like layouts, images, and strings) into a compiled format that Android can understand. It also handles the creation of the resources.arsc file and the AndroidManifest.xml processing.
apk本质其实就是一个zip文件,可以直接用winrar打开,此时内容如下:

有的介绍说要对齐一下。但是我没对齐也可以的。
zipalign -v 4 build/apk/app-debug-unaligned.apk build/apk/app-debug.apk
4.4 签名
最后就是签名,这一步感觉倒是挺无聊的。但是不签名,确实无法安装:

签名的步骤如下:
keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key
apksigner sign --ks my-release-key.jks --out out/app.signed.apk out/app.unsigned.apk
签完名,apk里面会多一个META-INF文件夹。

最后的文件大小大概是8k,不是我吹牛,这么小的安卓app绝对堪称罕见中的罕见了。。

5 运行
之后就是推送APK。当然,之前要进入开发者模式,然后把usb调试打开。
adb install out/app.signed.apk
然后就提示是否安装:

(这个图是另一个实验的app)
之后会提示说有一些东西太老之类的,但是可以看到期待的画面了。

6 参考和其他
最后,谷歌官方是很不推荐这种做法,推荐用Android Studio和Gradle,理由如下:
Important Considerations
Complexity: This process is very manual and error-prone.
Maintenance: Maintaining a project built this way is extremely difficult.
Features: You're missing out on all the features and optimizations that Gradle provides.
Dependencies: Managing dependencies manually would be a nightmare.
Android Studio: Android Studio and Gradle are designed to make Android development much easier.
Android SDK: You need to have the Android SDK installed and configured correctly.
Environment Variables: You need to set the ANDROID_HOME environment variable.
Missing files: You need to create the res directory and the strings.xml file.
Conclusion
While you can technically create a very simple Android 9 APK using aapt and d8 directly, it's strongly discouraged for anything beyond experimentation or very specific edge cases. Gradle is the standard build system for Android, and it provides a much more robust, efficient, and maintainable way to develop Android apps. I highly recommend using Gradle unless you have a very compelling reason not to.
之前倒是写过一个Gardle的文,但是很简单,也没有涉及到apk这一层。可以看看:Android学习18 -- Gradle_resourcehashescache.bin-CSDN博客
参考:
ChatGPT和Gemini
相关文章:
Android学习19 -- 手搓App
1 前言 之前工作中,很多时候要搞一个简单的app去验证底层功能,Android studio又过于重型,之前用gradle,被版本匹配和下载外网包折腾的堪称噩梦。所以搞app都只有找应用的同事帮忙。一直想知道一些简单的app怎么能手搓一下&#x…...
人工智能导论-第3章-知识点与学习笔记
参考教材3.2节的内容,介绍什么是自然演绎推理;解释“肯定后件”与“否定前件”两类错误的演绎推理是什么意义,给出具体例子加以阐述。参考教材3.3节的内容,介绍什么是文字(literal);介绍什么是子…...
wxWidgets中wxGrid表格使用示例,去掉竖向表头
这里设置表格各种属性如下: // 去掉竖向表头 grid->SetRowLabelSize(0); // 设置表格背景色为黑色 grid->SetDefaultCellBackgroundColour(*wxBLACK); // 设置单元格内容居中,字体为16号,白色 wxFont cellFont(16, wxFONTFAMILY_DEFAULT, wx…...
全面掌握市场信息:xtquant库在证券品种数据获取中的应用
全面掌握市场信息:xtquant库在证券品种数据获取中的应用 开篇点题:技术背景和应用场景 在量化交易领域,快速准确地获取市场基础信息是至关重要的。xtquant库提供了一种便捷的途径来获取各类证券品种的数据,包括股票、指数、基金等…...
DeepSeek 的含金量还在上升
大家好啊,我是董董灿。 最近 DeepSeek 越来越火了。 网上有很多针对 DeepSeek 的推理测评,除此之外,也有很多人从技术的角度来探讨 DeepSeek 带给行业的影响。 比如今天就看到了一篇文章,探讨 DeepSeek 在使用 GPU 进行模型训练…...
day38|leetcode 322零钱兑换,279.完全平方数,139.单词拆分
322. 零钱兑换 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是…...
【Linux系统】信号:信号保存 / 信号处理、内核态 / 用户态、操作系统运行原理(中断)
理解Linux系统内进程信号的整个流程可分为: 信号产生 信号保存 信号处理 上篇文章重点讲解了 信号的产生,本文会讲解信号的保存和信号处理相关的概念和操作: 两种信号默认处理 1、信号处理之忽略 ::signal(2, SIG_IGN); // ignore: 忽略#…...
Go语言指针的解引用和间接引用
在 Go 语言中,"解引用"和"间接引用"是与指针相关的概念。 解引用 (Dereferencing): 解引用是指通过指针访问它所指向的变量的值。在 Go 中,使用星号(*)来解引用一个指针。 例如: v…...
【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.6 广播机制核心算法:维度扩展的数学建模
2.6 广播机制核心算法:维度扩展的数学建模 目录/提纲 #mermaid-svg-IfELXmhcsdH1tW69 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-IfELXmhcsdH1tW69 .error-icon{fill:#552222;}#mermaid-svg-IfELXm…...
硬件产品经理:需求引力模型(DGM)
目录 1、DGM 模型简介 2、理论核心:打破传统线性逻辑 3、三大定律 第一定律:暗物质需求法则 第二定律:引力井效应 第三定律:熵减增长律 4、落地工具包 工具1:需求密度热力图 工具3:摩擦力歼灭清单…...
基于“蘑菇书”的强化学习知识点(四):贝尔曼方程
贝尔曼方程 摘要贝尔曼方程(Bellman Equation)详解1. 核心思想2. 基本概念3. 贝尔曼方程的两种形式(1) 状态值函数的贝尔曼方程(2) 动作值函数的贝尔曼方程 4. 贝尔曼最优方程(Bellman Optimality Equation)5. 示例:网…...
Guided Decoding (借助FSM,有限状态自动机)
VLLM对结构化输出的支持: vllm/docs/source/features/structured_outputs.md at main vllm-project/vllm GitHub VLLM对tool call的支持: vllm/docs/source/features/tool_calling.md at main vllm-project/vllm GitHub 以上指定输出格式…...
ComfyUI工作流 图像反推生成人像手办人像参考(SDXL版)
文章目录 图像反推生成人像手办人像参考SD模型Node节点工作流程效果展示开发与应用图像反推生成人像手办人像参考 本工作流旨在通过利用 Stable Diffusion XL(SDXL)模型和相关辅助节点,实现高效的人像参考生成和手办设计。用户可通过加载定制的模型、LORA 调整和控制节点对…...
C++11新特性之long long超长整形
1.介绍 long long 超长整形是C11标准新添加的,用于表示更大范围整数的类型。 2.用法 占用空间:至少64位(8个字节)。 对于有符号long long 整形,后缀用“LL”或“II”标识。例如,“10LL”就表示有符号超长整…...
【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.5 高级索引应用:图像处理中的区域提取
2.5 高级索引应用:图像处理中的区域提取 目录/提纲 #mermaid-svg-BI09xc20YqcpUam7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-BI09xc20YqcpUam7 .error-icon{fill:#552222;}#mermaid-svg-BI09xc20…...
响应式编程_01基本概念:前世今生
文章目录 引言响应式编程的技术优势全栈式响应式编程从传统开发模式到异步执行技术Web 请求与 I/O 模型异步调用的实现技术回调Future机制 响应式编程实现方法观察者模式发布-订阅模式数据流与响应式 响应式宣言和响应式系统 引言 大流量、高并发的访问请求的项目,…...
系统URL整合系列视频一(需求方案)
视频 系统URL整合系列视频一(需求方案) 视频介绍 (全国)某大型分布式系统Web资源URL整合需求实现方案讲解。当今社会各行各业对软件系统的web资源访问权限控制越来越严格,控制粒度也越来越细。安全级别提高的同时也增…...
C#中的委托(Delegate)
什么是委托? 首先,我们要知道C#是一种强类型的编程语言,强类型的编程语言的特性,是所有的东西都是特定的类型 委托是一种存储函数的引用类型,就像我们定义的一个 string str 一样,这个 str 变量就是 string 类型. 因为C#中没有函数类型,但是可以定义一个委托类型,把这个函数…...
Ubuntu 24.04 安装 Poetry:Python 依赖管理的终极指南
Ubuntu 24.04 安装 Poetry:Python 依赖管理的终极指南 1. 更新系统包列表2. 安装 Poetry方法 1:使用官方安装脚本方法 2:使用 Pipx 安装 3. 配置环境变量4. 验证安装5. 配置 Poetry(可选)设置虚拟环境位置配置镜像源 6…...
爱普生L3153打印机无线连接配置流程
家里使用的是移动宽带中兴路由器,有WPS功能,进入192.168.1.1管理员页面,用户名user,密码在路由器背面(可以登录后修改密码)。在网络-WLAN网络配置-WPS中,点击push button,激活路由器…...
LabVIEW如何有效地进行数据采集?
数据采集(DAQ)是许多工程项目中的核心环节,无论是测试、监控还是控制系统,准确、高效的数据采集都是至关重要的。LabVIEW作为一个图形化编程环境,提供了丰富的功能来实现数据采集,确保数据的实时性与可靠性…...
D. Vessels
题目链接:Problem - 371D - Codeforces 题目大意:有n层容器用来装水, 当一层的水满了,就会向下溢出,进入下一层,最后一层的溢出将会在地上。现有两种操作 1.在p层的容器里加入x升水。 2.查询p层的水量为…...
vue声明周期及其作用
vue声明周期及其作用 1. 生命周期总览 2. beforeCreate 我们在new Vue()时,初始化一个Vue空的实例对象,此时对象身上只有默认的声明周期函数和事件,此时data,methods都未被初始化 3. created 此时,已经完成数据观测࿰…...
安全策略实验
安全策略实验 1.拓扑图 2.需求分析 需求: 1.VLAN 2属于办公区,VLAN 3属于生产区 2.办公区PC在工作日时间(周一至周五,早8到晚6)可以正常访问OA server其他时间不允许 3.办公区PC可以在任意时刻访问Web Server 4.生产…...
浅谈java并发编程
例子代码:纠结哥/java-learn - Gitee.com Java并发编程是指在Java中通过多线程技术让程序能够同时执行多个任务。通过并发编程,Java程序可以提高性能,尤其是在需要处理大量数据或多个任务时。Java并发编程有多种方式,可以通过直接…...
蓝桥杯C语言组:暴力破解
基于C语言的暴力破解方法详解 暴力破解是一种通过穷举所有可能的解来找到正确答案的算法思想。在C语言中,暴力破解通常用于解决那些问题规模较小、解的范围有限的问题。虽然暴力破解的效率通常较低,但它是一种简单直接的方法,适用于一些简单…...
[Go]一、Go语言基础
G:\Go\【物语终焉】21周搞定Go语言 1.环境安装 All releases - The Go Programming Language blog地址: https://www.liwenzhou.com/categories/Golang/ 图文教程: 从零开始搭建Go语言开发环境 | 李文周的博客 官网地址: 国内: https://studygolang.com/dl Go官网下载…...
React+Cesium基础教程(003):加载3D建筑物和创建标签
文章目录 03-加载3D建筑物和标签方式一方式二完整代码03-加载3D建筑物和标签 方式一 添加来自 OpenStreetMap 的建筑物模型,让场景更加丰富和真实: viewer.scene.primitives.add(new Cesium.createOsmBuildings() );方式二 使用 Cesium ion 资源:...
两晋南北朝 侨置州郡由来
侨置的核心思想是面向人管理 而不是面向土地 1. 北雍州 西晋于长安置雍州,永嘉之乱,没于刘、石。苻秦之乱,雍州流民南出樊沔,孝武于襄阳侨立雍州。此时称长安为北雍州。...
七. Redis 当中 Jedis 的详细刨析与使用
七. Redis 当中 Jedis 的详细刨析与使用 文章目录 七. Redis 当中 Jedis 的详细刨析与使用1. Jedis 概述2. Java程序中使用Jedis 操作 Redis 数据2.1 Java 程序使用 Jedis 连接 Redis 的注意事项2.2 Java程序通过 Jedis当中操作 Redis 的 key 键值对2.3 Java程序通过 Jedis 当中…...
