项目里添加Activity
-
Activity
对应的 Java 文件 - AndroidManifest.xml
- 对应的界面 XML
- 界面 XML 用到的资源
Activity
及其派生类
继承图
简介
-
Activity:提供
Fragment
功能。 -
FragmentActivity:提供
Fragment
功能和ActionBar
功能。 -
AppCompatActivity:提供
ActionBar
功能。 - ActionBarActivity:deprecated
简单示例
AndroidManifest.xml
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
启动模式
-
standard
:- 默认模式,可以不用写配置。
- 在原任务栈中创建新
Activity
,不会创建新栈。 - 可以有多个相同或不同的
Activity
。
-
singleTop
:- 在原任务栈中创建新
Activity
,不会创建新栈。 - 可以有多个相同
Activity
。 - 如果
Activity
在任务栈顶的时候,启动与栈顶相同的Activity
时,不会创建新的Activity
,而会调用栈顶Activity
的onNewIntent()
。
- 在原任务栈中创建新
-
singleTask
:- 在原任务栈中创建新
Activity
,不会创建新栈。 - 启动新
Activity
时,若任务栈中已经存在相同的Activity
,就会销毁任务栈中这个Activity
之上的所有Activity
,并调用该Activity
的onNewIntent()
。
- 在原任务栈中创建新
-
singleInstance
:- 在新的任务栈中创建新的
Activity
。 - 在新任务栈中只能有这一个相同或不同的
Activity
。
- 在新的任务栈中创建新的
常见技巧
- 在
onCreate()
中检查savedInstanceState
是否为null
,若是则代表着Activity
是第一次加载,同样的技巧在Fragment
中也是可用的。 - 通过
getIntent()
来获取调用时传入的数据。
常用方法
通过重写使用
-
onActivityReenter()
:点击返回键时,重新进入父Activity
时调用,会接收到在子Activity
中调用setResult()
时传送的数据。 -
onActivityResult()
:在子Activity
中调用setResult()
,然后退出子Activity
时,父Activity
会接收到在setResult()
中设置的数据。 -
finishAfterTransition()
:在退场动画结束后执行finish()
,通过重写来决定在退场动画结束与调用finish()
之间需要做的东西。
直接调用
-
postponeEnterTransition()
:- 当通过
ActivityOptions.makeSceneTransitionAnimation()
启动Activity
时,延迟开始转场动画,直至调用startPostponedEnterTransition()
。 - 若没有通过
ActivityOptions.makeSceneTransitionAnimation()
启动Activity
,则此函数什么都不做。 - 在
onCreate()
或onActivityReenter()
中调用。
- 当通过
-
startPostponedEnterTransition()
:开始转场动画。
生命周期
- 打开
onCreate()
onStart()
onResume()
- 进入后台
onPause()
onStop()
- 进入前台
onRestart()
onStart()
onResume()
- 应用程序配置发生改变(横竖屏切换)
onPause()
onStop()
onDestrory()
onCreate()
onStart()
onResume()
- 退出
onPause()
onStop()
onDestrory()
横竖屏布局
通过创建默认方向layout
文件和横向layout
文件来实现。
保存Activity
数据
- 只能保存基本数据类型和实现
Serializable
或Parcelable
接口的对象。 - 应用配置改变时会调用
onSaveInstanceState()
。 -
保存:重写
onSaveInstanceState()
。@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(KEY_INDEX, mCurrentIndex); }
-
读取:在
onCreate()
中恢复数据if (savedInstanceState != null) { mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0); }
启动Activity
准备
- 被启动的活动必须具有的意图筛选器:
<category android:name="android.intent.category.DEFAULT"/>
方式一
startActivity(new Intent(".MainActivity"));
方式二
startActivity(new Intent(this, MainActivity.class));
Activity
通信
传入数据
- 调用的
Activity
Intent i = new Intent(this, CheatActivity.class); i.putExtra(/* data */); startActivity(i);
- 被调用的
Activity
mAnswerIsTrue = getIntent().getBooleanExtra(/* data */);
返回数据
- 启动
Activity
时,给Activity
一个请求标识符:startActivityForResult(i, REQUEST_CODE);
- 在被调用的
Activity
中设置结果,调用者会接受到此结果:Intent data = new Intent(); data.putExtra(/* data */); setResult(RESULT_OK, data);
- 被调用的
Activity
结束后会回调 调用者 的onActivityResult()
,数据会通过Intent
传回,可以根据请求标识符解析传回的Intent
:@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != Activity.RESULT_OK) { return; } if (requestCode == REQUEST_CODE) { if (data == null) { return; } // 解析数据 data.getBooleanExtra(/* data */); } }
封装newIntent()
静态方法
- 通过在被调用的
Activity
中封装newIntent()
静态方法,使得被调用的Activity
来决定如何被调用:public static Intent newIntent(Context packageContext, Data data) { Intent intent = new Intent(packageContext, MyActivity.class); intent.putExtra(ID, data); return intent; }
注意事项
- 相比与
onResume()
,onStart()
不一定会执行。 -
Activity
中的实例变量不可靠,生命期比Activity
长的实例变量应该尽量存在外部。 - 确保所有
Activity
都是AppCompatActivity
的子类,这样兼容性会很高。 - 后退按钮导航和层级导航(向上按钮导航)并不一样。层级导航是开始一个新的
Activity
,弹出回退栈里此Activity
以上的Activity
。后退按钮导航则是弹出回退栈里最顶层的Activity
。
Activity
的XML属性
<activity android:allowEmbedded=["true" | "false"]
android:allowTaskReparenting=["true" | "false"]
android:alwaysRetainTaskState=["true" | "false"]
android:autoRemoveFromRecents=["true" | "false"]
android:banner="drawable resource"
android:clearTaskOnLaunch=["true" | "false"]
android:configChanges=["mcc", "mnc", "locale",
"touchscreen", "keyboard", "keyboardHidden",
"navigation", "screenLayout", "fontScale",
"uiMode", "orientation", "screenSize",
"smallestScreenSize"]
android:documentLaunchMode=["intoExisting" | "always" |
"none" | "never"]
android:enabled=["true" | "false"]
android:excludeFromRecents=["true" | "false"]
android:exported=["true" | "false"]
android:finishOnTaskLaunch=["true" | "false"]
android:hardwareAccelerated=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:launchMode=["standard" | "singleTop" |
"singleTask" | "singleInstance"]
android:maxRecents="integer"
android:multiprocess=["true" | "false"]
android:name="string"
android:noHistory=["true" | "false"]
android:parentActivityName="string"
android:permission="string"
android:process="string"
android:relinquishTaskIdentity=["true" | "false"]
android:resizeableActivity=["true" | "false"]
android:screenOrientation=["unspecified" | "behind" |
"landscape" | "portrait" |
"reverseLandscape" | "reversePortrait" |
"sensorLandscape" | "sensorPortrait" |
"userLandscape" | "userPortrait" |
"sensor" | "fullSensor" | "nosensor" |
"user" | "fullUser" | "locked"]
android:stateNotNeeded=["true" | "false"]
android:supportsPictureInPicture=["true" | "false"]
android:taskAffinity="string"
android:theme="resource or theme"
android:uiOptions=["none" | "splitActionBarWhenNarrow"]
android:windowSoftInputMode=["stateUnspecified",
"stateUnchanged", "stateHidden",
"stateAlwaysHidden", "stateVisible",
"stateAlwaysVisible", "adjustUnspecified",
"adjustResize", "adjustPan"] >
</activity>