学习安卓开发[1] - 程序结构、Activity生命周期及页面通信
一、程序结构
Android原生应用采用了MVC的架构设计模式,因此可以将一个Android APP中的对象归为Model、View或Controller中的一种。
具体到某个实际的APP结构中,它一般会由若干个activity、layout文件和自定义类组成,activity是Android SDK中Activity类的实例,负责管理用户与应用界面的交互,应用的功能是通过编写Activity子类来实现的;layout文件则用于定义需要显示的UI对象以及指定它们在屏幕上所处的位置,layout文件的后缀为XML。
由此可知,layout文件等属于视图对象,此外Android还自带了很多可配置的视图类,在后面逐步了解。控制器则通常是Activity、Fragment或Service的子类。

二、layout文件内容
layout文件定义了界面显示的UI组件及其布局方式,对于下面这样一个简单界面
其layout文件内容为:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/question_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/true_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button" />
<Button
android:id="@+id/false_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/false_button" />
<Button
android:id="@+id/cheat_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cheat_button"/>
<Button
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next_button"
android:drawableRight="@drawable/arrow_right"/>
</LinearLayout>
</LinearLayout>
其组成有:
一个垂直的LinerLayout组件,包含一个TextView组件和一个水平的LinerLayout组件;
水平的LinerLayout组件中又包含4个Button组件。
先看一下这里面包含的一些后续会经常用到的属性:
1. android:layout_width和android:layout_height,可以设置为wrap_content(视图与其父视图大小相同)或match_content(视图会根据其内容自动调整大小)。可以看到作为根节点的LinerLayout也有layout_width和layout_height属性,这是因为Android系统为其提供了容纳整个应用的父视图。
2.android:orientation,orientation是LinerLayout组件具有的属性,它指定LinerLayout的子组件是水平放置还是水平放置。
3.android:text,TextView和Button具有text属性,指定组件要显示的文字内容。
三、字符串资源
可以看到android:text的值为类似"@string/next_button"这样的形式,这是对字符串资源的应用,字符串资源(string resource)在string.xml中定义。通过把字符串内容放置在字符串资源,然后再间接引用它们,这样可以方便地修改需要显示的内容,更重要的是便于应用的本地化。
比如@string/next_button在字符串资源中的形式为:
<string name="next_button">Next</string>
那么为什么在layout文件中输入“@string/”后,Android会自动提示出“next_button”呢,这要从资源ID说起。非代码形式的内容都属于资源,比如图像文件、音频文件、XML文件等,资源文件都存放在app/res的子目录下,string.xml的路径为app/res/values,layout.xml的路径为app/res/layout,要获取这些xml中定义的资源需要先知道对应的资源ID,所有资源的ID都存放在R.java文件中,将Android Studio的项目视图切换为Project后,可根据路径app/build/generated/source/r/debug/对于项目包名称/R.java找到R文件,在这里我们可以在public static final class string下找到
public static final int next_button=0x7f0b0025,这便是next_button的资源ID,资源ID都是int型。
R文件在编译时自动生成,手动修改可能会导致未知错误。修改资源内容后,R文件不会实时刷新,只有在应用安装到模拟器或物理设备时才会重新生成,Android Studio还另外保存有一份用于代码编译的隐藏的R文件。
四、Activity
1.组件的引用
一个页面的Activity与layout的名称有对应关系,比如activity_quiz.xml对应的activity名称为QuizActivity.java。在Activity中使用组件的第一步,也是通过资源ID获取该组件,比如引用一个Button时的代码为:
private Button mTrueButton;
...
mTrueButton=(Button) findViewById(R.id.true_button);
拿到组件后,就可以做后续的操作了,比如为Button设置监听器(listener):
mTrueButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
}
});
或者改变TextView的显示内容:
mQuestionTextView=(TextView) findViewById(R.id.question_text_view);
mQuestionTextView.setText(“New Text”);
2.Activity的生命周期
在使用Android Studio向导创建一个Activity后,默认会有onCreate方法:
@Override
protected void onCreate(Bundle savedinstanceState){
}
onCreate属于Activity的生命周期方法,此外还有onStart(), onResume(), onPause(), onStop(), onDestroy()。页面在不同的状态间切换时,这些方法会被Android系统执行

