android Activity


先说一下什么时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活动状态

  1. 运行状态
    栈顶的活动处于运行状态

  2. 暂停状态
    当一个活动不再栈顶的时候,但仍然可以看见的时候(只会占用部分屏幕时),程序就会进入暂停状态当一个活动不再栈顶的时候,但仍然可以看见的时候(只会占用部分屏幕时),程序就会进入暂停状态

  3. 停止状态
    不在栈顶,且完全不可见时,就会进入停止状态

  4. 销毁状态
    返回栈中移除后就会变成销毁状态

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之前调用,不然会报错

启动activity

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值