
第一步:先把Android Studio的“地基”打牢——环境配置和项目初始化
想写安卓APP源码,先得把Android Studio的环境搞定——这就像做饭前要先把锅碗瓢盆摆好,不然再会炒菜也没用。我帮小夏装的时候,他踩了三个典型坑,你可以提前避开:
首先是JDK安装。Android Studio需要Java Development Kit(JDK)才能运行,你直接下Oracle的JDK 17就行(别下太新的版本,比如21,可能和老版本Studio不兼容)。安装的时候记得选“Add to PATH”,不然Studio找不到JDK路径——小夏当时没选,结果Studio启动时弹出“JDK not found”,我帮他手动配置了环境变量才解决。
然后是Android Studio下载。直接去谷歌开发者官网下最新稳定版(别下Beta版,bug多),安装时选“Standard”标准配置——新手不用选“Custom”,省得不小心勾错选项。安装完成后,第一次启动会下载Android SDK(系统开发工具包),耐心等它下完,大概要10分钟左右。
接下来是项目初始化。打开Studio后,点“New Project”,选“Empty Activity”(新手优先选这个,结构最简单,没有多余的依赖)。然后填项目信息:
填完点“Finish”,Studio会自动生成项目结构——你会看到左边有“app”文件夹,里面有“java”(代码)、“res”(资源,比如图片、布局)、“manifests”(配置文件)三个子文件夹。我帮小夏理结构的时候,他问“这些文件夹都是干嘛的?”——简单说:java文件夹写逻辑代码(比如点击按钮后跳转到下一个页面),res文件夹放界面和资源(比如美食图片、页面布局),manifests里的AndroidManifest.xml是APP的“身份证”(写APP名称、权限、主页面)。
为了帮你更清楚初始化选项,我做了个表格:
选项名称 | 作用说明 | 新手推荐 |
---|---|---|
Empty Activity | 创建只有一个空页面的项目,结构最简单,适合新手 | 优先选 |
Bottom Navigation Activity | 带底部导航栏的模板,适合多页面APP(比如首页、我的) | 学会基础后再用 |
No Activity | 没有默认页面,需要自己写所有结构,复杂度高 | 不推荐新手 |
第二步:写源码的“骨架”——页面布局和核心功能实现
环境搭好后,就可以开始写源码了——先做“界面骨架”(XML布局),再写“逻辑肌肉”(Java代码)。我帮小夏做的美食推荐APP,核心界面是“美食卡”:左边一张图片,右边是美食名称、地址和评分。咱们就以这个为例,讲具体怎么写。
打开“res/layout/activity_main.xml”(这是主页面的布局文件),默认是“Design”可视化模式——你可以切换到“Code”模式,直接写XML代码(新手 先学Code模式,更清楚布局结构)。
我们用LinearLayout(线性布局)来放控件,代码大概长这样:
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:gravity="center_vertical">
<!-
美食图片 >
android:id="@+id/food_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/food1" <!-
要先把图片放到res/drawable文件夹里 >
android:scaleType="centerCrop"/>
<!-
文字区域 >
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginStart="16dp">
android:id="@+id/food_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="老巷口红烧肉"
android:textSize="18sp"
android:textStyle="bold"/>
android:id="@+id/food_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="XX路123号"
android:textSize="14sp"
android:textColor="#666666"
android:layout_marginTop="4dp"/>
android:id="@+id/food_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="评分:4.8"
android:textSize="14sp"
android:textColor="#FF5722"
android:layout_marginTop="4dp"/>
小夏当时写这段代码时,问了三个问题,我帮你提前解答:
布局写好后,打开“java/com/example/localfoodapp/MainActivity.java”(主页面的逻辑代码),我们要给控件赋值,比如把“老巷口红烧肉”改成从数据里读的内容(以后可以接数据库或接口)。
找到布局里的控件——用findViewById
方法:
// 找到ImageView(美食图片)
ImageView foodImage = findViewById(R.id.food_image);
// 找到TextView(名称、地址、评分)
TextView foodName = findViewById(R.id.food_name);
TextView foodAddress = findViewById(R.id.food_address);
TextView foodRating = findViewById(R.id.food_rating);
然后,给控件赋值:
// 给图片赋值(如果是网络图片,以后可以用Glide库加载,现在先用本地图片)
foodImage.setImageResource(R.drawable.food1);
// 给文字赋值
foodName.setText("老巷口红烧肉");
foodAddress.setText("XX路123号");
foodRating.setText("评分:4.8");
小夏当时写这段代码时,犯了个低级错误:把findViewById
写在了onCreate
方法外面——你要记住:所有控件初始化都要写在onCreate
方法里,而且要在setContentView(R.layout.activity_main)
之后,不然会报“NullPointerException”(空指针错误)。
我再给你加个小功能:点击“美食卡”跳转到详情页。 新建一个DetailActivity(右键“java”文件夹→New→Activity→Empty Activity),然后在MainActivity里给LinearLayout加点击事件:
// 找到整个美食卡的LinearLayout
LinearLayout foodCard = findViewById(R.id.food_card);
// 加点击事件
foodCard.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 跳转到DetailActivity
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
// 传递数据(比如美食名称)
intent.putExtra("food_name", "老巷口红烧肉");
startActivity(intent);
}
});
然后在DetailActivity里接收数据:
// 接收从MainActivity传过来的美食名称
String foodName = getIntent().getStringExtra("food_name");
// 给DetailActivity的TextView赋值
TextView detailName = findViewById(R.id.detail_name);
detailName.setText(foodName);
这样,点击美食卡就能跳到详情页了——小夏当时做完这个功能,兴奋得拍了张截图发朋友圈,说“原来写源码没那么难!”
第三步:让源码“活”起来——调试运行和常见Bug解决
写好源码后,要让它“跑”起来——要么用模拟器,要么用真机。我帮小夏运行的时候,他踩了两个常见坑,你可以提前规避:
首先是模拟器运行。点击Studio右上角的“AVD Manager”(虚拟设备管理器),点“Create Virtual Device”,选“Pixel 6”(谷歌的参考设备,适配性好),然后选“Android 13(Tiramisu)”系统镜像(下载需要点时间)。创建完成后,点“Run”按钮(绿色三角),模拟器会启动,然后安装APP。小夏第一次运行时,模拟器卡在开机界面10分钟——你创建模拟器时,内存至少设2G(在“Memory Options”里把RAM改成2048MB),CPU选“x86_64”,这样运行会顺畅点。
然后是真机运行。用USB线把手机连到电脑,打开手机的“开发者选项”和“USB调试”(不同手机打开方式不一样,比如小米是连续点“MIUI版本”5次)。连接成功后,Studio会识别到手机,选手机点“Run”就能安装APP。小夏当时连不上手机,我帮他检查发现是USB线的问题——换根原装线,或者用USB 3.0接口,大概率能解决。
最后是常见Bug解决。我整理了新手常遇到的3个问题和解决方法:
| Bug提示 | 原因 | 解决方法 |
||||
| Gradle sync failed | Gradle版本不兼容或网络问题 |
| INSTALL_FAILED_OLDER_SDK | APP最低SDK版本比手机高 | 打开“build.gradle(Module)”,把“minSdkVersion”改成和手机系统一致的版本(比如手机是Android 10,改成29) |
| 闪退(NullPointerException) | 控件没找到或赋值为空 | 检查findViewById
是否写在setContentView
之后,或者控件ID有没有写错 |
小夏当时遇到“NullPointerException”,我帮他检查发现是把R.id.food_card
写成了R.id.foodCard
——你写ID的时候要和XML里的android:id="@+id/food_card"
完全一致,大小写都不能错。
等你把这些步骤走完,就能得到一个能运行的安卓APP源码了——小夏当时做出第一个版本后,又加了搜索功能和收藏功能,现在那个APP已经在他们本地的美食社群里用了。你做的时候要是遇到问题,比如同步失败、代码报错,记得把错误信息截图发给我——我去年帮5个新手解决过类似问题,大概率能帮你搞定。
等你做出能运行的源码,记得来告诉我——我帮你看看能不能优化界面,或者加个小功能,比如分享到微信朋友圈。安卓开发没你想的那么难,慢慢来,你也能写出属于自己的APP!
本文常见问题(FAQ)
安装JDK时要注意什么?
Android Studio需要JDK才能运行, 下Oracle的JDK 17(别下太新的比如21,可能和老版本Studio不兼容)。安装的时候一定要选“Add to PATH”,不然Studio找不到JDK路径——我帮小夏装的时候他没选,结果启动时弹出“JDK not found”,后来手动配置环境变量才解决。
项目初始化时路径为什么不能有中文或空格?
项目保存路径要选全英文文件夹,别带空格或中文——小夏当时选了“D:我的项目”,结果Gradle同步失败三次。因为Android Studio的Gradle工具对中文或空格路径支持不好,容易识别错误,全英文路径能避免大部分同步问题。
模拟器运行卡怎么办?
创建模拟器时要注意两个设置:一是内存至少设2G(在“Memory Options”里把RAM改成2048MB),二是CPU选“x86_64”。我帮小夏调试时,他的模拟器卡在开机界面10分钟,改了这两个设置后运行就顺畅多了——新手别省内存,不然模拟器跑不起来。
遇到NullPointerException闪退怎么解决?
这个错误大多是控件没找到或赋值为空导致的,要检查两个点:第一,所有控件的findViewById方法是不是写在onCreate方法里,而且在setContentView(R.layout.activity_main)之后——小夏之前把findViewById写在外面,结果报错;第二,控件ID有没有写错,比如XML里是“food_card”,Java里写成“foodCard”,大小写或拼写错了都会找不到控件。
布局里sp和dp有什么区别?
sp是文字大小的单位,会跟随系统字体缩放——比如用户把手机字体调大,用sp的文字也会跟着变大;dp是布局单位,会适配不同屏幕密度——比如100dp在小屏幕手机和大屏幕手机上显示的大小比例是一致的。新手别用px(像素),不然在不同手机上显示会乱,优先用sp和dp准没错。