zhengzxj的专栏

1.对activity的理解 什么是activity:1.四大组件之一,一般的,一个用户交互界面对应一个activity2.显示布局 setContextView() button.setOnclickListener等等3.是Context的子类,实现了window.callback和keyevent.callback,能处理窗口和按键的用户交互事件4.如果多个activity界面有相同特点或功能 可以自己顶一个BaseActivity做父类 让子类去实现 生命周期: activity从创建(new出来)到死亡(垃圾回收)的过程中最多会执行7个不同的方法完整生命周期 onCreate onStart onPause onResume onStop onDestroy可视生命周期 onStart onPause onResume onStop 视频播放器 不可见后记录播放点 停止播放 可见后 读取进度 继续播放前台生命周期 onPause onResume 游戏暂停onRestart 当stop而没destroy时,重新可见,调用这个方法注:activity还有两个方法 onPostResume() 和 OnPostCreate()这两个生命周期的方法,不过开发的时候没有用到过,应该是框架调用的; AB两个activity跳转会调用哪些生命周期的方法在A创建B的时候,A先失去焦点,然后创建B,B可见,获取B焦点,A不可见,(如果B透明或者是窗口,A就继续可见)Apause Bcreate start resume Astop(A_do_nothing) 横竖屏切换的时候 Activity会从运行中销毁 让后重新创建 整个过程调用如下方法pause stop destroy create start resume 所以某些实时性比较高的场景下存在数据丢失的问题解决方案有二:1.写死横竖方向 清单中加入 orientation属性 写定是横的还是竖的2.不写死 清单加入 configChanged属性 忽略横竖屏转换,键盘弹出和窗体大小 如何将一个Activity设置成窗口的样式android:theme="@android:style/Theme.Dialog" activity被回收了 如何保持实时数据在内存不足的时候除了栈顶的activity之外,越靠栈底的activity越容易被回收我们可以复写onSaveInstanceState方法,将数据以键值对的方式存入Bandle对象当重新加载的时候用键去Bandle里取值但是,不常用,因为在一些断电,或者一些突发情况下,虚拟机直接停止的话,这个方法就没用了所以一般我们在做播放器或者数据实时保存要求比较高的模块的时候 最好新建一个线程 没隔几秒去记录一下数据(可以覆盖) 如何安全退出多层actiity1.利用Application,存放所有activity的实例,在最后一个退出的时候遍历集合调用finish方法2.发送特定广播:发送特定广播,每个activity收到以后关闭即可;3.递归关闭:在打开新的Activity时使用startActivityForResult,,然后自己加标志,在onActivityResult中处理,递归关闭。(setResult)4.抛异常强制退出:使程序Force Close。需要处理不弹出Force close窗口;2.service是否在main thread中执行, service里面是否能执行耗时的操作不能,要在子线程中执行耗时操作还有一种解决方案,让service运行在另外一个进程中(在清单文件中配置process属性)这种做法一般用在单进程分配的堆内存可能不够用,容易造成OOM异常的情况下会考虑使用;3.两个Activity之间怎么传递数据?a.数据放到第一个类的Bandle中去 Bandle放到Intent中去 然后startActivityForResult第二个类中把数据放到Intent中 然后setResult就可以了记得发送加上请求码,返回结果加上返回码;第一个类中复写,回调方法onActivityResult方法 要核对请求码和返回码请求码:当第一个类发送了两条以上的数据到两个不同的地方,使用多个请求码,这是就能分辨当前回调的数据是作用于那次请求返回码:可能第一个类一次请求中,需要多个返回数据,这时第二个类使用返回码,就能让第一个类区分自己需要的结果;b.调用Application的实例,所有activity共享数据,但是生命周期作用于整个应用程序,所以使用后立马释放;(尽量少用);c.序列化对象 然后存入到本地文件;1.需要存储的对象的类去实现Serializable2.new一个本地File文件对象,放入FileOutputStream中3.整个再放入ObjectOutputStream中 调用这个流的writeObject把目标对象写入到本地文件中去4.读取文件ObjectInputStream(参数是本地文件的FileInputStream流对象)实例对象调用readObject方法d.文件/网络:大图片的传递intent.setData(Uri);Uri.fromFile();task就好像是能包含很多activity的栈. 默认情况下,一个activity启动另外一个activity时,两个activity是放在同一个task栈中的,第二个activity压入第一个 activity所在的task栈.当用户按下返回键时,第二个activity从栈中弹出,第一个activity又在当前屏幕显示.这样,从用户角度来看,这两个activity就好像是属于同一个应用程序的,即使第二个activity是属于另外一个应用程序的.当然,这是指默认情况下. task栈包含的是activity的对象.如果一个activity有多个实例在运行,那么栈中保存的是每个实例的实体.栈中的activity不会重新排列,只有弹出和压入操作. 一个task中的所有activity都以整体的形式移动.整个task可以被移到前台或后台.打个比方,当前的task包含4个activity–当前 activity下面有3个activity.当用户按下HOME键返回到程序启动器(application launcher)后,选择了一个新的应用程序(事实上是一个新的task),当前的task就被转移到后台,新的task中的根activity将被显示在屏幕上.过了一段时间,用户按返回键回到了程序启动器界面,选择了之前运行的程序(之前的task).那个task,仍然包含着4个 activity.当用户再次按下返回键时,屏幕不会显示之前留下的那个activity(之前的task的根activity),而显示当前 activity从task栈中移出后栈顶的那个activity. 刚刚描述的行为是默认的activity和task的行为.有很多方法能够改变这种行为.activity和task之间的联系,以及task中的 activity的行为可以通过intent中的标记以及在manifest中的<activity>元素的属性控制.其中,主要的Intent标记有:4.怎么让在启动一个Activity是就启动一个service?在activity的onCreate()方法里面 startService();5.同一个程序,但不同的Activity是否可以放在不同的Task任务栈中?可以的,答案见下一题,6.activity的加载模式(任务栈)原栈中:standard(默认):创建新实例添加到原task中去;singleTop(Task顶单例):同上,比standard牛的就是顶部复用;singleTask(Task内单例):在同一个Task内只有一个实例.a.不存在或者在栈顶的时候都和singleTask一样;b.存在非栈顶:会把所有它之上的其他activity实例移除,从而浮到栈顶;新栈中:singleInstance(全局单例):创建单实例,放到新栈中;a.不存在:建新栈,建单实例放入栈中;b.存在:无论该activity存在于哪里,该task都会被调到前台显示;(此时该activity所在的task我们理解为新栈)注1:一个task中的所有activity都以整体的形式移动.整个task可以被移到前台或后台.注2:按下HOME键返回到程序启动器 = application launchertask就好像是能包含很多activity的栈. 默认情况下,一个activity启动另外一个activity时,两个activity是放在同一个task栈中的,第二个activity压入第一个 activity所在的task栈.当用户按下返回键时,第二个activity从栈中弹出,第一个activity又在当前屏幕显示.这样,从用户角度来看,这两个activity就好像是属于同一个应用程序的,即使第二个activity是属于另外一个应用程序的.当然,这是指默认情况下. task栈包含的是activity的对象.如果一个activity有多个实例在运行,那么栈中保存的是每个实例的实体.栈中的activity不会重新排列,只有弹出和压入操作. 一个task中的所有activity都以整体的形式移动.整个task可以被移到前台或后台.打个比方,当前的task包含4个activity–当前 activity下面有3个activity.当用户按下HOME键返回到程序启动器(application launcher)后,选择了一个新的应用程序(事实上是一个新的task),当前的task就被转移到后台,新的task中的根activity将被显示在屏幕上.过了一段时间,用户按返回键回到了程序启动器界面,选择了之前运行的程序(之前的task).那个task,仍然包含着4个 activity.当用户再次按下返回键时,屏幕不会显示之前留下的那个activity(之前的task的根activity),而显示当前 activity从task栈中移出后栈顶的那个activity. 刚刚描述的行为是默认的activity和task的行为.有很多方法能够改变这种行为.activity和task之间的联系,以及task中的 activity的行为可以通过intent中的标记以及在manifest中的<activity>元素的属性控制.其中,主要的Intent标记有:FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_RESET_TASK_IF_NEEDED FLAG_ACTIVITY_SINGLE_TOP主要的<activity>属性有: taskAffinity launchMode allowTaskReparentingclearTaskOnLaunch alwaysRetainTaskState finishOnTaskLaunch默认情况下,一个应用程序中的所有activity都有一个affinity–这让它们属性同一个task.然而,每个activity可以通过<activity>中的taskAffinity属性设置单独的affinity.不同应用程序中的activity可以共享同一个 affinity,同一个应用程序中的不同activity也可以设置成不同的affinity.affinity属性决定了:启动activity的 Intent对象需包含FLAG_ACTIVITY_NEW_TASK标记,activity的allowTaskReparenting被认为是设置成 true.FLAG_ACTIVITY_NEW_TASK标记当传递给startActivity()的Intent对象包含 FLAG_ACTIVITY_NEW_TASK标记时,系统会为需要启动的activity寻找与当前activity不同的task.如果要启动的 activity的affinity属性与当前所有的task的affinity属性都不相同,系统会新建一个带那个affinity属性的task,并将要启动的activity压到新建的task栈中;否则将activity压入那个affinity属性相同的栈中.allowTaskReparenting属性如果一个activity的allowTaskReparenting属性为true,那么它可以从一个task(TASK1)移到另外一个有相同affinity的task(TASK2)中(TASK2带到前台时).如果一个.apk文件从用户角度来看包含了多个“应用程序”,你可能需要对那些activity赋不同的affinity值.

累死累活不说,走马观花反而少了真实体验,

zhengzxj的专栏

相关文章:

你感兴趣的文章:

标签云: