首页 Android正文

Android四大组件之Activity详解

yuange Android 2018-12-27 880 0 四大组件

目录

Activity生命周期

Activity的交互

Activity横竖屏切换

Activity的启动方式

Activity之间的数据交换

Activity的启动模式

Intent Flag启动模式

清空任务栈

监听Anctivity生命周期

Activity之Recreate

 


一、Activity生命周期


OnCreate  创建Activity时调用 销毁以前只执行一次

OnStart   打开Activity时调用

OnResume  唤醒Activity时调用

OnPaused  暂停Activity时调用

OnStopped 停止Activity时调用

OnDestroy 销毁Activity时调用


 20180104150230363.png


 


在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方法来销毁它。


 


流程图


20180104152056890.png

三、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而不会去等待返回。



20180104150330387.png


 


七、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();

    }

 


评论

在线客服-可直接交谈

您好!有什么需要可以为您服务吗?