Android基础实验复现:环境搭建与Activity通信详解
简介这份实验报告面向软件学院修读移动应用软件开发技术课程的学生聚焦Android平台开发入门帮助读者完成从环境搭建到界面设计的完整实践训练。资源包内共1个doc文档约1.63MB以实验报告正文形式呈现内容按实验项目分节组织便于对照课程进度逐项完成。报告详细覆盖Android系统环境搭建包括JDK安装与环境变量配置、Eclipse集成开发环境的部署、Android SDK的在线更新与离线安装方法以及ADT插件的安装流程同时包含Activity运用实验涉及Activity的创建、启动、生命周期管理与Intent跳转并延伸到Android应用UI设计涵盖TextView、Button、ImageView等基础控件以及LinearLayout、RelativeLayout、GridLayout等布局管理器的使用。目前已有767人学习下载适合需要提交实验报告、复习Android开发基础流程或准备移动应用开发课程实践的学生参考可帮助读者快速理清各实验环节的操作要点与验证方式。1. 从一份 2013 年的实验报告说起Android 环境搭建与 Activity 通信到底该怎么复现翻到这份《移动应用软件开发技术实验报告》的时候我第一反应是这套东西现在还有人用吗JDK 6、Eclipse、ADT 插件、android-sdk_r16——全是十多年前的版本号。但仔细拆完发现它其实是一份结构非常完整的 Android 入门实训材料覆盖了环境搭建、Activity 跳转、Intent 传值、UI 布局嵌套、对话框交互这几块最核心的基础能力。对于刚接触 Android 开发、需要跟着实验步骤一步步走通“从零到能跑起来一个 App”的人来说这份报告的价值不在于版本新旧而在于它把每个环节的操作路径、验证方式、需要提交的截图和源码都列得很清楚。你拿到手就知道下一步该干什么不用自己去猜。这份资源适合两类人一类是正在上移动应用开发课程、需要完成类似实验任务的学生可以直接对照它的实验结构和代码模板来搭自己的工程另一类是已经工作但没系统走过 Android 基础流程的开发者想快速补一下 Activity 生命周期、Intent 传值、布局嵌套这些基本功。它不涉及高级架构、不聊 Jetpack、不讲 Compose就是最朴素的“建工程、写布局、跳页面、传数据”。但恰恰是这些最基础的东西很多人其实并没有真正跑通过一遍。接下来的内容我会按这份报告本身的实验顺序来拆先讲环境搭建里那些容易翻车的配置细节再讲 Activity 跳转和 Intent 传值的完整代码逻辑然后是 UI 布局嵌套和对话框的实现方式最后给几个排查问题的具体手段。每一步都尽量落到可复现的操作上不空谈概念。2. Android 开发环境搭建JDK、Eclipse、SDK、ADT 四件套的配置细节2.1 为什么这套老环境仍然值得走一遍现在主流开发早就切到 Android Studio 了Gradle 构建、Kotlin 优先、Jetpack 组件一应俱全。但这份实验报告用的是 JDK Eclipse Android SDK ADT 插件的组合这套流程在 2013 年前后是标准做法。你可能会问都什么年代了还配 Eclipse我的看法是如果你只是为了完成课程实验或者理解 Android 构建的基本链路走一遍这套流程反而能让你看清楚很多被 Android Studio 封装掉的东西——比如 SDK 目录结构长什么样、ADT 插件到底做了什么、环境变量为什么必须配。具体来说这套环境的核心逻辑是JDK 提供 Java 编译运行能力Eclipse 作为代码编辑器Android SDK 提供 Android 特有的编译工具和平台库ADT 插件负责把 SDK 和 Eclipse 打通。四者缺一不可而且有严格的依赖顺序。2.2 JDK 安装与环境变量配置实验报告里要求 JDK 6.0 以上版本实际你装 JDK 8 也完全能跑通这套流程。安装本身没什么好说的关键是环境变量。很多人装完 JDK 后在 cmd 里敲java -version能出版本号就以为配好了结果 Eclipse 启动时报 “No Java virtual machine found”这就是JAVA_HOME没配或者配错了。正确的做法是新建系统变量JAVA_HOME值指向 JDK 安装根目录然后在Path里追加%JAVA_HOME%\bin。注意不要直接往 Path 里写 JDK 的完整路径因为后面如果换 JDK 版本你得改好几个地方。# 验证 JDK 是否配置正确依次执行以下命令 java -version # 预期输出类似java version 1.8.0_xxx javac -version # 预期输出类似javac 1.8.0_xxx echo %JAVA_HOME% # 预期输出 JDK 安装根目录如 C:\Program Files\Java\jdk1.8.0_xxx三个命令都能正常输出才算 JDK 配置到位。java -version验证运行环境javac -version验证编译环境echo %JAVA_HOME%验证环境变量本身。少任何一个后面 Eclipse 或 SDK Manager 都可能出问题。实验报告里还要求写一个test.java来验证这个步骤看起来多余但实际上它能帮你确认编译和运行两条链路都通了。写一个最简单的类编译成.class文件再用java命令运行整个流程走通就说明 JDK 没问题。2.3 Eclipse 与 ADT 插件的安装要点Eclipse 本身是绿色软件下载压缩包解压就能用。实验报告里选的是 “Eclipse IDE for Java EE Developers” 版本这个版本自带了不少 Java Web 开发插件对于 Android 开发来说其实用不到但也不影响。解压后直接双击eclipse.exe就能启动。ADT 插件的安装是这套流程里最容易出问题的环节。实验报告里给的安装地址是http://dll-ssl.google.com/android/eclipse/这个地址现在肯定已经失效了。如果你要复现这套流程需要找离线的 ADT 插件包通过Help - Install New Software - Add - Archive的方式本地安装。在线安装的方式在当前网络环境下基本走不通。安装完 ADT 后必须重启 Eclipse然后在Window - Preferences - Android里设置 SDK Location。这一步如果跳过新建 Android 项目时 Eclipse 会报 “Android SDK not found” 的错误。设置完成后Eclipse 工具栏上会出现 Android SDK Manager 和 AVD Manager 两个图标说明 ADT 插件已经正常工作。2.4 Android SDK 的在线与离线安装SDK 的安装分在线和离线两种方式。在线方式是通过 SDK Manager 勾选需要的组件自动下载离线方式是自己手动下载各个平台的 zip 包解压到 SDK 目录对应的子文件夹里。实验报告里详细列了离线安装需要下载的文件清单包括android-1.5_r04-windows.zip到android-2.2_r01-windows.zip各个平台版本以及tools_r06-windows.zip、usb_driver_r03-windows.zip等工具包。离线安装的关键是目录结构要对平台包解压后放到platforms文件夹下每个版本一个子目录工具包解压后放到tools文件夹下文档包放到docs下。组件类型解压目标目录典型文件平台版本platforms/android-X.X/android-2.2_r01-windows.zip开发工具tools/tools_r06-windows.zip文档docs/docs-2.2_r01-linux.zip示例代码samples/samples-2.2_r01-linux.zipUSB 驱动usb_driver/usb_driver_r03-windows.zip目录结构不对的话SDK Manager 识别不到已安装的组件Eclipse 里新建项目时会提示没有可用的 Build Target。我一般会先解压tools包因为 SDK Manager 本身就在 tools 目录下有了它才能验证其他组件是否被正确识别。注意离线安装时platforms文件夹需要手动创建SDK 解压后不会自动生成这个目录。如果忘了建后面放进去的平台包不会被识别。3. Activity 跳转与 Intent 传值从 TestActivity01 到 TestActivity02 的完整实现3.1 Activity 与 Intent 的基本关系Activity 是 Android 应用的四大组件之一代表一个用户可以交互的屏幕。一个应用通常由多个 Activity 组成每个 Activity 负责一个独立的界面。Activity 之间的跳转靠 Intent 来完成Intent 可以理解为“我想干什么”的意图描述。这份实验报告里的实验二有两个子任务TestActivity01 实现最简单的 Activity 跳转MainActivity 上有一个按钮点击后启动 OtherActivityTestActivity02 在此基础上增加了数据传递把 MainActivity 里的字符串“中国”通过 Intent 传到 OtherActivity 并显示出来。这两个任务的代码结构非常清晰适合作为理解 Activity 通信的入门模板。下面我把关键代码拆开讲。3.2 TestActivity01按钮触发 Activity 跳转先看 MainActivity 的代码。核心逻辑是在onCreate里找到按钮控件然后给它设置点击监听器在监听器里创建 Intent 并启动目标 Activity。// MainActivity.java package com.example.test1; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { Button b; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 加载布局文件 b (Button) findViewById(R.id.button1); // 通过 ID 找到按钮控件 b.setOnClickListener(new OnClickListener() { public void onClick(View v) { // 创建 Intent指定从 MainActivity 跳转到 second Intent intent new Intent(MainActivity.this, second.class); startActivity(intent); // 启动目标 Activity } }); } }这段代码里有几个关键点。setContentView(R.layout.activity_main)负责把 XML 布局文件加载到当前 Activity 上没有这一行界面上什么都不会显示。findViewById(R.id.button1)通过资源 ID 找到布局里定义的按钮这个 ID 是在 XML 里用android:idid/button1声明的。new Intent(MainActivity.this, second.class)构造了一个显式 Intent第一个参数是当前上下文第二个参数是目标 Activity 的 Class 对象。startActivity(intent)执行跳转。目标 Activity 的代码更简单只需要加载自己的布局文件// second.java package com.example.test1; import android.os.Bundle; import android.app.Activity; import android.widget.TextView; public class second extends Activity { TextView t; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.two); // 加载 two.xml 布局 t (TextView) findViewById(R.id.ray); // 找到 TextView 控件 } }对应的布局文件activity_main.xml里定义了一个按钮two.xml里定义了一个 TextView。布局文件本身不复杂但要注意tools:context属性它指定了这个布局文件关联的 Activity 类方便在 Eclipse 里预览。提示新建 Activity 时必须在AndroidManifest.xml里注册否则启动时会报ActivityNotFoundException。Eclipse 的 ADT 插件在新建 Activity 时会自动帮你注册但如果你是手动创建类文件就需要自己加activity android:name.second /这一行。3.3 TestActivity02用 Bundle 传递字符串数据TestActivity02 在跳转的基础上增加了数据传递。MainActivity 里把字符串“中国”放进 Bundle再把 Bundle 塞进 Intent目标 Activity 从 Intent 里取出 Bundle再取出字符串显示到 TextView 上。// TextMainActivity.java package com.example.test; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class TextMainActivity extends Activity { Button y; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_text_main); y (Button) findViewById(R.id.button1); y.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent testintent new Intent(); // 创建空 Intent Bundle testbundle new Bundle(); // 创建 Bundle 用于携带数据 testbundle.putString(name, 中国); // 以键值对形式存入字符串 testintent.putExtras(testbundle); // 将 Bundle 放入 Intent testintent.setClass(TextMainActivity.this, test_2.class); // 指定目标 Activity startActivity(testintent); // 启动跳转 } }); } }目标 Activity 从 Intent 中取出数据// test_2.java package com.example.test; import android.os.Bundle; import android.app.Activity; import android.widget.TextView; public class test_2 extends Activity { TextView test; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second); test (TextView) findViewById(R.id.ruirui); Bundle tbd this.getIntent().getExtras(); // 获取 Intent 中的 Bundle String name tbd.getString(name); // 按键名取出字符串 test.setText(name); // 设置到 TextView 上显示 } }这里的关键是putString和getString的键名必须一致都是name。如果键名写错了getString会返回 nullTextView 上什么都不显示但程序不会崩溃这种问题排查起来比较隐蔽。我一般会在getString之后加一个判空逻辑或者在 Logcat 里打印一下取到的值。另外getIntent().getExtras()返回的 Bundle 可能为 null如果目标 Activity 是被其他方式启动的比如从桌面图标直接进入就没有 Intent 携带的数据。稳妥的做法是先判断getIntent().getExtras()是否为 null再取值。3.4 两个实验的差异与扩展思路TestActivity01 和 TestActivity02 的核心差异就在于是否携带数据。前者只做页面跳转后者在跳转的同时传递了一个字符串。实际开发中Intent 可以传递的数据类型远不止字符串还包括 int、boolean、数组、Serializable 对象、Parcelable 对象等。传递复杂对象时实现 Parcelable 接口的性能更好但代码量也更大。如果你想在这两个实验的基础上做扩展可以试试传递一个自定义的实体类对象在目标 Activity 里解析并展示多个字段或者用startActivityForResult实现带返回值的跳转比如从目标 Activity 返回一个结果给 MainActivity。这些都是在实际开发中高频使用的模式。4. UI 布局嵌套与对话框LinearLayout、TableLayout、RelativeLayout 的组合运用4.1 布局嵌套的分析方法实验三要求实现一个如图 3.1 所示的 UI 界面最外层是纵向的 LinearLayout里面包含三个子布局一个横向的 LinearLayout四列、一个 TableLayout三行三列、一个纵向的 LinearLayout四行。这种嵌套结构在 Android UI 设计里非常典型核心思路是“先分块、再填充”。拿到一个界面设计图第一步不是急着写 XML而是先分析它的层级结构。哪些元素是横向排列的哪些是纵向排列的哪些需要表格对齐哪些需要相对定位。分析清楚了XML 写起来就是按层级翻译的事。4.2 外层纵向 LinearLayout 与内层横向布局最外层用android:orientationvertical的 LinearLayout宽度和高度都设为fill_parent让它占满整个屏幕。第一个子布局是横向 LinearLayout里面放四个 TextView每个 TextView 的layout_weight设为 1这样四个控件会等分横向空间。LinearLayout android:orientationvertical android:layout_widthfill_parent android:layout_heightfill_parent !-- 第一块横向四列 -- LinearLayout android:orientationhorizontal android:layout_widthfill_parent android:layout_heightwrap_content android:layout_weight2 TextView android:textred android:gravitycenter android:background#CE0000 android:layout_widthwrap_content android:layout_heightfill_parent android:layout_weight1 / TextView android:textgreen android:gravitycenter android:background#00A600 android:layout_widthwrap_content android:layout_heightfill_parent android:layout_weight1 / !-- 其余两个 TextView 同理 -- /LinearLayout /LinearLayoutlayout_weight是 LinearLayout 里最核心的分配参数。当多个子控件的layout_weight都设为 1 时它们会等分剩余空间。如果某个控件的 weight 设为 2它就会占据两份空间。这里外层第一个子布局的layout_weight2表示它在纵向空间中占两份后面的 TableLayout 和另一个纵向 LinearLayout 各占一份。4.3 TableLayout 的三行三列实现TableLayout 是专门用来做表格对齐的布局它的子控件按行排列每行可以包含多个控件。实验要求三行三列那就写三个 TableRow每个 TableRow 里放三个 TextView。TableLayout android:layout_widthfill_parent android:layout_heightwrap_content android:stretchColumns* TableRow TextView android:text1-1 android:gravitycenter / TextView android:text1-2 android:gravitycenter / TextView android:text1-3 android:gravitycenter / /TableRow TableRow TextView android:text2-1 android:gravitycenter / TextView android:text2-2 android:gravitycenter / TextView android:text2-3 android:gravitycenter / /TableRow TableRow TextView android:text3-1 android:gravitycenter / TextView android:text3-2 android:gravitycenter / TextView android:text3-3 android:gravitycenter / /TableRow /TableLayoutandroid:stretchColumns*表示所有列都自动拉伸填满可用宽度。如果不加这个属性表格列宽会根据内容自适应可能导致列宽不一致看起来不整齐。4.4 多输入框对话框的实现实验三的第二个任务是实现一个多输入框的对话框要求用 LinearLayout 布局、两个 TextView 和两个 EditText点击按钮后有对应的输出。这个功能可以用 AlertDialog 来实现在对话框里嵌入一个自定义的 LinearLayout。// 在 Activity 中构建对话框 AlertDialog.Builder builder new AlertDialog.Builder(this); builder.setTitle(请输入信息); // 创建对话框内部的布局 LinearLayout layout new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); TextView label1 new TextView(this); label1.setText(姓名); EditText input1 new EditText(this); input1.setHint(请输入姓名); TextView label2 new TextView(this); label2.setText(年龄); EditText input2 new EditText(this); input2.setHint(请输入年龄); layout.addView(label1); layout.addView(input1); layout.addView(label2); layout.addView(input2); builder.setView(layout); // 将自定义布局设置到对话框上 builder.setPositiveButton(确定, new DialogInterface.OnClickListener() { Override public void onClick(DialogInterface dialog, int which) { String name input1.getText().toString(); String age input2.getText().toString(); // 用 Toast 显示输入结果 Toast.makeText(MainActivity.this, 姓名 name 年龄 age, Toast.LENGTH_SHORT).show(); } }); builder.setNegativeButton(取消, null); builder.show(); // 显示对话框这段代码的逻辑是先创建 AlertDialog.Builder然后构建一个纵向 LinearLayout 作为对话框的内容区域依次添加 TextView 和 EditText最后通过setView把布局嵌入对话框。点击“确定”按钮时从两个 EditText 里读取文本用 Toast 展示出来。注意AlertDialog 的setView方法接收的是一个 View 对象如果你在对话框里放了 EditText需要确保对话框的布局参数正确否则输入框可能显示不全或者宽度异常。常见做法是给 LinearLayout 设置 padding让内容不要贴边。5. 避坑与排查环境配置和 Activity 开发中的五个高频问题5.1 Eclipse 启动报 “No Java virtual machine found”现象双击eclipse.exe后弹窗提示找不到 Java 虚拟机Eclipse 无法启动。原因Eclipse 启动时会去读JAVA_HOME环境变量或者系统 Path 里的 java 路径如果JAVA_HOME没配、配错了目录、或者指向了 JRE 而不是 JDK就会报这个错。解决检查JAVA_HOME是否指向 JDK 根目录不是 JRE也不是 bin 目录。在 cmd 里执行echo %JAVA_HOME%确认路径存在且包含bin\javac.exe。如果环境变量没问题但 Eclipse 还是报错可以在 Eclipse 安装目录下新建eclipse.ini文件在开头加两行-vm和 JDK 的bin\javaw.exe完整路径。5.2 SDK Manager 无法在线更新组件现象打开 SDK Manager 后列表里显示不了可下载的组件或者点击安装后进度条一直不动。原因SDK Manager 需要访问 Google 的下载服务器网络不通或者被拦截时就会卡住。另外旧版本的 SDK Manager 可能使用了已经废弃的协议或地址。解决改用离线安装方式手动下载各个组件的 zip 包解压到 SDK 目录对应的子文件夹里。离线安装的关键是目录结构要对platforms下每个版本一个子目录tools下放工具包。放好之后重启 SDK Manager它应该能识别到已安装的组件。5.3 新建 Android 项目后 R.java 文件不生成现象新建项目后gen目录下没有R.java文件代码里引用R.layout.xxx全部报红。原因R.java 是 Eclipse 根据res目录下的资源文件自动生成的如果 XML 文件里有语法错误或者资源文件命名不规范比如文件名包含大写字母R.java 就不会生成。解决先检查res目录下所有 XML 文件是否有语法错误Eclipse 的 Problems 视图里会列出具体错误。然后确认资源文件名只包含小写字母、数字和下划线。修复错误后执行Project - Clean让 Eclipse 重新构建项目R.java 应该会重新生成。5.4 Activity 跳转时报 ActivityNotFoundException现象点击按钮后程序崩溃Logcat 里报android.content.ActivityNotFoundException: Unable to find explicit activity class。原因目标 Activity 没有在AndroidManifest.xml里注册。Android 要求所有 Activity 都必须显式声明在 Manifest 文件里否则系统找不到它。解决打开AndroidManifest.xml在application标签内添加activity android:name.second /其中.second是目标 Activity 的类名相对于包名的路径。如果 Activity 在子包下需要写完整的包路径。5.5 Intent 传值时目标 Activity 取到 null现象目标 Activity 里getIntent().getExtras()返回 null或者getString(key)取出来是 nullTextView 上什么都不显示。原因可能有三种情况——发送方没有调用putExtras或者键名写错了或者目标 Activity 是被其他方式启动的比如从桌面图标直接进入此时 Intent 里没有携带数据。解决在发送方确认putExtras被调用了并且键名和接收方的getString参数完全一致。在接收方加判空逻辑如果getExtras()返回 null就跳过取值或者给一个默认值。调试时可以在getString之后加一行Log.d(IntentTest, name name)在 Logcat 里看实际取到的值。6. 从实验报告到可运行工程几个让复现更顺手的实操技巧这份实验报告里的代码都是片段式的直接复制到 Eclipse 里可能会因为包名不一致、资源 ID 对不上而报错。我一般会先把整个工程结构搭好再往里面填代码。具体做法是在 Eclipse 里新建一个 Android Application Project包名统一用com.example.test然后按照实验报告里的文件清单逐个创建 Activity 类和对应的布局文件。有一个容易被忽略的点是AndroidManifest.xml里的minSdkVersion和targetSdkVersion。实验报告里用的平台版本比较老如果你装的是较新的 SDK新建项目时默认的 minSdkVersion 可能比较高导致在旧版本模拟器上跑不起来。我一般会把 minSdkVersion 设成 8 或者 10targetSdkVersion 设成 16 左右这样兼容性最好。另外Eclipse 里的模拟器AVD创建也是个坑。如果你在 AVD Manager 里创建模拟器时选了带 Google APIs 的镜像启动会特别慢。做这种基础实验选普通的 ARM 镜像就够了启动快占内存少。如果模拟器启动后一直卡在开机画面试试在创建时勾选 “Use Host GPU”能明显提升渲染速度。排查场景查看位置关键信息程序崩溃Logcat 视图AndroidRuntime标签下的异常堆栈布局不显示XML 编辑器Problems视图里的错误提示资源找不到gen/R.java确认资源 ID 是否生成跳转失败AndroidManifest.xml检查 Activity 是否注册数据传丢Logcat 自定义标签打印 Intent 里的 Bundle 内容最后说一个我自己的习惯每次新建一个 Activity我会先在 Manifest 里注册好再写 Java 代码最后写布局文件。这个顺序看起来无所谓但实际上能避免很多“代码写完了才发现没注册”的返工。从那以后我每次搭新工程都强制走一遍这个流程省了不少来回折腾的时间。希望帮到你。本文还有配套的精品资源点击获取