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

  • FrameLayout(框架布局)

    此布局是五中布局中最简单的布局,Android中并没有对child view的摆布进行控制,这个布局中所有的控件都会默认出现在视图的左上角,我们可以使用android:layout_marginandroid: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组成


Activity生命周期。

  • 启动Activity: onCreate()—>onStart()—>onResume(),Activity进入运行状态。

  • Activity退居后台: 当前Activity转到新的Activity界面或按Home键回到主屏: onPause()—>onStop(),进入停滞状态。

  • Activity返回前台: onRestart()—>onStart()—>onResume(),再次回到运行状态。

  • Activity退居后台,且系统内存不足, 系统会杀死这个后台状态的Activity(此时这个Activity引用仍然处在任务栈中,只是这个时候引用指向的对象已经为null),若再次回到这个Activity,则会走onCreate()–>onStart()—>onResume()(将重新走一次Activity的初始化生命周期)

  • 锁定屏与解锁屏幕 只会调用onPause(),而不会调用onStop()方法,开屏后则调用onResume()

  • 更多流程分支,请参照以下生命周期流程图 




通过Acitivty的xml标签来改变任务栈的默认行为

  • 使用android:launchMode="standard|singleInstance|singleTask|singleTop"来控制Acivity任务栈。

    任务栈是一种后进先出的结构。位于栈顶的Activity处于焦点状态,当按下back按钮的时候,栈内的Activity会一个一个的出栈,并且调用其onDestory()方法。如果栈内没有Activity,那么系统就会回收这个栈,每个APP默认只有一个栈,以APP的包名来命名.

    • standard : 标准模式,每次启动Activity都会创建一个新的Activity实例,并且将其压入任务栈栈顶,而不管这个Activity是否已经存在。Activity的启动三回调(onCreate()->onStart()->onResume())都会执行。

    • singleTop : 栈顶复用模式.这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,所以它的启动三回调就不会执行,同时Activity的onNewIntent()方法会被回调.如果Activity已经存在但是不在栈顶,那么作用于standard模式一样.

    • singleTask: 栈内复用模式.创建这样的Activity的时候,系统会先确认它所需任务栈已经创建,否则先创建任务栈.然后放入Activity,如果栈中已经有一个Activity实例,那么这个Activity就会被调到栈顶,onNewIntent(),并且singleTask会清理在当前Activity上面的所有Activity.(clear top)

    • singleInstance : 加强版的singleTask模式,这种模式的Activity只能单独位于一个任务栈内,由于栈内复用的特性,后续请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁了

Activity的堆栈管理以ActivityRecord为单位,所有的ActivityRecord都放在一个List里面.可以认为一个ActivityRecord就是一个Activity栈


Activity缓存方法。

有a、b两个Activity,当从a进入b之后一段时间,可能系统会把a回收,这时候按back,执行的不是a的onRestart而是onCreate方法,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变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。

注意上面的双引号,何为“容易”?言下之意就是该activity还没有被销毁,而仅仅是一种可能性。这种可能性有哪些?通过重写一个activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我们可以清楚地知道当某个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,将不会存储它的状态。

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 A的onRestoreInstanceState方法不会被执行

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

@Overridepublic 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);}@Overridepublic 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");}

为什么在Service中创建子线程而不是Activity中

这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。

Intent的使用方法,可以传递哪些数据类型。

通过查询Intent/Bundle的API文档,我们可以获知,Intent/Bundle支持传递基本类型的数据和基本类型的数组数据,以及String/CharSequence类型的数据和String/CharSequence类型的数组数据。而对于其它类型的数据貌似无能为力,其实不然,我们可以在Intent/Bundle的API中看到Intent/Bundle还可以传递Parcelable(包裹化,邮包)和Serializable(序列化)类型的数据,以及它们的数组/列表数据。

所以要让非基本类型和非String/CharSequence类型的数据通过Intent/Bundle来进行传输,我们就需要在数据类型中实现Parcelable接口或是Serializable接口。

http://blog.csdn.net/kkk0526/article/details/7214247

Fragment生命周期



注意和Activity的相比的区别,按照执行顺序

  • onAttach(),onDetach()

  • onCreateView(),onDestroyView()


Service的两种启动方法,有什么区别 1.在Context中通过public boolean bindService(Intent service,ServiceConnection conn,int flags) 方法来进行Service与Context的关联并启动,并且Service的生命周期依附于Context(不求同时同分同秒生!但求同时同分同秒屎!!)。

2.通过public ComponentName startService(Intent service)方法去启动一个Service,此时Service的生命周期与启动它的Context无关。

3.要注意的是,whatever,都需要在xml里注册你的Service,就像这样:

广播(Boardcast Receiver)的两种动态注册和静态注册有什么区别。

  • 静态注册:在AndroidManifest.xml文件中进行注册,当App退出后,Receiver仍然可以接收到广播并且进行相应的处理

  • 动态注册:在代码中动态注册,当App退出后,也就没办法再接受广播了


ContentProvider使用方法

http://blog.csdn.net/juetion/article/details/17481039


目前能否保证service不被杀死

Service设置成START_STICKY

  • kill 后会被重启(等待5秒左右),重传Intent,保持与重启前一样

