一, Activity的四种启动模式:standard、singleTop、singleTask、singleInstance
(1)standard模式:Standard模式是Android的默认启动模式,你不在配置文件中做任何设置,那么这个Activity就是standard模式,这种模式下,Activity可以有多个实例,每次启动Activity,无论任务栈中是否已经有这个Activity的实例,系统都会创建一个新的Activity实例
(2)singleTop模式:SingleTop模式和standard模式非常相似,主要区别就是当一个singleTop模式的Activity已经位于任务栈的栈顶,再去启动它时,不会再创建新的实例,如果不位于栈顶,就会创建新的实例。
(3)singleTask模式:SingleTask模式的Activity在同一个Task内只有一个实例,如果Activity已经位于栈顶,系统不会创建新的Activity实例,和singleTop模式一样。但Activity已经存在但不位于栈顶时,系统就会把该Activity移到栈顶,并把它上面的activity出栈。应用场景:程序主界面,我们肯定不希望主界面被多创建,而且在主界面退出的时候退出整个App是最好的设想。
(4)singleInstance模式:singleInstance模式也是单例的,但和singleTask不同,singleTask只是任务栈内单例,系统里是可以有多个singleTask Activity实例的,而singleInstance Activity在整个系统里只有一个实例,启动一singleInstanceActivity时,系统会创建一个新的任务栈,并且这个任务栈只有他一个Activity。场景:新的任务栈中只有它一个activity,始终只有它一个。从A跳到B,B是singleInstance模式,再从B跳C,再从C按返回键,会回到A,而B就像是被销毁了一样,其实是B进入一个新的task栈汇中,只有它一个。A和C是一个任务栈。拨号界面,闹钟界面
二:Fragment生命周期
可以看到 Fragment 的生命周期和 Activity 很相似,只是多了一下几个方法:
onAttach()在Fragment 和 Activity 建立关联是调用(Activity 传递到此方法内)
onCreateView()当Fragment 创建视图时调用
onActivityCreated()在相关联的 Activity 的 onCreate() 方法已返回时调用。
onDestroyView()当Fragment中的视图被移除时调用
onDetach()当Fragment 和 Activity 取消关联时调用。
Activity 生命周期对片段生命周期的影响,如下图
三:Service服务
1,service是在主线程(ui线程)运行的应用组件可在后台运行,它不是thread线程(在后台运行就是没有任何关联的界面)编写在后台下载的功能,用到网络请求的时候,需要在service起个子线程运行。
2,特点:(1),在后台运行,不与用户交互。(2),即使应用退出,服务也不会停止。
3,service分类
3,1,lacal service(本地服务)在同一个进程中,(即同一个应用程序中)俩者的通信是进程内通信。 3.2,Remote service(远程服务),不在同一个进程中(既不是同一个应用程序),这时存在一个进程间通信的问题,android专门为此设计了AIDL来实现进程间通信。
4,启动与停止
4.1,一般启动 startService(Intent intent)
stopService(Intent intent)
4.2, 绑定启动 bindService(Intent intent, ServiceConnection connection)
unbindService(ServiceConnection connection)
5,生命周期
5.1,startService
第一次调用:-->构造方法()-->onCreate()-->onStartCommand()
(重要)后面再调用:-->onStartCommand()
stopService(): -->onDestory()
5.2, bindService(Intent intent, ServiceConnection connection)
调用:-->构造方法()-->onCreate()-->onBind()-->onServiceConnected()
unbindService():(有当前Activity与Service的连接)-->onUnbind()-->onDestroy()
四:什么是Handler
1、什么是handler?
答:handler是Android给我们提供用来更新UI的一套机制,也是一套消息处理机制,我们可以发消息,也可以通过它 处理消息。
2,那为什么要用handler呢?我能不能不用?
答:我在网上搜了下,给我的答案是,肯定是不行的。因为android在设计的时候就封装了一套消息创建、传递、处理。如果不遵循就不能更新UI信息,就会报出异常。
3,Android为什么要设计只能用handler机制更新UI呢?
答:最根本的目的就是为了解决多线程并发的问题!
打个比方,如果在一个activity中有多个线程,并且没有加锁,就会出现界面错乱的问题。但是如果对这些更新UI的操作都加锁处理,又会导致性能下降。
处于对性能的问题考虑,Android给我们提供这一套更新UI的机制我们只需要遵循这种机制就行了。不用再去关系多线程的问题,所有的更新UI的操作,都是在主线程的消息队列中去轮训的。
4、handler、Looper、MessageQueue的原理是什么?
答:大家都知道handler的作用有两个,发送消息和处理消息。而handler发送的消息必须被送到指定MessageQueue(消息队列)中,也就是说,如果想让handler正常工作,就必须有一个MessageQueue(消息队列),不过MessageQueue(消息队列)是由Looper来关系。所以也可以说想让handler正常工作,必须在当前线程中有一个Looper对象。(请认真读)
4.1,来看一下Looper提供的构造器源码,如图:
你会发现该构造器用到的是private(私有化),告诉你的就是程序员你不能通过构造方法创建looper对象,而在方法中Looper创建了一个与关联的MessageQueue,这个MessageQueue就是用来管理Message(handler接收和处理的消息对象)!
4.2,为了保证当前线程有Looper对象,可以有两种情况处理。(疯狂的Android讲义224页)
(1)主ui线程启动,系统就初始化了一个Looper对象,只要在程序中直接创建handler即可,然后用handler发送和处理消息。
(2)程序员自己创建的线程,这个时候就要自己手动创建一个Looper对象了,创建Looper对象调用它的prepare()。prepare()方法 是为了保证每个线程最多一个Looper对象。
prepare()方法 源码如图。
然后用Looper.loop()启动它。此时loop()方法就会使用一个死循环不断地取出MessageQueue()中的消息,并将消息分给所对应的Handler处理。
好吧总结一下吧:
:Looper的作用:每个线程只有一个Looper,他负责管理MessageQueue,会不断的从MessageQueue取出消息,分发给对象 的handler
:MessageQueue的作用:由Looper管理,而MessageQueue则采用先进的方法来管理Message!
:Handler的作用:它把消息发送给Looper管理的MessageQueue,并负责处理Looper分发给他的消息
五,Android在子线程更新UI的最常见的五种方式 (这里不讲解AsyncTask(异步任务))
1、runOnUiThread()方法
2,handler.post()方法
3,handler.sendMessage()方法
4,view.post()方法。
5、view postDelayed(Runnable,long)
六,SDK和API的区别
SDK相当于开发集成工具环境,API就是数据接口。在SDK环境下调用API数据。
实际上SDK包含了API的定义,API定义一种能力,一种接口的规范,而SDK可以包含这种能力、包含这种规范。但是SDK又不完完全全只包含API以及API的实现,它是一个软件工具包,它还有很多其他辅助性的功能。SDK 包含了使用 API 的必需资料,所以人们也常把仅使用 API 来编写 Windows 应用程序的开发方式叫做“SDK编程”。
通俗语言解释
API: 前端调用后端数据的一个通道,就是我们俗说的接口,通过这个通道,可以访问到后端的数据,但是又无需调用源代码。
SDK: 工程师为辅助开发某类软件的相关文档、范例和工具的集合,使用SDK可以提高开发效率,更简单的接入某个功能。
举例说明:一个产品想实现某个功能,可以找到相关的SDK,工程师直接接入SDK,就不用再重新开发了。
七,7.1 GC机制:垃圾收集器一般完成两件事。1,检测出垃圾;2,回收垃圾,。
7.2 Java对象引用:通常,Java对象的引用可以分为4类:强引用、软引用、弱引用和虚引用。
强引用:通常可以认为是通过new出来的对象,即使内存不足,GC进行垃圾收集的时候也不会主动回收。软引用:在内存不足的时候,GC进行垃圾收集的时候会被GC回收。 弱引用:无论内存是否充足,GC进行垃圾收集的时候都会回收。 虚引用:和弱引用类似,主要区别在于虚引用必须和引用队列一起使用。引用队列:如果软引用和弱引用被GC回收,JVM就会把这个引用加到引用队列里,如果是虚引用,在回收前就会被加到引用队列里。 类加载器 是ClassLoader
八,超文本传输协议 http和https的区别
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
九,view事件的分发机制和传递顺序。附上图和录音(录音需要开会员,算了我自己听吧)
十,Java内存区域的分布。
根据虚拟机规范一般划分为五个区域: 程序计数器、方法区、虚拟机栈、本地方法栈、堆;其中程序计数器类似于计算机组成原理的PC寄存器,主要作用是用来标记程序正在运行的字节码地址;方法区主要每个类的基本信息,运行时常量池,编译后的代码等;栈区主要是存方法调用的栈帧,每个栈帧下又存储很多信息,局部变量表返回地址等;堆区就是。。。
内存一般分为栈区、堆区、方法区(方法区里面包含常量池)
栈区一般存放变量(局部变量)、方法的参数引以及用对象
堆区一般存放的是new的对象以及成员变量
方法区一般存放方法 里面常量池存放常量。
从堆和栈的功能以及作用来比较,堆和栈有什么不同?
堆主要用来存放对象,栈主要是用来执行程序的。相较于堆,栈的存取速度更快,但栈的大小和生存周期必须确定,因此缺乏一定的灵活性。而堆却可以在运行时动态的分配内存,生存期不用提前告诉编译器,但这也导致了其存取速度的缓慢。
不同线程调用方法为什么是线程安全的?
任何方法每次被线程调用,都会在栈中开辟新的空间。同一方法的不同线程执行,方法与方法之间互不影响。全局变量因为是存在堆区的对象中,所以会互相干扰。
成员变量存储在哪儿?
静态成员变量存储在方法区,非静态成员变量存储在堆区。
为什么局部变量不能够static修饰?
局部变量存储在栈区,在方法调用时不能够自动初始化必须由程序员手动初始化,否则会报错,归根结底是由于static变量和局部变量存储的位置不一样。
十一,java虚拟机和安卓虚拟机的区别。
Java虚拟机运行的是Java字节码,Dalvik虚拟机运行的是Dalvik字节码。
2,Dalvik可执行文件体积更小。
3,Java虚拟机与Dalvik虚拟机架构不同。Java虚拟机基于栈结构,程序在运行时虚拟机需要频繁的从栈上读取或写入数据,这个过程需要更多的指令分派与内存访问次数,会消耗不少CPU时间,对于像手机设备资源有限的设备来说,这是相当大的一笔开销。 Dalvil虚拟机基于寄存器结构,数据是访问通过寄存器直接传递,这样的访问方式比基于栈方式要快很多。
十二,webview和js如何交互。
十三,有没有用过dragger,svga等工具。svga是YY开源的一个动画框架,是一种全新的动画格式,能同时兼容ios、android,flutter,web多个平台的动画格式。SVGA提供了一整套的动画解决方案。
十四,如何优化直播平台的app,1:做缓冲机制,消息来了不是立马修改ui,先攒着消息,每过一个固定时间间隔刷新ui,注意释放内存,不要一直持有临时对象,主要是别一直频繁调cpu和gpu画ui,咱们画进度一般都是一秒一次,直播间那个人数多,并发高,可能一毫秒进来10条消息,不可能没次都画ui,如果进来超过100条消息,建议还是分段加载。这只是一方面,大家有别的好的方法可以留言。
十五。什么是Java的反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取类信息以及动态调用对象内容就称为java语言的反射机制。
反射的作用:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;
反射的实现:我们知道,要使用一个类,就要先把它加载到虚拟机中,生成一个Class对象。这个class对象就保存了这个类的一切信息。 反射机制的实现,就是获取这个Class对象,通过Class对象去访问类、对象的元数据以及运行时的数据。
有三种方法获得类的Class对象:Class.forName(String className)、className.class、实例对象.getClass();
十六:什么是java序列化:Java 序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。
以下情况需要使用 Java 序列化:
想把内存中的对象状态保存到一个文件中或者数据库中时候;想用套接字在网络上传送对象的时候;想通过RMI(远程方法调用)传输对象的时候。
十七:Java基本字节占用的字节数:1字节:byte,boolean。2字节:short,char。4字节:int,float。8字节:long,double。一个字节占8位。
十八:android线程间的通信方式:有的说的就是子线程更新UI的哪5种方式。还有的说其他的。操蛋,有没有统一的答案。
十九:如何优化android APP启动速度:1、Application的onCreate流程,对于大型的APP来说,通常会在这里做大量的通用组件的初始化操作;建议:很多第三方SDK都放在Application初始化,我们可以放到用到的地方才进行初始化操作。
2、Activity的onCreate流程,特别是UI的布局与渲染操作,如果布局过于复杂很可能导致严重的启动性能问题;建议:Activity仅初始化那些立即需要的对象,xml布局减少冗余或嵌套布局。
3,利用主题快速显示界面;异步初始化组件;梳理业务逻辑,延迟初始化组件、操作;去掉无用代码、重复逻辑等
二十:如何解决内存溢出。android64k问题。
二十一,Android中IntentService与Service的区别。
二十二,HashMap的数据结构,实现原理,内部是怎么存储数据的,以及hashmap和hashtable的区别。
二十三,Parcelable 和 Serializable的区别。
二十四,接口和抽象类的区别。
二十五,创建线程的两种方法,有什么区别。
二十六,自定义注解,关键字。生命周期。
二十七,内部类。
二十八,service和activity是如何传递数据的。
二十九,object的方法。
三十,写个单例,别人也可以new,如何保证唯一性。
三十一,xJava原理可总结为:被观察者(Observable)通过 订阅(Subscribe)按顺序发送事件给观察者(Observer), 观察者(Observer)按顺序接收事件& 作出对应的响应动作。具体如下图:
网友评论