1 手工新建一个Activity
1.1 在String.xml中添加需要Activity需要的字符串
- 新的Activity的界面需要一些用到的字符串资源,手工在String.xml中添加
Cheat!
Show Answer
1.2 新建一个布局xml文件
- 在包资源管理中,选中res/layout文件夹,新建一个Layout XML File
- 需要注意的是,同时需要复制创建一份横屏的layout文件
竖屏layout
横屏layout
1.3 创建一个Activity的类
- 包资源管理器中,创建一个新class,继承android.app.Activity类
- 复写onCreate函数。函数的参数是android.os.Bundle类型的savedInstanceState对象。函数需要将第二步定义的layout文件载入。
@Overridepublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat);
}
1.4 AndroidManifest.xml文件中声明Activity
- 必须有android:name属性
- "."表示告知OS在AndroidManifest.xml文件的包属性值,指定的包路径下可以找到Activity类文件
2 两个Activity之间的通信
2.1 Intent负责在两个Activity之间传递信息
- Activity的启动和关闭,是通过Android操作系统的ActivityManager来进行管理的。Intent对象是负责Activity和ActivityManager通信的。
- 例如A界面要启动B界面,A先发送Intent对象给ActivityManager。接收到信息后,ActivityManager根据消息启动B界面。
- 即使是APP内部的Activity通信,也需要通过操作系统的ActivityManager进行。
- Intent构造函数如下,第一个参数Context对象是告诉ActivityManager在哪一个包可以找到Class对象。第二个参数指的是要通信对象的Class。
public Intent (Context packageContext, Class> cls)
具体的实例,通过startActivity(Intent)启动另外的Activity
Intent i = new Intent(QuizActivity.this, CheatActivity.class);
startActivity(i);
- Intent分显示和隐式。上面的例子是显示调用,隐式调用一般用于App之间的调用。
2.2 Activity间的发送和接受数据
- Intent对象传递数据是通过Extra数据类型传递,其结构是一种key-value结构
- 设置Extra值是用putExtra函数,第一个参数是key,第二个参数是value。下面这个例子的value类型是boolean,也可以是其他类型。
public Intent putExtra(String name, boolean value)
- 获取Extra值是用getXXExtra函数,其中XX指的是类型。函数有两个参数,第一个参数是key值,第二个参数指的是value的默认值。下面的例子是boolean类型
mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);
2.3 Activity间获取调用的返回结果
- A界面调用B界面,有时候再返回时需要获取B界面的结果
- 这种情况下,启动A界面启动B界面,需要使用startActivityForResult函数。第一个参数是Intent对象,第二个参数是请求代码。
请求代码的作用是,当启动多个Activity时,需要判断区分回馈消息时,需要用到请求代码。
public void startActivityForResult(Intent intent, int requestCode)
当不需要区分时,requestCode填写0即可。
startActivityForResult(i, 0);
- 返回结果有两种方法可以调用
public final void setResult(int resultCode)
public final void setResult(int resultCode, Intent data)
resultCod预定义有两种常量
Activity.RESULT_OK
Activity.RESULT_CANCELED
- 如果不调用setResult函数,用户点击返回键后,activity会收到Activity.RESULT_CANCELED的结果代码
- ActivityManager会调用onActivityResult函数,来处理setResult函数设置的返回结果
protect void onActivityResult(int requestCode, int resultCode, Intent data)
- 例子
A界面调用B界面,B界面返回值
B界面设置返回结果
private void setAnswerShownResult(boolean isAnswerShown) {
Intent data = new Intent();
data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown);
setResult(RESULT_OK, data);
}
A界面处理返回结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {
return;
}
mIsCheater = data.getBooleanExtra(CheatActivity.EXTRA_ANSWER_SHOWN, false);
}
3 Activity的使用和管理
3.1 默认启动的Activity
启动App其实是启动一个Activity。默认启动的Activiy在AndroidManifest.xml文件中定义了,被设置为launcher Activity。具体声明如下:
3.2 Activity间调用的log分析
- 启动App
启动了主界面
11-11 01:41:21.899 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onCreate called
11-11 01:41:21.939 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onStart called
11-11 01:41:21.941 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onResume called
- 调用第2个Activity
暂停主Activity -> 启动第2个Activity -> OpenGLRenderer: endAllActiveAnimators -> 保存主Activity数据 -> 停止主Activity
11-11 01:44:01.177 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onPause called
11-11 01:44:01.196 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onCreate called
11-11 01:44:01.211 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onStart called
11-11 01:44:01.215 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onResume called
11-11 01:44:01.314 4511-4644/geoquiz.android.bignerdranch.com.geoquiz D/OpenGLRenderer: endAllActiveAnimators on 0xa4058c00 (RippleDrawable) with handle 0x956994c0
11-11 01:44:01.644 4511-4511/geoquiz.android.bignerdranch.com.geoquiz I/QuizActivity: onSavedInstanceState
11-11 01:44:01.644 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onStop called
- 在第2个Activity按回退键
暂停第2个Activity -> 主Activity处理返回的结果(onActivityResult called) -> 重新启动主Activity -> 停止并销毁第2个Activity
11-11 01:49:23.463 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onPause called
11-11 01:49:23.469 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onActivityResult called
11-11 01:49:23.471 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onStart called
11-11 01:49:23.472 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onResume called
11-11 01:49:23.779 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onStop called
11-11 01:49:23.780 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onDestroy called
- 总结
从调用者到被调用者时,调用Activity没有销毁,只是暂停
被调用者返回调用者时,被调用的Activity则会被销毁
3.3 原理
- 实际上ActivityManager维护着一个Activity栈,所有的应用都在一个共享的Activity栈中。
- 当主Activity调用第2个Activity时,两个Activity都在栈中,而第2个Activity在栈顶。
- 当按回退键回退到主Activity时,第2个Activity被弹出栈外,被销毁;而主Activity则回到栈顶。