Activity
什么是 activity?
- 一种重要的组件,为用户提供一个可交互的窗口
一个 app 中若干 activity 之间是紧密耦合在一起的吗?
- 不是,各 activity 之间是松散连接的
其中一个被作为 main activity,用于启动 app
一个新启动的 activity 是保留在哪里?
- Back栈的栈顶
当一个 Activity 启动的时候,该 Activity 会被推至Back栈的栈顶,并呈现给用户
前一个停止的 Activity 不会销毁,会保留到Back栈中
什么是生命周期?
- activity 从创建到销毁的过程 称为 Activity 的生命周期
每当 Activity 进入某个生命周期,相应的回调方法会被调用
在一个 activity 中必须实现的是哪个回调方法?
- onCreate 回调方法
如何把一个布局文件应用到一个 activity?
- onCreate > setContentView
例如 布局文件 activity_main.xml
setContentView(R.layout.activity_main);
一个定义好的 activity 还应该在哪个文件中声明一下?不声明会怎么样?
- 清单文件 AndroidManifest.xml
- 系统会看不到该 activity
无法在系统中存取这个 activity
在 manifest 文件中为什么要配置一下 intent 过滤器?
- 声明其他 app 组件是如何激活该 activity 的
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
//该过滤器声明本 activity 对 "main" 动作进行响应,并处于 "launcher" 这个类别中
//<action>元素指定该 activity 是 app 的主入口点,<category>元素指定该 activity 放在系统的"应用"中
是通过什么对 activity 启动的?
- 通过 Intent
调用 startActivity() 方法启动,并传相应的 Intent 参数
(这是用来从一个 Activity 启动另一个 Activity 的,分为显式和隐式.)
调用 startActivityForResult() 方法启动,可以从启动的 Activity 获得结果
可以通过哪个方法来关闭一个 activity?
finish()
或finishActivity(int requestCode)
不过不建议这样关闭,因为 Activity 有自己的生命周期
启动另一个Activity
什么是回调方法?
- 当系统中发生某种事件时,由系统调用的方法
如何创建第二个 activity?
- File > New > Activity > EmptyActivity
或者项目里右击 > New > Activity > EmptyActivity
怎么设置按钮的单击回调方法?该方法在哪里定义?该方法有哪些形式上的要求?
- 在相应的 MainActivity.java 中添加方法 如 sendMessage
- 为了匹配 android:onClick 属性值,该方法必须满足:
1.是 public
2.返回值为 void
3.有且仅有一个 View 作为参数
android 中 activity 的启动都是通过什么启动的?
- Intent
intent 构造方法中的两个参数什么含义?
- 1.上下文环境
2.系统发送Intent的目标,为某应用组件的Class,也就是被启动的组件的类名
Intent intent = new Intent(this, SignInActivity.class);
//从 this 启动 SignInActivity
快速引入类的快捷键是什么?
- Alt + Enter
如何取出输入到 EditText 中的文本数据?取出的数据类型是什么?
- getText 返回数据类型 CharSequence
EditText editText = (EditText) findViewById(R.id.editText);
String message = editText.getText().toString();
什么是键值对?
- 一键对应一值,键不可重复
如何给 intent 附加需要传递的数据?
- putExtra 方法,传入键值对
intent.putExtra(EXTRA_MESSAGE, message);
如何快速定义一个已使用的常量?
- 红色提示小灯泡里 Create constant field …
如何启动第二个 activity?
- 用 Intent ,分显式和隐式
例:显式
Intent intent = new Intent(this, SignInActivity.class);
//从 this 启动 SignInActivity
startActivity(intent);
如何在第二个被启动的 activity 中获取启动它的 intent 对象?
Intent intent = getIntent();
怎么取出第一个 activity 传递过来的数据?如何再显示在屏幕上?
- 用 getStringExtra 取出 putExtra 传递的数据
Extra 的意思是 额外 的数据
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = findViewById(R.id.textView);
textView.setText(message);
Activity 的生命周期
一个 activity 的生命周期中有几种状态?哪几种是稳定状态?这几种稳定状态下,用户可以同它们交互吗?每种状态之间的切换需要调用哪些回调方法?哪些回调方法是比较关键的方法?
- 六种 Created(创建) Started(启动) Resumed(运行) Paused(暂停) Stopped(停止) Destoryed(销毁)
- Resumed、Paused、Stopped
- Resumed 状态下可以,这个状态也称 Running 状态
- onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy()
启动 activity 到 resumed 稳定状态会经过几个回调方法?
- 3个,
onCreate() 执行结束后,系统立刻调用 onStart() 和 onResume() 方法,
你的 Activity 不会停留在 Created 和 Started 状态
activity 从 resumed 状态到 Destroyed 状态会经过几个回调方法?
- 3个,onPause()、onStop()、onDestroy()
在进入暂停状态时会执行哪个回调方法?在该方法中会做哪些操作?为什么需要做这些操作?
- onPause
- 向存储设备写入至关重要的持久性数据(例如用户编辑)
- 如果系统在紧急情况下必须恢复内存,则可能不会调用 onStop() 和 onDestroy()
从暂停状态回到 resumed 状态,会执行哪个回调方法,在该方法中会做哪些操作?
- onResume
- 这里你应该初始化那些你在onPause()中释放的组件,以及其它每次进入Resumed状态都应该初始化的(比如开始动画等)
在 activity 从 resumed 状态到 stopped 状态的时候,需要执行哪些回调方法?在onStop 中执行的操作同在 onPause 方法中有什么区别?
- onPause、onStop
- 使用 onStop() 来执行需要更耗费CPU的操作,诸如向数据库写数据
在从 stopped 状态回到 resumed 状态时,恢复资源的操作最好在哪个回调方法中做?为什么?
- onRestoreInstanceState()
- 另外一个是恢复操作在onCreate,而 onStop 后接 onRestart、onDestory
什么情况下,你的 activity 可能被销毁?在销毁前在哪个回调方法中可以保存 activity 的状态?在重建 activity 的时候会执行哪个回调方法并恢复 activity 的状态?
- 被调用 finish 方法,或系统为节省空间而暂时销毁
- onSaveInstanceState()
static final String STATE_SCORE = "playerScore";
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// 保存用户当前的游戏状态
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
// 总是首先调用父类中的onSaveInstanceState方法
super.onSaveInstanceState(savedInstanceState);
}
- onRestoreInstanceState() 和 onCreate()
前者是在 onStart 方法后被调用
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// 从保存实例中恢复状态变量值
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // 总是首先调用父类中的 onCreate 方法
// 检查我们是否是在重建以前销毁的本 Activity的实例
if (savedInstanceState != null) {
// 从保存的状态中恢复成员的值
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
} else {
// 新实例中的变量可能需要用默认值进行初始化
}
}
Activity 的四种 LaunchMode
activity 有几种启动模式?它配置在哪个标签的哪个属性中?
- 4种,
standard
:不管有没有已存在的实例,都生成新的实例(activity 可以被多次实例化)singleTop
:若有对应的 activity 实例正位于当前栈顶,系统会直接使用,不再生成新的实例singleTask
:系统创建一个新的 task 并且实例化 activity 为该 task 的根
若另一个 task 中已有该 activity 的实例,则使此 Activity 实例之上的其他 Activity 实例统统出栈,使此 Activity 实例成为栈顶对象,显示到屏幕前(不创建新的 task)singleInstance
:这种模式限定同一个 task 只能有一个 activity,(别的都和 singleTask 相同)
<activity android:name=".AnotherPick" android:launchMode="standard">
standard 模式怎么启动 activity?同一个 task 栈可以有几个相同 activity 的实例?
- 直接启动
- 多个
singleTop 模式启动的 activity 在同一个 task 栈中可以有几个相同 activity 的实例?栈顶可以有几个相同 activity 的实例?
- 很多,在间隔不同 Activity 的情况下
- 一个
singleTask 模式启动的 activity 在同一个 task 栈中可以有几个相同的 activity 的实例?该实例能在栈的哪个位置?
- 一个
- 栈顶,若不在栈顶,启动时会将其上的 Activity 统统出栈
singleInstance 模式启动的 activity 所在的 task 栈中可以有几个相同的 activity 的实例?在同一个 task 栈中还可以有其他 activity 的实例吗?
- 一个
- 不可以
Intent 和 Intent 过滤器
intent是什么?需要被启动 activity 返回结果的启动是哪个方法?不需要返回结果的是哪个方法?intent主要用在哪些场景?
- 一个消息传递对象
- startActivityForResult()
- startActivity()
- 三个场景
启动 Activity,启动服务,传递广播
显式意图同隐式意图的主要区别在哪里?同这两种不同的意图,系统是如何启动被启动的组件的?
- 显式 Intent:按名称(完全限定类名)指定要启动的组件
隐式 Intent :没有组件名称,而是声明要执行的操作,从而允许其他应用中的组件来处理它 - 创建显式 Intent 启动 Activity 或服务时,
系统将立即启动 Intent 对象中指定的应用组件
创建隐式 Intent 时,
Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,从而找到要启动的相应组件
保存在 intent 中的主要信息有哪些?什么是 action?action 在代码中和在 manifest 中的意图过滤器中的表述有何不同?action 必须是系统定义好的吗?自己可以定义 action 吗?
- 组件名称、操作、数据、类别;Extra、标志
- 操作
- 代码中可以是类常量,在清单的过滤器中只能是文本字符串值
- 可以自己定义 action
什么是URI?设置URI和设置MIME分别用什么方法?如果同时设置URI及MIME呢?
- URI (uniform resource identifier) 统一资源标识符,用来唯一的标识一个资源
- setData,setType
- setDataAndType
在 Intent 中附加信息,可以怎么做(两种方式)?
- putExtra 添加 键值
- 还可以创建一个包含所有 extra 数据的 Bundle 对象,然后使用 putExtras() 将Bundle 插入 Intent 中
当使用隐式意图进行 activity 的启动的时候,如果没有哪个 activity 能够对相应意图进行响应的时候,我们的代码应该怎么处理?
// 验证是否有activity处理该Intent
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}
通常app选择器是什么时候打开的?如何强制打开app选择器?
- 有多个组件能够响应隐式 Intent 时
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog 创建选择器
Intent chooser = Intent.createChooser(sendIntent, title);
// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
如何使得一个组件能够响应某类 action?一个组件能不能处理多种 intent?怎么做?同一个意图过滤器中可以有哪几种标签?每种标签可以有几个?
- 在 manifest 中添加过滤器 intent-filter
- 能
- 添加标签,测试过滤
- 三种,action、data、category
- 一个或多个
表达某个 activity 为主 activity 的意图过滤器怎么定义?
- ACTION_MAIN 和 CATEGORY_LAUNCHER 配对使用
activity 就会显示在启动器中,点开启动器图标即打开
系统是如何匹配隐式意图的?
- 当系统收到隐式 Intent 以启动 Activity 时,它根据 Action、Data、Category 三个方面将该 Intent 与 Intent 过滤器进行比较,搜索该 Intent 的最佳 Activity
与其他应用交互
分别在同一个 app 中的 activity 中相互切换和调用其他 app 中的 activity 的时候,分别采用什么样的 intent?
- 同一个app中一般采用 显示Intent,调用其他app的 activity 时必须采用隐式 Intent
如何验证系统中有没有相应的 activity 来响应 intent?
PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(intent, 0); //0处:PackageManager.MATCH_DEFAULT_ONLY
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe) {
startActivity(intent);
}
如何强行打开 app 选择器?
Intent intent = new Intent(Intent.ACTION_SEND);
// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show chooser
Intent chooser = Intent.createChooser(intent, title);
// Verify the intent will resolve to at least one activity
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
对于需要返回结果的启动 activity 用哪个启动方法?有了返回结果,调用 activity 怎么接收返回结果
- startForResult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
TextView textView = (TextView)findViewById(R.id.ma_tv_phoneNumber);
textView.setText(data.getDataString());
}
}
}
为什么在 activity 的 manifest 文件中加入 intent-filter 元素?
- 过滤器,为了更准确的匹配指定操作的 Intent
如何从 activity 中返回结果?
- 关键是调用 setResult 方法返回一个 含有返回结果的 intent
例如,返回 EditText 中的电话号码
public void returnTOMain(View view) {
EditText editText = (EditText)findViewById(R.id.ap_et_inputPhoneNumber);
String phoneNumber = editText.getText().toString();
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse(phoneNumber));
setResult(Activity.RESULT_OK, result);
finish();
}
End.