[安卓逆向]编写第一个安卓项目(一)

验证图:

一.下载安装开发工具

shell 复制代码
#Android Studio 下载地址
https://developer.android.google.cn/studio?hl=zh-cn
#自行安装该工具

二.编写项目

2.1 创建项目架构

此次开发工具为Android Studio 为2024.3.1版本

创建项目,选择 Empty Views Activity 模板 ,

谷歌已经将Kotlin视为Android开发的首选语言 ,此次演示选择Java 语言

2.2 编写登录界面

打开activity_main.xml

设置登录界面 拖拉了两个Textview,两个Plain Test和一个Button控件

美化后activity_main.xml登录界面(可以不使用):

xml 复制代码
<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F5F7FA"
    tools:context=".MainActivity">

    <!-- 顶部装饰条 -->
    <View
        android:id="@+id/topBar"
        android:layout_width="0dp"
        android:layout_height="120dp"
        android:background="@color/colorPrimary"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="欢迎登录"
        android:textColor="#FFFFFF"
        android:textSize="28sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="@+id/topBar"
        app:layout_constraintEnd_toEndOf="@+id/topBar"
        app:layout_constraintStart_toStartOf="@+id/topBar"
        app:layout_constraintTop_toTopOf="@+id/topBar" />

    <!-- 卡片容器 -->
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="32dp"
        app:cardCornerRadius="16dp"
        app:cardElevation="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="24dp">

            <!-- 用户名行:固定标签宽度,输入框自适应 -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:gravity="center_vertical">

                <TextView
                    android:layout_width="60dp"
                android:layout_height="wrap_content"
                android:text="用户名"
                android:textColor="#333333"
                android:textSize="16sp"
                android:textStyle="bold" />

                <EditText
                    android:id="@+id/etUsername"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@drawable/edittext_bg"
                    android:hint="请输入用户名"
                    android:padding="12dp"
                    android:inputType="text"
                    android:textSize="15sp"
                    android:layout_marginStart="12dp" />
            </LinearLayout>

            <!-- 密码行:同样固定标签宽度,输入框宽度一致 -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:gravity="center_vertical"
                android:layout_marginTop="20dp">

                <TextView
                    android:layout_width="60dp"
                android:layout_height="wrap_content"
                android:text="密码"
                android:textColor="#333333"
                android:textSize="16sp"
                android:textStyle="bold" />

                <EditText
                    android:id="@+id/etPassword"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@drawable/edittext_bg"
                    android:hint="请输入密码"
                    android:padding="12dp"
                    android:inputType="textPassword"
                    android:textSize="15sp"
                    android:layout_marginStart="12dp" />
            </LinearLayout>

            <!-- 登录按钮 -->
            <Button
                android:id="@+id/btnLogin"
                android:layout_width="match_parent"
                android:layout_height="54dp"
                android:layout_marginTop="32dp"
                android:background="@drawable/button_bg"
                android:text="登 录"
                android:textColor="#FFFFFF"
                android:textSize="18sp"
                android:textStyle="bold" />

        </LinearLayout>

    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

同时在res/drawable下增加button_bg.xml和edittext_bg.xml ,res/values下修改colors.xml

button_bg.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FFFFFF" />
    <corners android:radius="12dp" />
    <stroke android:width="1dp" android:color="#DDDDDD" />
</shape>

edittext_bg.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape>
            <solid android:color="#0066CC" />
            <corners android:radius="27dp" />
        </shape>
    </item>
    <item>
        <shape>
            <solid android:color="#2196F3" />
            <corners android:radius="27dp" />
        </shape>
    </item>
</selector>

colors.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="colorPrimary">#2196F3</color>
</resources>

2.3 编写java代码

打开MainActivity.java

编写MainActivity.java代码

java 复制代码
package com.example.myapplication;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity {

    private EditText etUsername;
    private EditText etPassword;
    private Button btnLogin;

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

        // 处理状态栏沉浸(保持原样)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        // 1. 初始化控件(确保 id 与 XML 完全一致)
        try {
            etUsername = findViewById(R.id.etUsername);
            etPassword = findViewById(R.id.etPassword);
            btnLogin = findViewById(R.id.btnLogin);

            // 调试:如果控件为空,会在 Logcat 中打印错误
            if (etUsername == null || etPassword == null || btnLogin == null) {
                Toast.makeText(this, "控件初始化失败,请检查 XML 中的 id", Toast.LENGTH_LONG).show();
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(this, "初始化出错:" + e.getMessage(), Toast.LENGTH_LONG).show();
            return;
        }

        // 2. 设置登录按钮点击事件
        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取输入内容
                String username = etUsername.getText().toString().trim();
                String password = etPassword.getText().toString().trim();

                // 简单的验证逻辑
                if (username.isEmpty()) {
                    Toast.makeText(MainActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
                } else if (password.isEmpty()) {
                    Toast.makeText(MainActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
                } else if (username.equals("admin") && password.equals("123456")) {
                    Toast.makeText(MainActivity.this, "登录成功!", Toast.LENGTH_SHORT).show();
                    // 可以在这里添加跳转逻辑
                } else {
                    // 这里就是你说的"用户名或密码错误"
                    Toast.makeText(MainActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

三.打包

3.1 调试版APK打包

  1. 点击菜单栏 BuildGenerate App Bundles or APKsGenerate APKs

  2. 等待底部状态栏出现成功提示,并显示 APK 文件路径

    3.点击 locate 直接打开文件夹

3.1 正式签名版APK

如果需要发给别人用,或者要上架应用商店,必须签名。

  1. 点击菜单栏 BuildGenerate Signed App Bundle or APK选择 APK
  2. 点击 Create new 创建签名密钥(只需创建一次)
    • Key store path:点击文件夹图标,选择保存位置(如 D:/mykey.jks
    • Password:输入密码(记住它)
    • Alias:别名(如 mykey
    • 其他随便填,至少填一个 Name
  3. 等待构建完成,点击 locate 打开文件夹

APK 位置
项目根目录/app/release/app-release.apk

3.2 正式版安装

模拟器中安装打包好的签名版APK

总结

此次演示从项目创建到打包以及安装都做了简单描述,有了这些基础逆向时才会如鱼得水。

相关推荐
weiggle11 小时前
第七篇:状态提升与单向数据流——架构设计的核心
android
xingpanvip11 小时前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
goldenrolan11 小时前
A公司物料替代测试系统 v1.7:从需求到 exe/apk 的 AI 辅助全链路实践
android·自动化测试·软件测试·python·ai
AC赳赳老秦12 小时前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw
骇客之技术13 小时前
AutoLua:在安卓上写 Lua 脚本
android·junit·lua
kiros_wang14 小时前
Android 常见面试题
android
货拉拉技术15 小时前
Hook植入日志协助定位问题方案
android
FlightYe15 小时前
Android投屏MirrorCast全链路
android
Ehtan_Zheng15 小时前
Kotlin const val vs val:字节码、性能与隐藏陷阱详解
android·kotlin
墨狂之逸才15 小时前
Android TV 垃圾应用清理指南
android