基础总结之一:Activity

来源:互联网 发布:数控切割套料软件 编辑:程序博客网 时间:2024/06/07 09:56
(不断补充中。。。大家看看Activity还有啥没说的,留言啊~)
面试的同学看看我这个总结应该不错,嘿嘿~
1.Activity生命周期图谱

2. onSaveInstanceState和onRestoreInstanceState
onSaveInstanceState调用时机:
1)用户按下Home键回到桌面 或者 长按Home键切换其他应用
2)按下电源按键,关闭屏幕显示时。
3)从Activity A启动到一个新的Activity时
4)屏幕切换时,会调用当前Activity的该方法
onRestoreInstanceState调用时机:
一般是跟onSaveInstanceState成对,但是例如按下Home键又回来了,Activity中途没有被销毁,回来后不会调用该函数。
总之,系统未经许可,销毁了你的Activity时,onSaveInstanceState会被系统调用

3. 屏幕切换
1)转屏的生命周期:onCreate -> onStart -> onResume -> Running 转屏 ->onPause ->onSaveInstanceState ->onStop ->onDestroy ->onCreate -> onStart -> onRestoreInstanceState ->onResume
2)强制屏幕横或竖:android:screenOrientation=“protrait/landscape”
3)可以在layout-landlayout-port2个文件夹中定义横屏和竖屏2个布局文件,然后系统选择加载。也可以代码中获取横竖屏方向:getResources().getConfiguration().orientation,然后自己选择不同的布局文件。
4)在AndroidManifest.xml中设置android:configChanges="orientation|keyboardHidden|screenSize",这样Activity就不会重建,只会调用下Activity和View类的onCofigurationChanged()。
5)不设置Activity的android:configChanges时,竖屏切横屏会调用生命周期一次,横屏切竖屏时,会调用2次。
只设置configChanges="orientation"时,无论怎么切,都只调用生命周期一次。
设置android:configChanges="orientation|keyboardHidden|screenSize"(4.0以前不用screenSize)。不会调用生命周期,只会调用onConfigurationChanged()。
6)布局中的每一个View默认实现了onSaveInstanceState()方法,这样的话,这个UI的任何改变都会自动的存储和在activity重新创建的时候自动的恢复。但是这种情况只有在你为这个UI提供了唯一的ID之后才起作用,如果没有提供ID,将不会存储它的状态。

4.活动的启动模式
1)四个模式:
standard:默认模式;
singleTop:如果singleTop在栈顶,当前Activity生命周期:onPause-》onNewIntent-》onResume
singleTask:离开的时候onPause->onSaveInstanceState->onStop 再次回来后:onNewIntent->onRestart->onStart->onResume
singleInstance:离开的时候onPause->onSaveInstanceState->onStop 再次回来后:onNewIntent->onRestart->onStart->onResume
在<activity>标签中配置android:launchMode
应用场景(应该很多面试都会问):
singleTop:适合接受通知启动的内容显示页面。例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。
singleTask:适合作为程序的入口点。例如浏览器的主界面,不管从多少个应用启动浏览器,只会启动主界面一次,其余都走onNewIntent,并且会清空主界面上面的其他页面。
singleInstance:适合需要与程序分离开的页面。不常用。例如闹铃提醒,将闹铃提醒与闹铃设置分离开。
2)2中方式设置启动模式:《activity》标签中的android:launchMode属性;设置Intent的Flag标签。下面是常用Flag标签:
FLAG_ACTIVITY_NEW_TASK:创建一个新Task,然后把Activity放进去,每次都会重新创建一个新的Task,跟singleInstance类似。该Flag通常用来从Service中启动Activity(由于Service中并不存在Activity栈,所以需要使用该Flag创建一个Task然后存放启动的Activity)
FLAG_ACTIVITY_CLEAR_TOP:与SingleTask类似
FLAG_ACTIVITY_SINGLE_TOP:与singleTop模式类似
FLAG_ACTIVITY_NO_HISTORY:效果就是,如果AActivity启动了BActivity后,AActivity就会从Task中移除消失掉。

5.<activity>标签androird:windowSoftInputMode
设置的时候通常格式:"stateXXX | adjustXXX"
常用组合:"stateHidden|adjustResize" 和 "stateHidden|adjustPan"
可选值:(state即表示键盘状态;adjust即表示调整布局)
stateUnspecified:默认设置。未指定键盘的状态,系统将自动选择一个合适的状态 或 依赖主题中的设置。
stateUnchanged:不改变,保持上一个activity的键盘状态
stateHidden:键盘影藏
stateAlwaysHidden:即使该Activity获取到了焦点,键盘也影藏(跟上一个区别?)
stateVisible:进入该页面,键盘强制显示
stateAlwaysVisible:键盘总是显示,区别是从前一个页面回退到当前页面后,也强制显示出来,而上面的属性如果回退前的那个页面未显示,回退后也不会
adjustUnspecified:默认值。如果有可滚动控件(如ScrollView),系统知识减小滚动区域大小。如果没有,软件盘会遮挡部分内容,而且如果输入控件偏下,键盘会把布局顶上去
adjustResize:Activity的主窗口总是会调整大小,保证键盘显示出来。特色是如果控件偏下,键盘不会把整体布局顶上去(在使用时布局会被软键盘顶上去,体验非常不好
adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分(在使用时获取焦点的控件下边的View将会被软键盘覆盖)
6.Activity切换动画
activity切换动画的几种方式:
1)调用overridePendingTransition() ,api2.0开始就可以用。
2)theme主题中设置android:windowAnimationStyle下的四个属性:
activityOpenEnterAnimation
activityOpenExitAnimation
activityCloseEnterAnimation
activityCloseExitAnimation
3)从5.0开始,通过ActivityOptions可以实现更符合MD风格的动画(此外,这种方式可以实现两个Activity组件之间的过度动画)
7.Activity之间传递数据
1)通过Intent
2)广播
3)使用全局的东西来存储,例如:Application类中存全局数据;全局的一个静态类存全局数据;保存在网络、本地数据库、文件、sharedpreference
8.从一个应用启动另一个应用
1)利用ComponentName启动,代码:
    ComponentName component = new ComponentName("目标应用包名","目标应用的全路径Activity");<span style="white-space:pre"></span>Intent intent = new Intent(); intent.setComponent(component);<span style="white-space:pre"></span>startActivity(intent);