启动APP时,依次执行onCreate, onStart, onResume,直接进入运行态;
按Home键回到主页时,依次执行onPause, onStop,进入停止态;
点击返回键退出APP时,则会依次执行onPause, onStop和onDestroy,页面被销毁;
需要注意的是,旋转屏幕时也会依次执行onCreate, onStart, onResume,这是因为发生屏幕旋转时,Android会销毁当前activity,寻找合适的备选资源并重新创建。这一特性对于需要保存页面状态的activity会造成问题,因为重新创建activity会丢失当前页面的操作状态,这是我们不希望发生的。要解决这个问题,可以覆盖系统的onSaveInstanceState(Bundle)方法,在APP转入停止状态时,这个方法在onStop之前由系统调用,我们可以在这个方法中将activity视图状态相关的数据存入Bundle对象中:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt(KEY_INDEX, mCurrentIndex);
}
然后在每次重新创建activity时尝试读取Bundle中的内容:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mCurrentIndex = savedInstanceState.getInt(KEY_INDEX);
}
....
}
五、页面通信
一般来说一个APP不可能只有一个页面,通过主页面打开子页面时就涉及到了页面间的通信。
Android使用基于Intent的通信方式,intent对象是component用来与操作系统通信的媒介工具。activity就是一种component对象。Intent是一种多用途通信工具,Intent类有多个构造方法,能满足不同的使用需要。
1.从父页面启动子页面
假设父页面为QuizActivity,子页面为CheatActivity,则从父页面启动子页面的方法为:
...
Intent intent = new Intent(QuizActivity.this, CheatActivity.class);
intent.putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue);
startActivity(intent);
...
使用intent.putExtra方法可以在启动子页面的同时传入需要的值,然后子页面可读取传入值的方法为:
mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);
2.子页面返回结果给父页面
在很多场景中都需要子页面返回结果给父页面。有两个方法可以使用:
public final void setResult(int resultCode)
public final void setResult(int resultCode, Intent data)
resultCode的值为预定义常量,有:
Activity.RESULT_OK,对应确认操作
Activity.RESULT_CANCELED,对应取消操作
Activity.RESULT_FIRST_USER,用于自定义结果代码
使用public final void setResult(int resultCode, Intent data)即可将结果数据通过Intent返回给父页面。
相应的,在父页面要取得子页面的返回结果,需要覆盖onActivityResult(int, int, Intent方法)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE_CHEAT) {
if (data == null) {
return;
}
//TODO
}
}
学习安卓开发[1] - 程序结构、Activity生命周期及页面通信的更多相关文章
- 【Android实验】第一个Android程序与Activity生命周期
目录 第一个Android程序和Activity生命周期 实验目的 实验要求 实验过程 1. 程序正常启动与关闭 2. 外来电话接入的情况 3. 外来短信接入的情况 4. 程序运行中切换到其他程序(比 ...
- Android学习路线(十二)Activity生命周期——启动一个Activity
DEMO下载地址:http://download.csdn.net/detail/sweetvvck/7728735 不像其他的编程模式那样应用是通过main()函数启动的.Android系统通过调用 ...
- Android学习路线(十四)Activity生命周期——停止和重新启动(Stopping and Restarting)一个Activity
正确地停止和重新启动你的activity在activity的生命周期中是一个非常重要的过程.这样可以确保你的用户感觉到你的应用一直都活着而且没有丢失进度.你的activity的停止和重新启动时有几个重 ...
- 学习安卓开发[2] - 在Activity中托管Fragment
目录 在上一篇学习安卓开发[1]-程序结构.Activity生命周期及页面通信中,学习了Activity的一些基础应用,基于这些知识,可以构建一些简单的APP了,但这还远远不够,本节会学习如何使用Ac ...
- .Net程序员快速学习安卓开发-布局和点击事件的写法
关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 本系列课程 致力于老手程序员可以快速入门学习安卓开发.系统全面的从一个.Net程序员的角度一步步学习总结安 ...
- 程序员带你学习安卓开发-XML文档的创建与解析
这是程序员带你学习安卓开发系列教程.本文章致力于面向对象程序员可以快速学习开发安卓技术. 上篇文章:程序员带你学习安卓开发系列-Android文件存储 因知识连贯性推荐关注头条号:做全栈攻城狮.从头开 ...
- 程序员带你学习安卓开发系列-Android文件存储
这是程序员带你学习安卓开发系列教程.本文章致力于面向对象程序员可以快速学习开发安卓技术. 上篇文章:.Net程序员快速学习安卓开发-布局和点击事件的写法 主要讲解了布局和点击事件的写法. 上篇文章补充 ...
- 程序员带你学习安卓开发,十天快速入-对比C#学习java语法
关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...
- Android学习整理之Activity生命周期篇
一.Activity生命周期说明 Activity的四种状态: ⒈活动状态(Active or Running):也称为运行状态,处于Activity栈顶,在用户界面中最上层,完全能被用户看到,能 ...
随机推荐
- 树的简介及Java实现
一.树的基本知识 树是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合.把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的.它具有以下的特点:每个结 ...
- 使用RSA加密在Python中逆向shell
i春秋翻译小组-Neo(李皓伟) 使用RSA加密在Python中逆向shell 这是一个关于使用RSA加密编程逆向shell的python教程. 我想提一下,这篇文章更多的是关于理解shell中涉及的 ...
- [Swift]LeetCode42. 接雨水 | Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- [Swift]LeetCode342. 4的幂 | Power of Four
Given an integer (signed 32 bits), write a function to check whether it is a power of 4. Example 1: ...
- [Swift]LeetCode977. 有序数组的平方 | Squares of a Sorted Array
Given an array of integers A sorted in non-decreasing order, return an array of the squares of each ...
- 如何在 Linux 上复制文件/文件夹到远程系统?
从一个服务器复制文件到另一个服务器,或者从本地到远程复制是 Linux 管理员的日常任务之一. 我觉得不会有人不同意,因为无论在哪里这都是你的日常操作之一.有很多办法都能处理这个任务,我们试着加以概括 ...
- 并发编程(七)——AbstractQueuedSynchronizer 之 CountDownLatch、CyclicBarrier、Semaphore 源码分析
这篇,我们的关注点是 AQS 最后的部分,共享模式的使用.本文先用 CountDownLatch 将共享模式说清楚,然后顺着把其他 AQS 相关的类 CyclicBarrier.Semaphore 的 ...
- 纽约工作日志流水账 Day 1
周六早上8:00从青岛登机,历经17个小时,终于在当地时间周六下午2点半到达目的地纽约. 被媳妇吐槽旁边坐了美女妹子,其实是个美国妹子,旁边人家还有男朋友,全程只和我说了2句话,Exc ...
- mysql 架构篇系列 4 复制架构一主一从搭建(半同步复制)
一.概述 在mysql 5.5之前,mysql 的复制是异步操作,主库和从库的数据之间存在一定的延时,这样存在一个隐患:当主库上写入一个事务并提交成功,而从库尚未得到主库推送的Binlog日志时,主库 ...
- C#版[击败100.00%的提交] - Leetcode 6. Z字形变换 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...