文章目录
先说一下什么时Activity吧,简单一句话,凡是你在应用中看得到的东西都是放在活动中的(其实有点牵强的,不过无伤大雅)。
activity的简单介绍
Activity是Android系统提供的一个系统活动基类,我们项目中所有的活动都要继承它
public class HelloWordActivity extends Activity{
@Override
protected void onCtreate(Bundle saveInstanceState){
setContentView(R.layout.hello_word_layout);
}
@Override
public boolen onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.hello_word,menu);
return true;
}
}
manifest注册
<applicaiton>
<activity android:name=".ActivityMain"
android:label="this is applicaiton">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</applicaiton>
- activity要卸载application中
- 主activity一定要加入上卖弄intent filter 不然启动不了
返回栈和启动模式
Android使用Task来管理activity,一个task就是存放在栈里面的activity集合,这个栈也称作返回栈(Back Stack)。在默认情况下每当我们启动了一个新的activity,它会在返回栈中入栈,并处于栈顶的位置,而每当我们按下Back键或调用finish()方法去销毁一个活动,之前入栈的就被推到栈顶了。就像在羽毛球从桶里面拿出来一样。有一个博客图画的非常好看,启动模式讲的也很清楚,以下内容搬运自该博客(http://www.cnblogs.com/codingWarrior/p/4894722.html ),如侵害作者权益,请联系我删除。
任何activity类都要manifest文件中注册,其中有一项属性就是设置启动模式(lunchMode)。默认为standard
<activity
android:launchMode="singleTask">
</activity>
standard
5.0之前:
新的activity会被压入task 栈的栈顶。
跨应用的访问activity在5.0之前也都是在同一个在东一个栈
可以看见名字是老activity的,但是内容是新activity的
5.0之后:
对于跨应用的activity终于符合逻辑了,跨应用的activity会被塞进一个新的Task,在新模式下,如果从standard lauchmode 打开相册软件,再从相册打开standard lauchmode,会出现下面这种情况,如果你一直点的话,早晚内存会满的。
singleTop
singleTop其实和standard几乎一样,使用singleTop的Activity也可以创建很多个实例。唯一不同的就是, 如果调用的目标Activity已经位于调用者的Task的栈顶,则不创建新实例,而是使用当前的这个Activity实例,并调用这个实例的onNewIntent方法 。
- 只有在调用者和目标Activity在同一Task中,并且目标Activity位于栈顶,才使用现有目标Activity实例,否则创建新的目标Activity实例。
- 如果是外部程序启动singleTop的Activity,在Android 5.0之前新创建的Activity会位于调用者的Task中,5.0及以后会放入新的Task中。
singleTask
如果系统中不存在singleTask Activity的实例,那么就需要创建这个Activity的实例,并且将这个实例放入和调用者相同的Task中并位于栈顶。
如果singleTask Activity实例已然存在,那么在Activity回退栈中,所有位于该Activity上面的Activity实例都将被销毁掉(销毁过程会调用Activity生命周期回调),这样使得singleTask Activity实例位于栈顶。与此同时,Intent会通过onNewIntent传递到这个SingleTask Activity实例。
然而在Google关于singleTask的 文档 有这样一段描述
The system creates a new task and instantiates the activity at the root of the new task.
意思为 系统会创建一个新的Task,并创建Activity实例放入这个新的Task的底部。
然而实际并非如此,在我的例子中,singleTask Activity并创建并放入了调用者所在的Task,而不是放入新的Task,使用 adb shell dumpsys activity 便可以进行验证。
然而想要实现文档的描述也并非不可能,我们需要在设置launchMode为singleTask的同时,再加上taskAffinity属性即可。
<activity
android:launchMode="singleTask"
android:taskAffinity="">
</activity>
完成上面的修改,我们看一下效果,Task的变化如下图
同时,系统中的任务管理器效果也会相应变化
singleInstance
Activity活动状态
-
运行状态
栈顶的活动处于运行状态 -
暂停状态
当一个活动不再栈顶的时候,但仍然可以看见的时候(只会占用部分屏幕时),程序就会进入暂停状态当一个活动不再栈顶的时候,但仍然可以看见的时候(只会占用部分屏幕时),程序就会进入暂停状态 -
停止状态
不在栈顶,且完全不可见时,就会进入停止状态 -
销毁状态
返回栈中移除后就会变成销毁状态
Activity中的函数
我们手机上的操作会直观的反应在activity中各个onxxx函数的调用
onCreate()
这个方法在活动的第一次创建时候调用,你应该在这个方法中对活动进行初始化,如布局和绑定事件。如果处于暂停状态的活动被回收了,你在按back键的就会调用onCreate()函数,临时的数据也就会丢失.这个函数有一个Bundle类型的参数就是之前的数据。
onStart()
在活动由不看见变为可见的时候调用
onResume()
这个方法在活动准备好和用户交互时候调用,此时活动一定位于返回栈的栈顶,且处于运行状态
onPause()
这个方法在系统准备去启动或恢复另一个活动的时候调用,我们通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法一定要快,不然会影响到新的栈顶活动
onStop()
这个方法在活动完全不可见的时候调用。它和onPause方法区别于,如果启动的新活动是一个对话框式的活动,那么onPause()会执行,而onStop()不会执行
onDestroy()
这个方法在活动销毁之前调用,之后活动状态将边变为销毁状态
onRestart()
这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重启了 。
onSaveInstanceState()
活动被回收之前被调用,可以用这个方法解决临时数据得不到保存的问题,这个方法有一个Bundle类型的参数,可以用putString(),putInt()…来保存数据,这些函数中第一个参数为键,第二个参数为值
@Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState();
String tempData="Something you just typed";
ouState.putString("data_key","tempData");
}
boolean onCreateOptionsMenu(Menu)
调用res下的菜单布局xml文件。return表示显示(true)不显示(false)
boolean onOptionItemSelected(MenuItem item)
点击菜单时调用
boolean onOptionItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_item:
Toast.makeText(this, "you click add", Toast.LENGTH.SHORT).show();
break;
case R.id.reamove_item:
Toast.makeText(this, "you click add", Toast.LENGTH.SHORT).show();
bresk;
default
;
} return true;
}
getMenuInflater().inflater()
getMenuInflater()获得MenuInflater对象
第一参数 菜单文件通过传入R中注册的菜单来生成菜单(R.menu.xxx.xml)
第二参数 添加到那个menu对象
setContentView()
加载布局,参数是一个布局id(R.layout.xxxxx)
requestWindwoFeature()
可以设置窗口特性比如隐藏标题栏(Window.FEATURE.NO_TITLE),但是一定要注意这个函数要在set’ContentView之前调用,不然会报错