Android基础面试题

1. 转屏时候Activity的生命周期

1.1 新建一个Activity,并把各个生命周期打印出来

1.2 执行Activity,得到例如以下信息

onCreate-->
onStart-->
onResume-->

1.3 按crtl+f12切换成横屏时

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->

1.4 再按crtl+f12切换成竖屏时,发现打印了两次同样的log

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->

1.5 改动AndroidManifest.xml。把该Activity加入 android:configChanges="orientation",运行步骤3

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->

1.6  再运行步骤4。发现不会再打印同样信息,但多打印了一行onConfigChanged

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onConfigurationChanged-->

1.7 把步骤5的android:configChanges="orientation" 改成 android:configChanges="orientation|keyboardHidden"。运行步骤3。就仅仅打印onConfigChanged

onConfigurationChanged-->

1.8 运行步骤4

onConfigurationChanged-->
onConfigurationChanged-->

总结:

①不设置Activity的android:configChanges时,切屏会又一次调用各个生命周期,切横屏时会运行一次。切竖屏时会运行两次

②设置Activity的android:configChanges="orientation"时,切屏还是会又一次调用各个生命周期。切横、竖屏时仅仅会运行一次

③设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会又一次调用各个生命周期,仅仅会运行onConfigurationChanged方法

2. View怎样刷新

3. 类变量和和函数变量有什么差别

类变量也叫全局变量,函数变量也局部变量,两者的作用域不同。全局变量作用于整个类,局部变量作用于某个方法,方法结束后,变量消失。
4. Java gc垃圾回收机制
Java GC(Garbage Collection,垃圾收集,垃圾回收)机制。是Java与C++/C的主要差别之中的一个。作为Java开发人员,一般不须要专门编写内存回收和垃圾清理代 码,对内存泄露和溢出的问题,也不须要像C程序猿那样战战兢兢。这是由于在Java虚拟机中,存在自己主动内存管理和垃圾清扫机制。概括地说。该机制对 JVM(Java Virtual Machine)中的内存进行标记,并确定哪些内存须要回收,依据一定的回收策略。自己主动的回收内存。永不停息(Nerver Stop)的保证JVM中的内存空间,放置出现内存泄露和溢出问题。
5. Andriod 遇到OOM问题,该怎么解决?

导致OOM 有下面几种情况:

应用中须要载入大对象,比如Bitmap

 解决方式:当我们须要显示大的bitmap对象或者较多的bitmap的时候。就须要进行压缩来防止OOM问题。

我们能够通过设置BitmapFactory.Optiions的inJustDecodeBounds属性为true。这种话不会载入图片到内存中,可是会将图片的width和height属性读取出来,我们能够利用这个属性来对bitmap进行压缩。

Options.inSampleSize 能够设置压缩比

持有没用的对象使其无法被gc,导致Memory Leak . 也就是我们说的内存泄漏。内存泄露初期没有什么现象,可是终于会导致内存溢出。

6. ANR的几种情况,怎样避免

①Activity主线程 (事件处理线程” / “UI线程) 在5秒内没有响应输入事件

②BroadcastReceiver 没有在10秒内完毕返回

③Service也是跑在UI Thread里的,仅仅是比activity报ANR的阀值要大些,15秒没有完毕返回,出现ANR。

解决的方法都是不在UI线程中做耗时的操作。一般都是启动子线程。假设要更新UI界面,能够用Handler和Message来完毕。

7. 静态变量和静态方法

静态变量 类型说明符是static。

静态变量属于静态存储方式。其存储空间为内存中的静态数据区(在 静态存储区内分配存储单元),该区域中的数据在整个程序的执行期间一直占用这些存储空间(在程序整个执行期间都不释放)。也能够觉得是其内存地址不变,直 到整个程序执行结束(相反。而auto自己主动变量,即动态局部变量,属于动态存储类别,占动态存储空间,函数调用结束后即释放)。静态变量虽在程序的整个执行过程中始终存在,可是在它作用域之外不能使用。