提升service优先级

  • 在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播

  • 【结论】目前看来,priority这个属性貌似只适用于broadcast,对于Service来说可能无效

提升service进程优先级

  • Android中的进程是托管的,当系统进程空间紧张的时候,会依照优先级自动进行进程的回收

  • 当service运行在低内存的环境时,将会kill掉一些存在的进程。因此进程的优先级将会很重要,可以在startForeground()使用startForeground()将service放到前台状态。这样在低内存时被kill的几率会低一些。

  • 【结论】如果在极度极度低内存的压力下,该service还是会被kill掉,并且不一定会restart()

onDestroy方法里重启service

  • service +broadcast 方式,就是当service走ondestory()的时候,发送一个自定义的广播,当收到广播的时候,重新启动service

  • 也可以直接在onDestroy()里startService

  • 【结论】当使用类似口口管家等第三方应用或是在setting里-应用-强制停止时,APP进程可能就直接被干掉了,onDestroy方法都进不来,所以还是无法保证

监听系统广播判断Service状态

  • 通过系统的一些广播,比如:手机重启、界面唤醒、应用状态改变等等监听并捕获到,然后判断我们的Service是否还存活,别忘记加权限

  • 【结论】这也能算是一种措施,不过感觉监听多了会导致Service很混乱,带来诸多不便

在JNI层,用C代码fork一个进程出来

  • 这样产生的进程,会被系统认为是两个不同的进程.但是Android5.0之后可能不行

root之后放到system/app变成系统级应用

大招: 放一个像素在前台(手机QQ)


动画有哪两类,各有什么特点?三种动画的区别

  • tween 补间动画。通过指定View的初末状态和变化时间、方式,对View的内容完成一系列的图形变换来实现动画效果。 Alpha Scale Translate Rotate。

  • frame 帧动画 AnimationDrawable 控制 animation-list xml布局

  • PropertyAnimation 属性动画


Android的数据存储形式。

  • SQLite:SQLite是一个轻量级的数据库,支持基本的SQL语法,是常被采用的一种数据存储方式。 Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的api

  • SharedPreference: 除SQLite数据库外,另一种常用的数据存储方式,其本质就是一个xml文件,常用于存储较简单的参数设置。

  • File: 即常说的文件(I/O)存储方法,常用语存储大数量的数据,但是缺点是更新数据将是一件困难的事情。

  • ContentProvider: Android系统中能实现所有应用程序共享的一种数据存储方式,由于数据通常在各应用间的是互相私密的,所以此存储方式较少使用,但是其又是必不可少的一种存储方式。例如音频,视频,图片和通讯录,一般都可以采用此种方式进行存储。每个Content Provider都会对外提供一个公共的URI(包装成Uri对象),如果应用程序有数据需要共享时,就需要使用Content Provider为这些数据定义一个URI,然后其他的应用程序就通过Content Provider传入这个URI来对数据进行操作。



如何判断应用被强杀

在Applicatio中定义一个static常量,赋值为-1,在欢迎界面改为0,如果被强杀,application重新初始化,在父类Activity判断该常量的值。

应用被强杀如何解决

如果在每一个Activity的onCreate里判断是否被强杀,冗余了,封装到Activity的父类中,如果被强杀,跳转回主界面,如果没有被强杀,执行Activity的初始化操作,给主界面传递intent参数,主界面会调用onNewIntent方法,在onNewIntent跳转到欢迎页面,重新来一遍流程。

Json有什么优劣势。

怎样退出终止App

Asset目录与res目录的区别。

Android怎么加速启动Activity。

Android内存优化方法:ListView优化,及时关闭资源,图片缓存等等。

Android中弱引用与软引用的应用场景。

Bitmap的四种属性,与每种属性队形的大小。

View与View Group分类。自定义View过程:onMeasure()、onLayout()、onDraw()。

如何自定义控件:

  1. 自定义属性的声明和获取

    • 分析需要的自定义属性

    • 在res/values/attrs.xml定义声明

    • 在layout文件中进行使用

    • 在View的构造方法中进行获取

  2. 测量onMeasure

  3. 布局onLayout(ViewGroup)

  4. 绘制onDraw

  5. onTouchEvent

  6. onInterceptTouchEvent(ViewGroup)

  7. 状态的恢复与保存


更多相关文章

  1. Android下的POS打印机调用
  2. blcr加速android启动速度遇到的问题及解决方法
  3. Android(安卓)Launcher 分析
  4. 代码讲解Android(安卓)Scroller、VelocityTracker
  5. Android(安卓)Apk加壳原理分析
  6. 浅谈Java中Collections.sort对List排序的两种方法
  7. mybatisplus的坑 insert标签insert into select无参数问题的解决
  8. python起点网月票榜字体反爬案例
  9. Python list sort方法的具体使用

随机推荐

  1. android ListView美化-->几个比较特别的
  2. Android(安卓)应用程序窗体显示状态操作(r
  3. Android MP4取得播放时长的方法
  4. Android如何动态更换桌面图标(巨坑)
  5. android基础知识12:android自动化测试06―
  6. 第10章 Android的消息机制
  7. Android信任Https自签名证书详细教程
  8. Android AOP(二):AspectJ在Android中实现A
  9. android控件的属性
  10. JOIM:Android通过IPCamera通过互联网实时