android题库系列--360

Q:软引用、弱引用区别
  软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。
  弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。

Q:垃圾回收
1、那些内存需要回收:
  可以采用引用计数法,有引用就+1,为0的就是没有引用的直接回收,但无法回收两个对象相互引用的情况;这种情况需要使用可达性分析法,当一个对象到GC roots无引用,证明这个对象可以被回收,可以当作gc roots结点的对象有:虚拟机栈、方法区静态属性、方法区静态常量、本地方法栈
2、什么时候回收:
  一般有几个阶段,新生代(新对象,快速回收)、老年代(老对象、生命周期长)、持久代(存放静态文件、大文件、基本不回收)
3、如何回收:
  对于新生代,对象容易死亡、存活率低,采用复制算法收集,效率高;对于老年代或者持久代,采用标记-清除算法或者标记整理算法

gc收集器
年轻代收集器包括:Serial收集器、ParNew收集器以及Parallel Scavenge收集器
老年代收集包括:Serial Old收集器、Parallel Old收集器以及CMS收集器。

Q:多线程:怎么用、有什么问题要注意;Android线程有没有上限,然后提到线程池的上限
  有几种方法可以新开一个线程:继承一个thread,实现一个runable接口,实现一个callable接口;需要注意线程导致的内存泄漏,不要随意新建线程池,尽量复用线程池;Android线程没有上限,但只享有一个进程的资源,所以合适的线程数量很重要,线程池中线程的数量一般CPU核数或者I/O效能有关,那个负债高以那个为标准,比如CPU密集型为n+1; I/O密集型为2n+1;

Q:锁
有三种锁机制实现方案,1、synchronized对象锁,自动释放锁 2、ReentrantLock重入锁,需要手动释放锁,lock.lock();// 得到锁 ,lock.unlock();// 释放锁 3、读写锁 ReadWriteLock这个保证读和读不用互斥,提高了效率

锁机制处理同步时一种悲观策略,因为锁会产生阻塞,一个线程在执行,其他线程必须等待而不能执行其他任务,大大降低了效率,引申出了volatile和CAS,比单纯的锁能提供更高性能的一种共享资源访问机制

Q:OOM,内存泄漏
内存溢出OOM,当分配的内存不够加载相关资源时容易导致内存溢出,内存泄漏也是比较容易导致内存溢出的。开发中比较容易出现的地方:
1、加载大图、微博长图。在某些低端机容易OOM
2、bitmap大对象使用完没有关闭
3、文件流使用完没有关闭、广播和服务没有取消注册等
4、过多的耗时操作没有关闭,访问网络、数据的线程池
5、滥用上下文

Q:ANR怎么分析解决
ANR原因:
1、主线程阻塞或者进行数据读取
2、CPU满负荷或者I/O阻塞
3、内存不足
4、各大组件生命周期ANR,比如广播onReceive(),输入5秒,前台服务20秒,后台服务60秒

解决办法:
根据log日志查找anr类型,复现;
分析trace.txt 的ANR日志;
借助DDMS进行分析;

Q:LinearLayout、RelativeLayout、FrameLayout的特性、使用场景
LinearLayout用在横向或者纵向控件比较多的时候,效率较高;
RelativeLayout 执行两次绘制onMesure(),用在子布局有很多控件且布局不规则的时候;
FrameLayout 使用在需要有视图效果重叠控件的地方比较方便;
绘制效率:FrameLayout >LinearLayout>RelativeLayout

Q:如何实现Fragment的滑动
和viewpager绑定使用,作为一个page 页面;

Q:ViewPager使用细节,如何设置成每次只初始化当前的Fragment,其他的不初始化
重写setUserVisibleHint(boolean isVisibleToUser)方法,在里面判断是否对用户可见,如果可见则开始初始化页面,如加载网络数据

Q:ListView重用的是什么
主要是针对子view控件的复用,采用ViewHolder当内容contentview不为空时,直接从tag里面取viewholder获取相关控件,不用再次findViewById;

Q:进程间通信的机制
android 系统中采用的是Binder,其他方式还有共享内存、管道、文件等

Q:AIDL机制
AIDL是一种接口语言,Binder的数据传输过程就是通过AIDL来实现的:
1、服务端中的Service给与其绑定的客户端提供Binder对象
2、客户端通过AIDL接口中的asInterface()将这个Binder对象转换为代理Proxy并通过它发起RPC请求
3、客户端挂起当前线程,并将数据写入data然后调用transact();
4、服务端调用ontransact()并启动线程池处理请求并返回处理数据,写入reply;
5、返回调用结果并唤醒客户端

Q:AsyncTask机制
AsyncTask内部是通过handler和线程池来实现异步任务的

Q:如何取消AsyncTask
1、task.cancel();
2、在doInBackground和onProgressUpdate中进行检测,如果任务已经取消,则直接退出循环

