Android UI相关知识

来源:互联网 发布:js实现二级菜单导航 编辑:程序博客网 时间:2024/06/11 21:03

一 Activity

1请描述 下Activity 命周期。

答:onCreate() //activity 命周期开始时被调 。

onRestoreInstanceState() //onCreate完成后被调 , 来恢复UI状态。onRestart() //activity从停 状态重新启动时调 。
onStart() //activity对 户即将可 的时候调 。
onResume() //activity与 户交互的时候,重绘屏幕。
onSaveInstanceState() //activity即将移出栈顶保UI状态时调 此 法。onPause() //当系统要启动 个其他的activity时调 (其他的activity显示之前),

onStop() // 户 再可 时调
onDestroy //activity被销毁前所调 的最后 个 法,当进程终 时会调  

2 横竖屏切换时activity的 命周期 

设置Activityandroid:configChanges时,切屏会重新调 各个 命周期,切横屏时会执一次,

切竖屏时会执 两次。设置Activityandroid:configChanges="orientation"时,切横,竖屏时 命周期只会执一次。设置Activityandroid:configChanges="orientation|keyboardHidden"时,切屏 会重新调 声明周期,只会执 onConfigurationChanged 法。 

3  如果四种LaunchMode及其使用场景

standard 模式

这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中。使用场景:大多数Activity。
singleTop 模式
如果在任务的栈顶正好存在该Activity的实例,就重用该实例( 会调用实例的 onNewIntent() ),否则就会创建新的实例并放入栈顶,即使栈中已经存在该Activity的实例,只要不在栈顶,都会创建新的实例。使用场景如新闻类或者阅读类App的内容页面。
singleTask 模式
如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的 onNewIntent() )。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。使用场景如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。
singleInstance 模式
在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。使用场景如闹铃提醒,将闹铃提醒与闹铃设置分离。singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) -> C,完全退出后,在此启动,首先打开的是B。

4 如果后台的Activity由于某原因被系统回收 ,如何在被系统回收之前保存当前状态?

当你的程序中某 个Activity A在运 时中,主动或被动地运 另 个新的Activity B这个时候A会执

Java代码
public void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

outState.putLong("id", 1234567890);}

B 完成以后 会来找A,这个时候就有两种情况, 种是A被回收, 种是没有被回收,被回收的A就要重新调onCreate() 法, 同于直接启动的是这回onCreate() 是带上参数savedInstanceState,没被收回的就还是onResume就好 。savedInstanceState是 个Bundle对象,你基本上可以把他 解为系统帮你维护的 个Map对象。在onCreate() 你可能会 到它,如果正常启动onCreate就 会有它,所以 的时候要判断 下是否为空。

Java代码if(savedInstanceState != null){

long id = savedInstanceState.getLong("id");}

Activity缓存 法。ab两个Activity,当从ab之后 段时间,可能系统会把a回收,这时候按back,执 的 是a

onRestartonCreate 法,a被重新创建 次,这是a中的临时数据和状态可能就丢失 。

可以 Activity中的onSaveInstanceState()回调 法保存临时数据和状态,这个 法 定会在活动被回收之前调 。 法中有 个Bundle参数,putString()putInt()等 法需要传 两个参数, 个键 个值。数据保存之后会在onCreate中恢复,onCreate也有 个Bundle类型的参数。

示 代码:

@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

//这 ,当Acivity第 次被创建的时候为空//所以我们需要判断 下

if( savedInstanceState != null ){savedInstanceState.getString("anAnt");

}}

@Override
protected void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

outState.putString("anAnt","Android");}

onSaveInstanceState (Bundle outState)当某个activity变得被系统销毁时,该activityonSaveInstanceState就会被执 ,除 该

activity是被 户主动销毁的, 如当 户按BACK键的时候。

注意上 的双引号,何为? 下之意就是该activity还没有被销毁, 仅仅是 种可能性。这种可能性有哪些?通过重写 个activity的所有 命周期的onXXX 法,包括onSaveInstanceStateonRestoreInstanceState 法,我们可以清楚地知道当某个activity(假定为activity A)显示在当前task的最上层时,其onSaveInstanceState 法会在 么时候被执 ,有这么 种情况:

1、当 户按下HOME键时。

