Activity深入理解

目录

  • Activity生命周期
  • Activity的交互
  • Activity横竖屏切换
  • Activity的启动方式
  • Activity之间的数据交换
  • Activity的启动模式
  • Intent Flag启动模式
  • 清空任务栈
  • 监听Anctivity生命周期
  • Activity之Recreate

 

一、Activity生命周期


OnCreate  创建Activity时调用 销毁以前只执行一次
OnStart   打开Activity时调用
OnResume  唤醒Activity时调用
OnPaused  暂停Activity时调用
OnStopped 停止Activity时调用
OnDestroy 销毁Activity时调用

 

 

在Application中可以监听所有Activity的生命周期

registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            }

            @Override
            public void onActivityStarted(Activity activity) {
            }

            @Override
            public void onActivityResumed(Activity activity) {
            }

            @Override
            public void onActivityPaused(Activity activity) {  
            }

            @Override
            public void onActivityStopped(Activity activity) {
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
            }
        });

 

二、Activity的交互


当第一个Activity跳转到第二个Activity时,首先执行的是第一个Activity的OnPaused方法,然后执行第二个Activity的OnCreate、OnStart、OnResumed方法,等到第二个Activity完全加载完毕(可显示状态)以后才会执行第一个Activity的Onstopped方法,当然跳转过程不会使第一个Activity被销毁。

当从第二个Activity返回到第一个Activity时,首先执行的是第二个Activity的OnPaused方法,然后调用第一个Activity的OnRestart方法、OnStart方法、OnResumed方法,最后第一个Activity已经加载完毕(可显示状态),调用第二个Activity的OnStopped、OnDestroy方法来销毁它。

 

流程图

三、Activity横竖屏切换


Activity横竖屏切换时并不是直接实现了横屏效果,而是先销毁了原来的Activity,然后调用OnCreate、OnStart、OnResume方法来呈现一个新的Activity。

因为Activity在横竖屏切换时会重新创建Activity这样会使原本的Activity的进度发生改变(例如播放器),所以有些情况下我们需要通过OnSaveInstanceState(Bundle outState)这个方法来保存一些数据。

具体使用方法

在OnSaveInstanceState(Bundle outState)方法中保存数据,面以String为例。

 

@Override
public void onSaveInstanceState(Bundle outState)
{
        //一般用于保存当前状态信息
	super.OnSaveInstanceState(outState);
	outState.putString("key","value");
}

//我们看到OnCreate方法中有一个参数就是Bundle savedInstanceState
//所以我们在OnCreate中来获取保存数据.
if(savedInstanceState!=null)
{
   String str = savedInstanceState.getString("key");
}

注意:OnSaveInstanceState方法是在OnPause方法执行以后才开始执行的。
 

四、Activity的启动方式

 

一、 直接启动

1.方法一

 

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
StartActivity(intent);

2.方法二

 

Intent intent = new Intent();
ComponentName component = new ComponentName( MainActivity.this,SecondActivity.class);
intent.setComponent(component);
startActivity(intent);

 

二、 匿名启动

首先在Mainifest.xml文件中进行注册

<activity android:name=".SecondActivity">
	<intent-filter>
		<action android:name="test"/>
		<category android:name="android.intent.category.DEFAULT"/>
	</intent-filter>
</activity>

然后在代码中调用

Intent intent = new Intent();
intent.setAction("test");
startActivity(intent);

使用于Activity的class文件不是来自于代码,而是来自于第三方文件时。或者启动一个系统Activity时使用(系统Activity我们不用在Mainifest.xml中进行注册)。
注意:如果启动系统Activity需要设置一个Uri。

 

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.parse("http://www.baidu.com");
intent.setData(uri);
startActivity(intent);

五、Activity之间的数据交换

一、跳转时传递数据

(1)方法一

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("name","db");//以键值对的方式传递
StartActivity(intent);
在SecondActivity的代码中获取数据
Intent intent = getIntent();
if(intent!=null)
{
	String name = intent.getStringExtra("name");
}

(2)方法二

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name","db");
intent.putExtras(bundle);
StartActivity(intent);
//在SecondActivity的代码中获取数据和方法一相同

(3)当传递的类型比较多的时候,我们可以通过java类来传递