2)利用Action去匹配,来启动目标Activity
startActivity(new Intent("action字符串"));
9.双击退出应用
可以通过记录时间差的方式,或者延迟的方式。
1)记录时间差
    private static long INTERVAL = 2000L;   //两次双击的间隔时间    private long lastBackPress = 0L;        //上次点击回退按钮的时间    private Toast mToast;    @Override    public void onBackPressed() {        long currentTime = System.currentTimeMillis();        if (currentTime - lastBackPress <= INTERVAL) {            if (mToast != null) {//如果退出应用,需要及时关闭Toast提示                mToast.cancel();            }            finish();        } else {            lastBackPress = currentTime;            mToast = Toast.makeText(this, "双击退出", Toast.LENGTH_SHORT);            mToast.show();        }    }
2)延迟
    private boolean mIsExit;    @Override    /** * 双击返回键退出 */    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK) {            if (mIsExit) {                this.finish();            } else {                Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show();                mIsExit = true;                new Handler().postDelayed(                        new Runnable() {                            @Override                            public void run() {                                mIsExit = false;                            }                        }, 2000);            }            return true;        }        return super.onKeyDown(keyCode, event);    }

10.onKeyDown和onBackPressed区别
1)onKeyDown:该方法是老方法,兼容1.0到2.1,是常规方法。他监听的Back键方式:
@Override<span style="white-space:pre"></span>public boolean onKeyDown(int keyCode, KeyEvent event){<span style="white-space:pre"></span>if( keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 ){<span style="white-space:pre"></span>//按下的如果是BACK,同时没有重复。<span style="white-space:pre"></span>XXXXX //业务逻辑<span style="white-space:pre"></span>return true;//返回true,这个事件老子消耗掉了<span style="white-space:pre"></span>}<span style="white-space:pre"></span>return super.onKeyDown(keyCode, event);<span style="white-space:pre"></span>}
2)onBackPressed:从2.0开始出现的新方法,直接单独获取Back键按下事件。
11.隐式启动某个Activity : action、category、data
(详细的可以看这位大神的:http://blog.csdn.net/iispring/article/details/48481793 下面只是简单黏贴大神说的常用情况)
启动Activity分为:显式Intent启动,和隐式Intent启动。
隐式Intent需要分别通过intent-filteraction、category、data三个标签的测试才能算通过匹配。下面分别说下匹配规则:
1)action匹配
intent对象可以通过setAction()方法设置唯一的一个action值,或者不设置
intent-filter中可以声明其支持0个或多个action(握草,intent最多设置一个,这货随意加)
  • intent对象设置了action :只有当组件的intent-filter中包含了intent对象中的action值的时候,action测试才通过(我设置了action,肯定要找一个含有相同action的intent-filter)
  • intent对象没设置action:如果intent-filter至少有一个任意的action的值,该intent对象就可以通过该intent-filter的action测试,反之,如果intent-filter中没有定义任何的action,那么该intent无法通过该intent-filter的action测试(可以理解:Intent没有action,就随便找一个设置了action的intent-filter嫁了算了,如果你连action都没有,see you~世界就是这么现实)
2)category匹配
intent对象的addCategory()方法可以添加0个到多个category,但如果Intent是传递到startActivity() 或 startActivityForResult()中,系统会默认给传递的隐式Intent添加android.intent.category.DEFAULT,所以最终intent至少还有一个category
intent-filter中可以声明其支持0个或多个category。
(可以理解:category其实就是目录嘛,每一个潜在意图可以属于一个乃至多个目录,就像一个红色的苹果,用苹果和红色2个属性分类就可以描述清楚这个是一个红色的苹果,恩,没错~)
  • Intent对象含有一个乃至多个category:
intent-filter中必须要包含这N个category,intent对象才能通过category测试(如果是activity,考虑android.intent.category.DEFAULT哦。整个可以理解为:这个苹果的所有属性都能在过滤器中找到,恩,才可以放进这个过滤器的篮子里)
  • Intent没有添加category:
其实如果是寻找activity,那么默认会有DEFAULT目录,否则没有。如果这些全考虑完,Intent的category还是为空,那么他可以通过任何的category匹配(理解:空集合是任何集合的子集,恩~~)。如果Intent没有category,但是是放到startActivityXXX()的,默认会有DEFAULT目录,那还是回到了第一种情况。
3)data匹配
这个通常不用,就不黏贴了。



0 0
原创粉丝点击