静态变量并非说其就不能改变值。不能改变值的量叫常量。 其拥有的值是可变的 ,并且它会保持最新的值。说其静态,是由于它不会随着函数的调用和退出而发生变化。

即上次调用函数的时候,假设我们给静态变量赋予某个值的话,下次函数调用时,这个值保持不变。

静态方法是使用公共内存空间的,就是说全部对象都能够直接引用。不须要创建对象再使用该方法。

8. Android Handler机制

直接在UI线程中开启子线程来更新TextView显示的内容,执行程序我们会发现,例如以下错 误:android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.翻译过来就是:仅仅有创建这个控件的线程才干去更新该控件的内容。
 全部的UI线程要去负责View的创建而且维护它,比如更新某个TextView的显示,都必须在主线程中去做,我们不能直接在UI线程中去创建子线程更新UI界面,要利用消息机制:Handler。例如以下就是handler的简单工作原理图:

1)Looper: 一个线程能够产生一个Looper对象。由它来管理此线程里的MessageQueue(消息队列)。

 
2)Handler: 你能够构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。

 

4)线程:UIthread 通常就是main thread,而Android启动程序时会替它建立一个MessageQueue。 

9.进程和线程的差别

进程,常被定义为程序的运行。能够把一个进程看成一个独立的程序,在内存中有其完备的数据空间和代码空间。

一个进程所拥有的数据和变量仅仅属于他自己。


线程,某一进程中一路单独执行的程序。

也就是线程存在于进程之中,一个进程由一个或多个线程构成。各线程共享相同的代码和全局数据,但各有自己的堆栈。因为堆栈是每一个线程一个,因此局部变量对每一线程来说是私有的。因为全部线程共享相同的代码和全局数据,他们比进程更紧密,线程间的相互作用更easy。因为他们本身有某些供通信用的共享内存:进程的全局数据。

进程拥有一个完整的虚拟地址空间,不依赖于线程而独立存在;反之,线程是进程的一部分。没有自己的地址空间,与进程内的其它线程一起共享分配给该进程的全部资源

进程和线程的关系 
(1)一个线程仅仅能属于一个进程。而一个进程能够有多个线程,但至少有一个线程。 
(2)资源分配给进程。同一进程的全部线程共享该进程的全部资源。 
(3)处理机分给线程,即真正在处理机上执行的是线程。

 
(4)线程在运行过程中。须要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

10.位,字节,中文字符占空间大小

Bit意为"位"或"比特",是计算机运算的基础; 
Byte意为"字节",是计算机文件大小的基本计算单位; 
1byte = 8bits。两者换算是1:8的关系。 
两个字节一个汉字。

 
1Bit=1/16个字 
所以16bit=1个汉字

11.Intent Filter的机制

12.AM的机制

13.vim的基本操作

14.Serializable 和 Parcelable 差别
Android 中自己定义的对象序列化的问题有两个选择一个是Parcelable,另外一个是Serializable(Java)。
一 序列化原因:
① 永久性保存对象,保存对象的字节序列到本地文件里。
② 通过序列化对象在网络中传递对象。
③ 通过序列化在进程间传递对象。

 
二 至于选取哪种可參考以下的原则:
① 在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类。
② Serializable在序列化的时候会产生大量的暂时变量,从而引起频繁的GC。
③ 如要要将数据储存在磁盘上,使用Serializable,由于在外界有变化的情况下,Parcelable不能非常好的保证数据的持续性。


实现方法:
①Serializable 的实现。仅仅须要继承  implements Serializable 就可以。这仅仅是给对象打了一个标记,系统会自己主动将其序列化。
②Parcelabel 的实现。须要在类中加入一个静态成员变量 CREATOR。这个变量须要继承 Parcelable.Creator 接口。

原文地址:https://www.cnblogs.com/clnchanpin/p/7137159.html