"Activity"-安卓面试必问技能点大总结"

Activity


1.什么是Activity?

  • 1.四大组件之一
  • 2.通常一个界面对应一个activity
  • 3.是Context的子类
  • 4.同时实现window.callback和keyevent.callback回调,可处理与窗体用户的交互事件
  • 5.常见的类型有:FragmentActivity,ListActivity,TabActivity
  • 6.开发过程中,我们碰到多个界面有共同点或者功能,就自定义一个BaseActivity

2.请描述Activity的生命周期

相对应关系

  • 1.创建到可见过程:

    onCreate->onStart->onResume(获焦)

  • 2.可见到销毁过程

    (失焦)onPasu->onStop->onDestroy

  • 3.还有一个Restart

    当界面来到onStop,然后没有销毁的时候,调用onRestart那么就会来到onStart了.


3.Activity的状态都有哪些?

联想到进程级别,然后至少了个服务而已

  • foreground activity
  • visible activity
  • background activity
  • empty activity

4.如何保存Activity状态?

  • 内存充足时:

    切换了活动窗口 执行onPause,onStop后的activiy**仍然在内存中**,activiy的所有信息和状态数据不会消失,当activiy有后台变回到前台后,所有的数据又得到保留和显示.

  • 内存不足时:

    切换窗口执行onPause,onStop后的activity**可能被销毁**,此时就不会有activity对象了,当这个activiy回到前台的时候,之前的操作都消失了.

  • 避免消失的方法:

    重写“保存实例状态”的方法,onSaveInstanceState();房子onPause和onStop之前.

  • 横竖屏切换时保持当前播放进度:

        //控件
        private VideoView videoView;  
        //路径
        private static final String VIDEO_PATH = Environment  
            .getExternalStorageDirectory()  
            + File.separator  
            + "mymovie"  
            + File.separator + "shenghuaweiji.mp4"; 

        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);   

            if (videoView == null) {  
                videoView = (VideoView) this.findViewById(R.id.myvideo);  
                //前期设置,控制器,路径,请求
                MediaController controller = new MediaController(this);  
                videoView.setMediaController(controller);  
                videoView.setVideoPath(VIDEO_PATH);  
                videoView.requestFocus();  
            }  
            //判断如果有保存了内容,并且保存了进度,当做bundle获取
            if (savedInstanceState != null  
                    && savedInstanceState.getInt("currentposition") != 0) {  
                //那么就跳到那个位置即可
                videoView.seekTo(savedInstanceState.getInt("currentposition"));  
            } 
            //开始播放. 
            videoView.start();  
        }
        //覆写保存状态方法. 
        @Override  
        protected void onSaveInstanceState(Bundle outState) {  
            //这里通过给定的Bunde,往里保存信息,即获取当前位置进度.
            outState.putInt("currentposition", videoView.getCurrentPosition());  
            Log.v("tag", "onSaveInstanceState");  
            super.onSaveInstanceState(outState);  
        }  

5.两个Activity之间的跳转会执行哪些方法?

写两个Activity:A->B

  • 打开A,控制台显示如下:

    A-onCreate

    A-onStart

    A-onResume

  • 点击跳转到B界面,控制台显示内容增加如下

    A-onPause,A先失焦,但还不立即不可见,A不可见显示在最后.

    B-onCreate

    B-onStart

    B-onResume

  • 然后因为B此时可见,所以现在才到并不可见,注意A并不销毁,除非定义finish

    A-onStop

  • 拓展,如果再点击返回键

    那么B将是: onPause

    然后A:onStart onResume ,A显示了,B才不可见

    最后才到B: onStop onDestoy,销毁了,此时相当于finish里,因为标准的stand模式.


6.横竖屏切换时的Activity生命周期

跟是否已经配置了清单文件有关系

  • 没配置:那么将会是完完整整的来一遍生命周期:

    A onCreate

    A onStart

    A onResume

    A onPause

    A onStop

    A onDestroy

    A onCreate

    A onStart

    A onResume

  • 设置“对应的”Activiy中配置(注意是对应,不要写在前面的android:否则不起效)
        <activity android:name=".MainActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            >
  • 最好里面写了键盘|方向|屏幕尺寸,三个都写,否则有的机型可能不认.

  • 加上之后如果此时重写onConfigurationChanged方法,那么就会只是调用该方法,而不再重写生命周期

    A  onCreate
    A  onStart
    A  onResume
    A onConfigurationChanged
    A onConfigurationChanged
    
  • 拓展:

    保持横屏或者竖屏的方法:
    对应的Activiy中配置:android:screenOrientation=”landscape”(横屏,portrait是竖屏);


7.如何讲一个Activity设置成窗口样式?

首先这个ActiviyXX是要继承Acitivity,如果是继承其他Activity是报错的.

简单实现的话一句代码即可:

            <activity android:name=".MainActivityB"
             android:theme="@android:style/Theme.Dialog"/>

启动第二个界面的效果图:
这里写图片描述
如果想自定义样式的话(比如圆角,色彩等等):

  • 1.在res/value下创建style.xml文件(设置样式名字,且父类必须是Theme.Dialog)
        <style name="Theme.FloatActivity" parent="android:style/Theme.Dialog">  
        <!-- float_box为我们定义的窗口背景 ,这个不是必须的-->  
        <item name="android:windowBackground">@drawable/float_box</item>  
        </style>  
  • 2.在res/drawable文件夹里创建一个窗口的显示碎片参数(填充颜色圆角距离等)
        <?xml version="1.0" encoding="utf-8"?>  
        <shape xmlns:android="http://schemas.android.com/apk/res/android">  
            <solid android:color="#ffffff" />  
            <stroke android:width="3dp" android:color="#ff000000" />  
            <corners android:radius="3dp" />  
            <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />  
        </shape>  
  • 3.3.在AndroidMainifest.xml中要想变成窗口的Activity的声明中加入我们的主题姓名
        android:theme="@style/Theme.FloatActivity"  

