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.进程和线程的区别

进程,常被定义为程序的执行,可以把一个进程看成一个独立的程序,在内存中有其完备的数据空间和代码空间。一个进程所拥有的数据和变量只属于他自己。

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

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

进程和线程的关系 
(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 接口。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值