Q:序列化
序列化就是把当前的数据保存下来,这种操作要么就是通过流写入磁盘或者其他介质,这种过程叫做序列化,反之从其他位置获取到内存这个过程称为反序列化;

Q:Android为什么引入Parcelable
Serializable的设计初衷是为了序列化对象到本地文件、数据库、网络流、RMI以便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是由于Serializable效率过低,消耗大,而android中数据传递主要是在内存环境中(内存属于android中的稀有资源),因此Parcelable的出现为了满足数据在内存中低开销而且高效地传递问题。

Q:有没有尝试简化Parcelable的使用
Parcelable自动生成代码插件

Q:项目:拉活怎么做的
1、提升进程优先级,或者把当前服务提升为前台服务
2、当锁屏时,生成一个1像素的前台服务
3、当应用退出时,在接收到应用关闭广播时尝试重新打开应用

Q:应用安装过程
应用的安装是由PMS(包管理器)进行管理的,
1) 拷贝apk文件到指定目录
在Android系统中,apk安装文件是会被保存起来的,默认情况下,用户安装的apk首先会被拷贝到 /data/app 目录下。
/data/app目录是用户有权限访问的目录,在安装apk的时候会自动选择该目录存放用户安装的文件,而系统出厂的apk文件则被放到了 /system 分区下,包括 /system/app,/system/vendor/app,以及 /system/priv-app 等等,该分区只有Root权限的用户才能访问,这也就是为什么在没有Root手机之前,我们无法删除系统出厂的app的原因了。
(2) 解压apk,拷贝文件,创建应用的数据目录
为了加快app的启动速度,apk在安装的时候,会首先将app的可执行文件(dex)拷贝到 /data/dalvik-cache 目录,缓存起来。
然后,在/data/data/目录下创建应用程序的数据目录(以应用的包名命名),存放应用的相关数据,如数据库、xml文件、cache、二进制的so动态库等等。

(3) 解析apk的AndroidManifinest.xml文件
Android系统中,也有一个类似注册表的东西,用来记录当前所有安装的应用的基本信息,每次系统安装或者卸载了任何apk文件,都会更新这个文件。这个文件位于如下目录:
/data/system/packages.xml
系统在安装apk的过程中,会解析apk的AndroidManifinest.xml文件,提取出这个apk的重要信息写入到packages.xml文件中,这些信息包括:权限、应用包名、APK的安装位置、版本、userID等等。
由此,我们就知道了为啥一些应用市场和软件管理类的app能够很清楚地知道当前手机所安装的所有的app,以及这些app的详细信息了。
另外一件事就是Linux的用户Id和用户组Id,以便他可以获得合适的运行权限。
以上这些都是由PackageServiceManager完成的,下面我们会重点介绍PackageServiceManager。

(4) 显示快捷方式
这些应用程序只是相当于在PackageManagerService服务注册好了,如果我们想要在Android桌面上看到这些应用程序,还需要有一个Home应用程序,负责从PackageManagerService服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式。在Android系统中,负责把系统中已经安装的应用程序在桌面中展现出来的Home应用程序就是Launcher了
2.PackageManagerService的启动过程
Android系统在启动的过程中,会启动一个应用程序管理服务PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,即以Apk为后缀的文件,然后对这些文件进解析,得到应用程序的相关信息。应用程序管理服务PackageManagerService安装应用程序的过程,其实就是解析析应用程序配置文件AndroidManifest.xml的过程,并从里面得到得到应用程序的相关信息,例如得到应用程序的组件Activity、Service、Broadcast Receiver和Content Provider等信息,有了这些信息后,通过ActivityManagerService这个服务,我们就可以在系统中正常地使用这些应用程序了。应用程序管理服务PackageManagerService是系统启动的时候由SystemServer组件启动的,启后它就会执行应用程序安装的过程,因此,本文将从SystemServer启动PackageManagerService服务的过程开始分析系统中的应用程序安装的过程。

推荐阅读更多精彩内容

  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 13,217评论 3 82
  • 别人的总结不一定适合自己,所以尽量多做一些自己的总结,针对自己的薄弱点重点说明,适当的借鉴别人,少走一些弯路。最重...
    renkuo阅读 6,014评论 2 47
  • 1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供...
    简欲明心阅读 68,099评论 17 294
  • 第二部分 自动内存管理机制 第二章 java内存异常与内存溢出异常 运行数据区域 程序计数器:当前线程所执行的字节...
    小明oh阅读 653评论 0 2
  • 清明小长假马上就要到了。 晚上,我们仨出去万达广场小聚了一下,回来时下了点毛毛雨,路上有点堵车,绕道而归,看到几个...
    幸福Gary妈阅读 18评论 0 0