public class User implements Serializable{
	private String name;
	private int age;
	public User(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
}
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
User user = new User("db",20);
Bundle bundle = new Bundle();
bundle.putSerializable("User",user);
intent.putExtras(bundle);
StartActivity(intent);

在SecondActivity的代码中获取数据

Intent intent = getIntent();
if(intent!=null)
{
	User user = (User)intent.getSerializableExtra("User");
}

注意:Bundle传递数据时数据大小必须小于1M否则会抛出TransactionTooLargeException异常。

 

二、回传数据

这样我们需要一个回调方法来实现,当activity退出时,向上一个activity传递数据(MainActivity获取SecondActivity返回的数据)。

设置数据

Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("name","db");
intent.putExtras(bundle);
SecondActivity.this.setResult(-1,intent);

获取数据(系统提供了一个回调方法)

//接收选择器选中的结果:放在需要接受数据的activity中
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //在这里用switch判断requestCode或者resultCode的值
	//然后通过Bundle取出数据
 	Bundle bundle = data.getExtras();
 	String name = bundle.getString("name");
        }
    }


当我们需要回传数据时就不能使用startActivity(intent)来开启Activity了,需要使用startActivityForResult(intent,requestCode);//requestCode的值随意给不能重复。

 

六、Activity的启动模式


Activity的启动模式共四种:standard、singleTop、singleTask、singleInstance

设置启动模式(在Manifest的activity中添加以下代码)

 

android:launchMode="singleTask"

 

standard(标准模式)是系统的默认模式(可以不指定)。

singleTop(单栈顶模式)如果存在A-B-C三个Activity,启动D,则D会被创建形成A-B-C-D;如果是A-B-C-D,D是栈顶的情况下,再次启动D,则D不会被创建。

singleTask(单例模式)如果不存在D(Activity)则创建D,否则把D调到栈顶(不重新创建)。使用singleTask启动模式可以用来退出整个应用:将主Activity设为singleTask模式,然后在要退出的Activity中转到主Activity,从而将主Activity只上的Activity都清除,然后重写主Activity的OnNewIntent方法,在方法中添加finish(),将最后一个Activity结束掉。

singleInstance 与singleTask相似,不会重复创建Activity,但是该模式下创建Activity会被放到一个新的Task中。这种启动模式类似于浏览器,和浏览器的工作原理一致,singleInstance的Activity会出现在一个新的任务栈中,而且该任务栈只存在该Activity

 

注意:如果在singleTop或者singleInstance的Activity中通过startActivityForResult方法来启动另一个Activity则系统会直接返回Activity.RESULT_CANCELED而不会去等待返回。




 

七、Intent Flag启动模式

  • Intent.FLAG_ACTIVITY_NEW_TASK :这种启动模式启动的Activity都会被放入一个新的任务栈中,用于从Service启动Activity,因为Service和Activity并不在同一任务栈中
  • Intent.FLAG_ACTIVITY_SINGLE_TOP : 使用singleTop模式启动Activity
  • Intent.FLAG_CLEAR_TOP :使用singleTask模式来启动一个Activity
  • Intent.ACTIVITY_NO_HISTORY : 使用这种模式启动其他Activity后,该Activity就消失,将不会保留在Activity栈中。

 

八、清空任务栈

可以通过设置AndroidMainifest文件中<activity>标签的属性来实现

  • clearTaskOnLaunch :每次返回该Activity时,都将该Activity之上的所有Activity清楚掉。
  • finishOnTaskLaunch:作用于自己身上,当离开该Activity所处的Task,那么用户再返回时,该Activity就会被finish掉。
  • alwaysRetainTaskState :该Activity将不接受任何清除命令,一直保持在当前Task状态。

 

九、监听Anctivity生命周期

    在Application中对Activity的生命周期进行注册,其监听的是所有activity的生命周期

 /**
     * 在application中监听所有aictivity的生命周期
     */
    public void setRegisterActivityLifecycleCallbacks() {
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

            }

            @Override
            public void onActivityStarted(Activity activity) {

            }

            @Override
            public void onActivityResumed(Activity activity) {
                
            }

            @Override
            public void onActivityPaused(Activity activity) {
                
            }

            @Override
            public void onActivityStopped(Activity activity) {

            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });
    }

 

十、Activity之Recreate

我们可以通过Activity的recreate方法来重建Activity,recreate多走了两个个方法onSaveInstanceState(Bundle outState)和onRestoreInstanceState(),即通过Bundle来绑定之前的状态。如果你在Activity的onCreate方法中添加了Fragment,在Activity执行recreate方法时也会多次创建重复的Fragment这样也会造成内存泄漏,其结局办法为,在Recreate之前我们可以先remove掉之前已经包含的Fragment。

   @Override
    public void recreate() {
        try {//避免重启太快 恢复
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            for (Fragment fragment : fragmentAdapter.getFragmentsList()) {
                fragmentTransaction.remove(fragment);
            }
            fragmentTransaction.commitAllowingStateLoss();
        } catch (Exception e) {
        }
        super.recreate();
    }

 

 

 

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值