这是显 的,系统 知道你按下HOME后要运 多少其他的程序, 然也 知道activity A是否会被销毁,故系统会调onSaveInstanceState,让 户有机会保存某些 永久性的数据。以下 种情况的分析都遵循该原则

2、 按HOME键,选择运 其他的程序时。3、按下电源按键(关闭屏幕显示)时。4、从activity A中启动 个新的activity时。

5、屏幕 向切换时, 如从竖屏切换到横屏时。(如果 指定configchange属性) 在屏幕切换之前,系统会销毁activity A,在屏幕切换之后系统 会 动地创建activity A,所以onSaveInstanceState 定会被执

总 之,onSaveInstanceState的调 遵循 个重要原则,即当系统未经你许可时销毁 你的activity,则onSaveInstanceState会被系统调 ,这是系统的责任,因为它必须要提供 个机会让你保存你的数据(当然你 保存那就随 你 )。另外,需要注意的 点:

1.布局中的每 个View默认实现onSaveInstanceState() 法,这样的话,这个UI的任何改变都会 动地存储和在activity重新创建的时候 动地恢复。但是这种情况只有在你为这个UI提供 唯 的ID之后才起作 ,如果没有提供ID,app将 会存储它的状态。

2.由于默认的onSaveInstanceState() 法的实现帮助UI存储它的状态,所以如果你需要覆盖这个 法去存储额外的状态信息,你应该在执 任何代码之前都调 类的onSaveInstanceState() 法(super.onSaveInstanceState())。 既然有现成的可 ,那么我们到底还要 要 实现onSaveInstanceState()?这得看情况 ,如果你 的派 类中有变 影响到UI,或你程序的 为,当然就要把这个变 也保存 ,那么就需要 实现,否则就 需要。

3.由于onSaveInstanceState() 法调 的 确定性,你应该只使 这个 法去记录activity的瞬间状态(UI的状态)。 应该 这个 法去存储持久化数据。当 户离开这个activity的时候应该在onPause() 法中存储持久化数据( 如应该被存储到数据库中的数据)。

4.onSaveInstanceState()如果被调 ,这个 法会在onStop()前被触发,但系统并 保证是否在onPause()之前或者之后触发。

onRestoreInstanceState (Bundle outState)

onRestoreInstanceState 法,需要注意的是,onSaveInstanceState 法和onRestoreInstanceState是成对的被调 的,(本 注:我昨晚调试时就发现原来 定成对被调 的!)

onRestoreInstanceState被调 的前提是,activity A“确实被系统销毁 , 如果仅仅是停 在有这种可能性的情况下,则该 法 会被调 , 如,当正在显示activity A的时候, 户按下HOME键回到主界 ,然后 户紧接着 返回到activity A,这种情况下activity A 般 会因为内存的原因被系统销毁,故activity AonRestoreInstanceState 法 会被执

另外,onRestoreInstanceStatebundle参数也会传递到onCreate 法中,你也可以选择在onCreate 法中做数据还原。 还有onRestoreInstanceStateonstart之后执 。 于这两个函数的使 ,给出示范代码( 意 定义代码在调 super的前或后):

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

savedInstanceState.putBoolean("MyBoolean", true);savedInstanceState.putDouble("myDouble", 1.9);savedInstanceState.putInt("MyInt", 1);savedInstanceState.putString("MyString", "Welcome back to Android");// etc.

super.onSaveInstanceState(savedInstanceState);}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {

super.onRestoreInstanceState(savedInstanceState);

boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");double myDouble = savedInstanceState.getDouble("myDouble");
int myInt = savedInstanceState.getInt("MyInt");
String myString = savedInstanceState.getString("MyString");

理解Activity,View,Window三者关系



这个问题真的很不好回答。所以这里先来个算是比较恰当的比喻来形容下它们的关系吧。Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图)LayoutInflater像剪刀,Xml配置像窗花图纸。
1:Activity构造的时候会初始化一个Window,准确的说是PhoneWindow。
2:这个PhoneWindow有一个“ViewRoot”,这个“ViewRoot”是一个View或者说ViewGroup,是最初始的根视图。
3:“ViewRoot”通过addView方法来一个个的添加View。比如TextView,Button等
4:这些View的事件监听,是由WindowManagerService来接受消息,并且回调Activity函数。比如onClickListener,onKeyDown等。


二 Fragment

1 android fragmentactivity的区别