显示效果
这里写图片描述


8.如何退出Activity?如何安全退出已调用多个Activity的Application?

  • 1.用户退出的时候,摁个返回键就是退出
  • 2.写代码的时候如果想退出:加上finish()即可;
  • 多个的时候:

    我建立了4个窗口

    每个窗口的onCreate方法都要调用工具方法的addActivity(this);

    窗口A

    显示窗口A,并有个跳转到B窗口的按钮
    

    窗口B

    显示B,有跳到C的按钮
    

    窗口C

    显示C,有跳到D的按钮
    

    窗口D

    显示D,有跳到A的按钮,而且还有个关闭所有页面的按钮(关键:调用集合的exit方法)
    

    我的关闭所有窗口的工具类:

    用单例定义一个工具类,那么该类只能是第一次的时候创建,里面的成员变量(集合)也是唯一的,详细代码如下:

        //工具类设置成单例模式,那么只会在第一次创建的时候有一个对象,以后在调用还是这个对象,所以里面的集合也是只有一个.
        class ExitAllActivity {
            private        List<Activity>  activityList = new LinkedList();
            private static ExitAllActivity instance     = new ExitAllActivity();

            private ExitAllActivity() {
            }
            // 单例模式中获取唯一的实例
            public static ExitAllActivity getInstance() {
                return instance;
            }
            //添加Activity到容器中
            public void addActivity(Activity activity) {
                activityList.add(activity);
                Log.d("ExitAllActivity", "add---------------------"+activity + "");
            }
            // 遍历所有Activity并finish
            public void exit() {
                for (Activity activity : activityList) {
                    //逐个finish
                    activity.finish();
                    Log.d("ExitAllActivity", "*********************all finish");

                }
            }
        }

9.请描述Activity的启动模式有几种,以及各自的特点

这个启动模式我专门写了一篇详细的介绍,大家请点击我访问专题,因为这个模式是非常重要的,面试或者开发过程中都能对大家有极大的帮助.

点击访问


举例: 有A(为测试对象),B两个页面,两个页面都有跳至对方的按钮

  • 标准模式(standard),请点击以上链接访问


  • 单个顶部模式(singleTop),请点击以上链接访问


  • 单个任务模式(singleTask),请点击以上链接访问


  • 单个实例模式(singleInstance),请点击以上链接访问.


10.一个启动模式为singleTop的activity,如果再试图启动会怎么样?

  • 讲解:

    该题目准确的讲应该这样问,如果一个启动模式为Top的活动,想再次获取新的意图值怎么办?

    答:重写onNewInten**t(Intent intent),并在里面写setIntent(intent)**即可.

  • 举例:

    • 如果另个都为默认,那么都正常传值,但是”如果我们用SinleXX来控制某个界面,比如“共享的界面”

    • 1.两个界面A(top模式),B为正常

    • 2.都有跳至对方的按钮(里边带startActivity)(没写finish)
    • 3.A跳到B就把”A->B”字符串传过去,反之亦然,跳自己就是”A->A”,然后在里边的获取焦点的时候弹吐司表示得到了值.
    • 4.初始化进来的时候A是 onCreate,onStart,onResume,弹了空吐司
    • 5.再次点击A:吐司是空的,并未出现A->A,但是执行了onNewIntent(),因为此时在栈顶top了
    • 6.此时跳到B,然后再跳回A,此时A因为不在顶部,所以谈新的A,执行:create,start,resume
    • 7.此时再点A,发现吐司**竟然还是上次的B->A!!!而不是A->A,说明 数据并没有传过来
    • 8.解决方法,让A收到信息,A->A也能收到,而且要求是singlexx模式的话就要用到:重写onNewInten,并写setIntent(intent)即可

    (PS:onSinglestance也是如此)

  • 再来看更直观的:

    • 如果大家改成“singleTask”单一任务就更简单明了
    • 初次进来空吐司,点A空吐司
    • 跳到B,然后再跳到A,空吐司
    • A自己跳到A,还是空吐司.证明了值没传过来.
    • 那么就要通过刚才的方法来解决.
  • 该方法什么时候用:

    (前提:ActivityA已启动)

    • 当ActivityA的LaunchMode为SingleTop时,如果ActivityA在栈顶,且现在要再启动ActivityA,这时会调用onNewIntent()方法

    • 当ActivityA的LaunchMode为SingleInstance,SingleTask时,如果已经ActivityA**已经在堆栈**中,那么此时会调用onNewIntent()方法

    • 为Standard时,由于每次启动ActivityA都是启动新的实例,和原来启动的没关系,所以不会调用原来ActivityA的onNewIntent方法**

  • 总结:

    • 如果遇到一个应用的Activity供多种方式调用启动的情况,多个调用希望只有一个Activity的实例存在,这就需要Activity的onNewIntent(Intent intent)方法了。
    • 只要在Activity中加入自己的onNewIntent(intent)的实现加上Manifest中对Activity设置lanuchMode=“singleTask”就可以。

    • onNewIntent()非常好用,Activity第一启动的时候执行onCreate()—->onStart()—->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent(). 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()—->onResart()——>onStart()—–>onResume(). 如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()—->onStart()—->onResume()等。

    • 当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值