可以 解Fragment是 种特殊的View,负责 个模块或者 个特殊部分的展示。 部分Fragment是依托于Activity存在的,由ActivityFragmentManager来管

Fragment可以解决多Activity的问题,即将3.0之前的频繁Activity跳转改成 个ActivityFragment的切换。
Fragment可以解决碎 化的问题。

2 fragment 命周期
onAttach, onCreate, onCreateView, onViewCreated, onActivityCreated, onStart, onResume,

onPause, onStop, onDestroyView, onDestroy, onDetach.

3 Fragment使
1 继承 个fragment类,实现onCreateView

2 xml中定义fragment标签,在ac中使 这个xml。或者通过FragmentManager提供 对Activity运 时的Fragment的添加、删除、替换的操作。如果要执 添加、删除、修改的操作,你必须通过FragmentManager的对象获得 个FragmentTransaction对象。在Activity中你可以通过getFragmentManager()来获得Fragment对象,然后通过FragmentManager对象的beginFragmentTransaction() 法来获得FragmentTransaction对象。通过它的add() 法来添加 个Fragment到当前的Activity中。 个FragmentTransaction对象可以执 多个增删修的 法,如果你想把这些修改提交到Activity上,必须在最后调 下这个对象的commit()

4、与其他Fragment的交互两个单独的Fragment之间是 应该进 通信的。应该使 他们所存在的Activity作为沟通的纽带。 

xml与资源

1布局

五种布局: FrameLayoutLinearLayoutAbsoluteLayoutRelativeLayoutTableLayout全都继承ViewGroup,各 特点及绘制效率对 。

FrameLayout(框架布局)

此布局是五种布局中最简单的布局,Android中并没有对child view的摆布进 控制,这个布局中所有的控件都会默认出现在视图的左上 ,我们可以使android:layout_margin,android:layout_gravity等属性去控制 控件相对布局的位置。

LinearLayout(线性布局) (或 )只控制 个控件的线性布局,所以当有很多控件需要在 个界 中 出时,可以

LinearLayout布局。 此布局有 个需要格外注意的属性:android:orientation=“horizontal|vertical

android:orientation="horizontal时,说明你希望将 平 向的布局交给LinearLayout*,其 元素的android:layout_gravity="right|left"等控制 平 向的gravity值都是被忽 的,此时LinearLayout中的 元素都是默认的按照 平从左向右来排*,我们可以android:layout_gravity="top|bottom"gravity值来控制垂直展示。

反之,可以知道 当android:orientation="vertical时,LinearLayout对其 元素展示上的的处 式。

AbsoluteLayout(绝对布局)可以放置多个控件,并且可以 定义控件的x,y位置RelativeLayout(相对布局)

这个布局也是相对 由的布局,Android对该布局的child view的 平layout&垂直layout做 解析,由此我们可以FrameLayout的基础上使 标签或者Java代码对垂直 向 以及 平 向 布局中的views进 任意的控制.

相关属性:

android:layout_centerInParent="true|false"android:layout_centerHorizontal="true|false"android:layout_alignParentRight="true|false"

TableLayout(表格布局)将 元素的位置分配到 或 中, 个TableLayout由许多的TableRow组成

2 .Manifest.xml 件中主要包括哪些信息?manifest:根节点,描述package中所有的内容。

uses-permission: 定义权限。
permission: 声明 安全许可来限制哪些程序能你package中的组件和功能。instrumentation:声明 来测试此package或其他package指令组件的代码。application:包含packageapplication级别组件声明的根节点。activity:Activity是 来与 户交互的主要 具。receiver:IntentReceiver能使的application获得数据的改变或者发 的操作,即使它当前 在运 。service:Service是能在后台运 任意时间的组件。 provider:ContentProvider是 来管 持久化数据并发布给其他应 程序使 的组件。

3 android:gravityandroid:layout_gravity的区别

LinearLayout有两个 常相似的属性:android:gravityandroid:layout_gravity。他们的区别在 于:android:gravity 于设置View组件的对 式, android:layout_gravity 于设置Container组件
的 对 式。举个 ,我们可以通过设置
android:gravity="center"来让EditText中的 字在EditText组件中居中显示;同 时我们设置EditTextandroid:layout_gravity="right"来让EditText组件在LinearLayout中居右显示。 




0 0
原创粉丝点击