(闹钟(弹出),支付宝支付界面)
>>特点
①图片缓存->媒体缓存5.菜单键快速应用切换(双击菜单键,就能自动切换到上一个应用)
1.client 发出请求
2.server 收到请求,并自己生成一对密钥,即 公钥S 和 私钥S
3.server 把生成的 公钥S 传递给 client (除了 公钥S ,还有很多额外信息)
4.client 收到 公钥S后进行判断,若无效,弹出警告,否则生成一串随机数,我们称之为 私钥C ,然后 client 用 server 传过来的 公钥S 对该随机数加密,形成【私钥C】
5.client 把【私钥C】传递给 server
6.server 收到【私钥C】,用 私钥S 把【私钥C】解密成私钥C,然后把需要传递的数据用 私钥C 进行加密
7.server 把【数据】传递给 clien
8.client 收到【数据】,用 私钥C 解密,完成一波收割
(用HTTPS进行加密的优点:利用非对称加密的安全性来加密那一串随机数--私钥C;利用对称加密的快捷性来加密报文,总体来说就是把真正加密解密的密钥(私钥C)用公钥S和私钥S来加密)
注:对称加密:是指加密和解密用一致的密钥,特点是快!!!
非对称加密:指密钥区分公钥和私钥,公钥加密,私钥解密(私钥好比唯一一把钥匙,公钥好比锁,钥匙只有一把,但锁可以有很多,被锁头锁上的数据全天下只有一把私钥才能打开),特点是安全,但是慢!!!
http协议:应用层协议,并且http协议是基于tcp连接的,主要解决的是如何包装协议的
tcp协议:传输层协议,通常也叫做tcp/ip协议,主要解决数据如何在网络中传输
udp协议:传输层协议,用户数据报协议,不可靠的协议,只负责把应用层的协议的数据传送到ip层的数据报,而不管数据是否到达。
ip协议:网络层。
socket连接:长连接(是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,说白了socket就是一组调用接口(API),封装了做tcp/ip开发的网络接口,通过Socket,我们才能使用TCP/IP协议。)
http连接:短连接
TCP/IP协议和Http协议之间的关系:
TPC/IP协议是传输层协议,主要解决数据 如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据,而socket则是对TCP/IP协议的封装和应用(程序员层面上)。实际上http协议就是建立在tcp/ip协议之上的。
tcp/ip协议, http协议,socket三者之间的关系:
实际上,传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,而Socket本身不算是协议,它只是提供了一个针对TCP或者UDP编程的接口。
十七.内存泄露产生的原因及解决方法?
1)一个Activity通常就是一个单独的屏幕(窗口);
2)Activity之间通过Intent进行通信;
3)Android每一个应用中的Activity都必须在AndroidManifest.xm配置文件中声明,否则系统将不识别也不执行该Activity.
1)Service用于在后台完成用户指定的操作,Service分为两种:
(a)started(启动):当应用程序组件(如activity)调用startService()方法启动服务时,服务处于started状态。
(b)bound(绑定):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。
Service生命周期?
1.StartService
Oncreate
OnstartCommand
Ondestroy
2.BindService
Oncreate
OnBind
OnUnbind
OnDestroy
startService()与bindService()区别:
当服务是started状态时,其生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动服务的组件已经被销毁,服务仍然运行。
使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止;
Service完整的生命周期从调用onCreate()开始直到调用onDestroy()结束。
Service有两种使用方法:
(1)以调用Context.startService()启动,而以调用Context.stopService()结束。
(2)以调用Context.bindService()方法建立,以调用Context.unbindService()关闭。
Service通常位于后台运行,它一般不需要与用户交互,因此Service组件没有图形用户界面。Service组件需要继承Service基类。Service组件通常用于为其他组件提供后台服务或监控其他组件的运行状态。
1)各应用程序之间可以通过ContentResolver类从该内容提供者中获取或存入数据;
2)只有需要在多个应用程序间共享数据是才需要内容提供者。
3)ContentProvider实现数据共享。
4)开发人员不会直接使用ContentProvider类的对象,大多数是通过ContentResolver对象实现对ContentProvider的操作。
定义:
Broadcast是四大组件之一,是一种广泛运用在应用程序之间传输信息的机制,通过发送Intent来传送我们的数据
Broadcast Receiver的使用场景:
同一App具有多个进程的不同组件之间的消息通信
不同App之间的组件之间的消息通信
Broadcast Receiver实现机制
自定义广播类继承BroadcastReceiver,复写onReceiver()
通过Binder机制向AMS进行注册广播
广播发送者通过Binder机制向AMS发送广播
AMS查找符合相应条件的广播发送到BroadcastReceiver相应的循环队列中
消息队列执行拿到广播,回调BroadcastReceiver的onReceiver()
LocalBroadcastManager特点
本地广播只能在自身App内传播,不必担心泄漏隐私数据
本地广播不允许其他App对你的App发送该广播,不必担心安全漏洞被利用
本地广播比全局广播更高效
以上三点都是源于其内部是用Handler实现的
1)你的应用可以使用它对外部事件进行过滤,只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力,例如闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
2)广播接收者的注册有两种方法,分别是程序动态注册和AndroidManifest文件中进行静态注册。
3)动态注册广播接收器特点是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用。
4大基本组件都需要注册才能使用,每个Activity、service、Content Provider都需要在AndroidManifest文件中进行配置。AndroidManifest文件中未进行声明的activity、服务以及内容提供者将不为系统所见,从而也就不可用。而broadcast receiver广播接收者的注册分静态注册(在AndroidManifest文件中进行配置)和通过代码动态创建并以调用Context.registerReceiver()的方式注册至系统。需要注意的是在AndroidManifest文件中进行配置的广播接收者会随系统的启动而一直处于活跃状态,只要接收到感兴趣的广播就会触发(即使程序未运行)。
内容提供者的激活:当接收到ContentResolver发出的请求后,内容提供者被激活。而其它三种组件activity、服务和广播接收器被一种叫做intent的异步消息所激活。
内容提供者仅在响应ContentResolver提出请求的时候激活。而一个广播接收器仅在响应广播信息的时候激活。所以,没有必要去显式的关闭这些组件。Activity关闭:可以通过调用它的finish()方法来关闭一个activity。服务关闭:对于通过startService()方法启动的服务要调用Context.stopService()方法关闭服务,使用bindService()方法启动的服务要调用Contex.unbindService()方法关闭服务。
OnClickListener
。对设置 OnClickListener
来说,View
是被观察者,OnClickListener
是观察者,二者通过setOnClickListener()
方法达成订阅关系。订阅之后用户点击按钮的瞬间,Android Framework 就会将点击事件发送给已经注册的OnClickListener
。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。3.Build模式(建造者模式)
任何需要生成复杂对象的地方,都可以使用工厂方法模式。用new就能创建的对象不需要使用工厂模式,因为使用工厂模式就要增加一个工厂类,增加了系统复杂度。
快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。
一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。
接着分别比较左右两边的序列,重复上述的循环。
public class FastSort{ public static void main(String []args){ System.out.println("Hello World"); int[] a = {12,20,5,16,15,1,30,45,23,9}; int start = 0; int end = a.length-1; sort(a,start,end); for(int i = 0; i){ System.out.println(a[i]); } } public void sort(int[] a,int low,int high){ int start = low; int end = high; int key = a[low]; while(end>start){ //从后往前比较 while(end>start&&a[end]>=key) //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较 end--; if(a[end]<=key){ int temp = a[end]; a[end] = a[start]; a[start] = temp; } //从前往后比较 while(end>start&&a[start]<=key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置 start++; if(a[start]>=key){ int temp = a[start]; a[start] = a[end]; a[end] = temp; } //此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用 } //递归 if(start>low) sort(a,low,start-1);//左边序列。第一个索引位置到关键值索引-1 if(end //右边序列。从关键值索引+1到最后一个 } }
1、 ==是判断两个变量或实例是不是指向同一个内存空间
equals是判断两个变量或实例所指向的内存空间的值是不是相同
2、==是指对内存地址进行比较
equals()是对字符串的内容进行比较
3、==指引用是否相同
equals()指的是值是否相同
二十七.在子线程中如何更新UI?
第一种用 Handler
在主线程中定义Handler,通知Handler完成UI更新;
第二种用 用Activity对象的runOnUiThread方法更新UI;
第三种用 View.post(Runnable r) ;
总结:UI的更新必须在主线程中完成,所以不管上述那种方法,都是将更新UI的消息发送到了主线程的消息对象,让主线程做处理;
二十八.Handler原理
Handler主要用于线程间的通信。
一个Handler允许发送和处理Message和Runable对象,UI主线程会自动分配一个Looper(消息轮询器),每个Looper中封装着MessageQueue(消息队列),遵循先进先出原则。Looper负责不断的从自己的消息队列里取出队头的任务或消息执行。一般是在子线程执行完耗时操作之后,通过Handler的sendMessage或post方法将Message和Runable对象传递给MessageQueue,而且在这些对象离开MessageQueue时,Handler负责执行他们(用到handleMessage方法,主要执行刷新UI的代码)。
二十九. Java中常用的数据结构?
点击打开链接
java中有几种常用的数据结构,主要分为Collection和map两个主要接口(接口只提供方法,并不提供实现),而程序中最终使用的数据结构是继承自这些接口的数据结构类。其主要的关系(继承关系)有:
Collection---->Collections Map----->SortedMap------>TreeMap
Collection---->List----->(Vector \ ArryList \ LinkedList) Map------>HashMap----->TreeMap----->HashTable
Collection---->Set------>(HashSet \ LinkedHashSet \ SortedSet)
List总结:
所有的List中可以有相同的元素,可以有null元素,
基于Array的List(Vector,ArrayList)适合查询,而LinkedList 适合添加,删除操作
Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象;
HashSet和TreeSet的区别?
1、TreeSet 是二差树实现的,Treeset中的数据是自动排好序的,不允许放入null值。
2、HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。
3、HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的 String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例 。
Map总结:
Map有:HashMap、TreeMap、Hashtable。 1、HashMap:线程不安全,键、值不允许为null,并且没顺序。 2、Hashtable:线程安全,键、值允许为null,并且没顺序。 3、TreeMap:线程不安全、键、值不允许为null,并且没顺序。 备注:当前用的最多的是HashMap,因为线性不安全,也就是说读取和存储效率要更高一些。
几个常用类的区别 :
1.ArrayList: 元素单个,效率高,多用于查询
2.Vector: 元素单个,线程安全,多用于查询
3.LinkedList:元素单个,多用于插入和删除
4.HashMap: 元素成对,元素可为空
5.HashTable: 元素成对,线程安全,元素不可为空
HashSet:元素无序、不可重复;ArrayList:元素有序,可重复
HashMap以键值对的形式保存数据,key值可重复,value值不可重复
多线程一个是利用现在CPU的多核机制,可以提供并行能力
另一个是实现异步处理,不会阻塞主线程,可以提供更好的用户体验
哪些场景用到多线程?
场景一:一个业务逻辑有很多次的循环,每次循环之间没有影响,比如验证1万条url路径是否存在,正常情况要循环1万次,
逐个去验证每一条URL,这样效率会很低,假设验证一条需要1分钟,总共就需要1万分钟,有点恐怖。这时可以用多线程,
将1万条URL分成50等份,开50个线程,没个线程只需验证200条,这样所有的线程执行完是远小于1万分钟的。
场景二:需要知道一个任务的执行进度,比如我们常看到的进度条,实现方式可以是在任务中加入一个整型属性变量(这样
不同方法可以共享),任务执行一定程度就给变量值加1,另外开一个线程按时间间隔不断去访问这个变量,并反馈给用户。
总之使用多线程就是为了充分利用cpu的资源,提高程序执行效率,当你发现一个业务逻辑执行效率特别低,耗时特别长,
就可以考虑使用多线程。不过CPU执行哪个线程的时间和顺序是不确定的,即使设置了线程的优先级,因此使用多线程的风险
也是比较大的,会出现很多预料不到的问题,一定要多熟悉概念,多构造不同的场景去测试才能够掌握!
SQLite:
SQLite是一个轻量级的数据库,支持基本SQL语法,是常被采用的一种数据存储方式。Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。
SharedPreference:
除SQLite数据库外,另一种常用的数据存储方式,其本质就是一个xml文件,常用于存储较简单的参数设置
File:
即常说的文件(I/O)存储方法,常用于存储大数量的数据,但是缺点是更新数据将是一件困难的事情。
ContentProvider:
Android 系统中能实现所有应用程序共享的一种数据存储方式,由于数据通常在各应用间的是互相私密的,所以此存储方式较少使用,但是其又是必不可少的一种存储方式。例如音频,视频,图片和通讯录,一般都可以采用此种方式进行存储。每个ContentProvider都会对外提供一个公共的URI(包装成Uri对 象),如果应用程序有数据需要共享时,就需要使用ContentProvider为这些数据定义一个URI,然后其他的应用程序就通过 Content Provider传入这个URI来对数据进行操作。
网络存储:
从网络读取数据和写入数据。 Android提供了通过网络来实现数据的存储和获取的方法。
我们可以调用WebService返回的数据或是解析HTTP协议实现网络数据交互。
三十三.线程之间的通信方式(如何避免ANR)
(1). AsyncTask,其中doInBackground()和onPostExecute(Result)两个方法非常重要
doInBackground() 这个方法运行在后台线程中,主要负责执行那些很耗时的操作,如访问网络。该方法必须重写。
onPostExecute(Result) 这个方法运行于UI主线程,在doInBackground(Params…)方法执行后调用,该方法用于接收后台任务执行后返回的结果,刷新UI显示。
(2.)子线程 + handler
在子线程中执行完耗时操作需要刷新UI时,通过handler.sendMessage()发消息给主线程, 然后在主线程Handler中的handleMessage()方法中执行刷新UI操作。
三十四.Activity的生命周期?
七个,oncreate,onstart,onresume(重新开始),onpause(暂停),onstop(停止),onrestart,ondestroy,;(清楚整个周期的过程)
A-B(由A跳转到B) A先onpause到B运行oncreate onstart然后是onresume(获取焦点) 最后是A(失去焦点)运行onstop。
1).启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。
2).当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
3).当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
4).当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。
5).用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。
6).当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
7).用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。
Activity的任务栈?
先进后出
FragmentPageAdapter和FragmentPageStateAdapter的区别
FragmentPageAdapter在每次切换页面的的时候,是将Fragment进行分离,适合页面较少的Fragment使用以保存一些内存,对系统内存不会多大影响
FragmentPageStateAdapter在每次切换页面的时候,是将Fragment进行回收,适合页面较多的Fragment使用,这样就不会消耗更多的内存
三十六.Service(服务)和Thread(线程)的区别?
1).Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作。
2).Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。
Service是安卓中系统的组件,它运行在独立进程的主线程中,不可以执行耗时操作。Thread是程序执行的最小单元,分配CPU的基本单位,可以开启子线程执行耗时操作
Service在不同Activity中可以获取自身实例,可以方便的对Service进行操作。Thread在不同的Activity中难以获取自身实例,如果Activity被销毁,Thread实例就很难再获取得到
三十七.面向对象的特征?
封装
封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
继承
面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
多态
多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
说白了就是:同一个事件发生在不同的对象上会产生不同的结果。
实现多态,有二种方式,覆盖,重载。
覆盖,是指子类重新定义父类的虚函数的做法。
重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
方法的重载属于,编译时多态,方法名相同参数列表不同,返回值必须相同或都没有返回值类型。
方法的覆盖属于运行时多态,子类覆盖父类的方法,子类指向父类引用,在调用方法的时候用父类的引用调用。
多态存在的三个必要条件:
一、要有继承;
二、要有重写;
三、父类引用指向子类对象。
1.可替换性(substitutability)。多态对已存在代码具有可替换性
3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的
4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
三十八.Final Finally Finalized 区别?
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不
可继承。
finally 是异常处理语句结构的一部分,表示总是执行。
finalize 是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此
方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
三十九.NDK是什么?NDK 是 Native Development Kit 的简称。它是一个工具集,集成了 Android 的交叉编译环境,并提供了一套比较方便的 Makefile ,可以帮助开发者快速开发 C 或是 C++ 的动态库,并自动的将 so 和 java 程序打包成 apk ,在 Android 上运行。Android 上,应用程序的开发,大部分基于 Java 语言来实现。要使用 c 或是 c++ 的程序或库,就需要使用 NDK 来实现。
四十.安卓的系统架构?
应用层:使用Java语言进行开发的一些应用程序
应用框架层:主要是谷歌发布的一些操作支持的类库(API框架),开发人员可以使用这些类库方便的进行程序开发,但是在开发时必须遵守框架的开发原则
系统运行库层:当使用安卓框架层进行开发时,安卓操作系统会自动使用一些c/c++的库文件来支持所使用的各个组件,使其可以更好的为程序服务;
Linux内核层:安卓操作系统主要是基于Linux内核,程序的安全性,驱动程序,进程管理等都由Linux内核提供。
四十一.OnTouch和OnTouchEvent区别?1.onTouch方法:
onTouch方法是View的 OnTouchListener接口中定义的方法。
当一个View绑定了OnTouchLister后,当有touch事件触发时,就会调用onTouch方法。
(当把手放到View上后,onTouch方法被一遍一遍地被调用)
2.onTouchEvent方法:
onTouchEvent方法是override 的Activity的方法。
重写了Activity的onTouchEvent方法后,当屏幕有touch事件时,此方法就会别调用。
APP版本更新:
在清单文件更改版本号,上传更新的应用到平台,利用平台的更新提醒用户是否更新新版本。
数据库更新:
先更改版本号,在onupgress方法内判断版本号是否一致,不一致则更新数据库。
四十三.移动互联数据的交换格式?
移动互联数据交互格式有XML和JSON
共同点:
1.JSON和XML的数据可读性基本相同
2.JSON和XML同样拥有丰富的解析手段
Json的优势:3.JSON相对于XML来讲,数据的体积小
4.JSON与JavaScript的交互更加方便
5.JSON对数据的描述性比XML较差
6.JSON的速度要远远快于XML
四十四.线程相关?
定义:
线程被称为轻量级进程,是程序执行流的最小单元,是进程的一个实体。有就绪,阻塞,运行 三种基本状态。
多线程定义:
在单个程序中同时运行多个线程完成不同的工作。
线程和进程的区别:
进程定义:
进程是系统进行资源分配和调度的一个独立单位。
关系:
一个线程可以创建和撤销另一个线程,同一个进程中的多个线程可以同时并发执行,他可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行顺序
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。 (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
区别:
他们是不同的操作系统资源管理方式。
进程有独立的地址空间,一个进程崩溃后,不会对其他进程产生影响
线程只是一个进程中不同的执行路径,线程有自己的堆栈和局部变量,线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉, 所以多线程的操作要比多进程的程序健壮。 但在进程切换时耗费资源较大,效率要差一些
对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程,
(因为进程在切换时耗费的资源要大一些,效率差
进程的优先级?四十五.XML有几种解析方式?区别?
三种:DOM SAX PULL
DOM 将XML文件的所有内容读取到内存中,
优点是对文档增删改查比较方便,缺点占用内存比较大
SAX 是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备, 缺点是只适合做文档的读取,不适合做文档的增删改,不能中途停止。PULL 与SAX相似,可随时终止,调用next() 方法提取它们(主动提取事件)
四十六.访问网络如何加密?
1:对称加密(DES,AES)和非对称(RSA公钥与私钥),(支付宝里的商户的公钥和私钥)一般用到的HTTPS加密是结合对称加密和非对称加密来进行加密(利用对称加密的快捷性加密报文和非对称加密的安全性进行)
2:MD5(算法)
3:Base64
四十七.手机横竖屏切换时Activity生命周期的变化点击打开详情
2、运行Activity,得到如下信息
onCreate-->
onStart-->
onResume-->
3.切换成横屏时
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
4、再切换成竖屏时,发现打印了两次相同的log
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
5、修改AndroidManifest.xml,把该Activity添加
android:configChanges="orientation",切换横屏时生命周期运行一次。
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
6、再切换竖屏时,发现不会再打印相同信息,但多打印了一行onConfigChanged
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onConfigurationChanged-->
7、把步骤5的android:configChanges="orientation" 改成
android:configChanges="orientation|keyboardHidden",切换横屏时,就只打印
onConfigChanged
onConfigurationChanged-->
8、切换竖屏时
onConfigurationChanged-->
onConfigurationChanged-->
总结:
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,
切横屏时会执行一次,切竖屏时会执行两次
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调
用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges="orientation|keyboardHidden"时,
切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
总结一下整个Activity的生命周期
补充一点,当前Activity产生事件弹出Toast和AlertDialog的时候Activity的生命
周期不会有改变
Activity运行时按下HOME键(跟被完全覆盖是一样的):onSaveInstanceState -->
onPause --> onStop onRestart -->onStart--->onResume
Activity未被完全覆盖只是失去焦点:onPause--->onResume
onSavedInstanceState()和onRestoreInstanceState()并不是activity生命周期的方法。
onSaveInstanceState()会在onPause()或onStop()之前执行,onRestoreInstanceState()会在onStart()和onResume()之间执行。
onSaveInstanceState()需要调用的时,activity可能销毁,也可能没有销毁,只有在activity销毁重建的时候onRestoreInstanceState()才会调用。
四十八.JNI与NDK的区别?
JNI的作用:
扩展:JNI扩展了JVM能力,驱动开发,例如开发一个wifi驱动,可以将手机设置为无限路由;
高效: 本地代码效率高,游戏渲染,音频视频处理等方面使用JNI调用本地代码,C语言可以灵活操作内存;
复用: 在文件压缩算法 7zip开源代码库,机器视觉 OpenCV开放算法库等方面可以复用C平台上的代码,不必在开发一套完整的Java体系,避免重复发明轮子;
特殊: 产品的核心技术一般也采用JNI开发,不易破解;
JNI在Android中的作用:
JNI可以调用本地代码库(即C/C++代码),并通过 Dalvik 虚拟机与应用层和应用框架层进行交互,Android中JNI代码主要位于应用层和应用框架层;
应用层: 该层是由JNI开发,主要使用标准JNI编程模型;
应用框架层: 使用的是Android中自定义的一套JNI编程模型,该自定义的JNI编程模型弥补了标准JNI编程模型的不足;
四十九.CMake的理解?
CMake是什么?
CMake 是一个开源的跨平台自动化构建系统
1、HandlerThread产生背景
当系统有多个耗时任务需要执行时,每个任务都会开启一个新线程去执行耗时任务,这样会导致系统多次创建和销毁线程,从而影响性能。为了解决这一问题,Google提供了HandlerThread,HandlerThread是在线程中创建一个Looper循环器,让Looper轮询消息队列,当有耗时任务进入队列时,则不需要开启新线程,在原有的线程中执行耗时任务即可,否则线程阻塞。
2、HanlderThread的特点、
HandlerThread本质上是一个线程,继承自Thread
HandlerThread有自己的Looper对象,可以进行Looper循环,可以创建Handler
HandlerThread可以在Handler的handlerMessage中执行异步方法
HandlerThread优点是异步不会堵塞,减少对性能的消耗
HandlerThread缺点是不能同时继续进行多任务处理,需要等待进行处理,处理效率较低
HandlerThread与线程池不同,HandlerThread是一个串行队列,背后只有一个线程。
五十二.String buffer 与string builder 的区别?
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
三者在执行速度方面的比较:StringBuilder > StringBuffer > String
五十三.Java中的四种引用?
强 软 弱 虚
强引用
只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象;
软引用
软引用是用来描述一些有用但并不是必需的对象,只有在内存不足的时候JVM才会回收该对象。
弱引用
弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。
虚引用
虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。
五十四. TCP四次挥手?
所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,
五十五. Android线程产生死锁的四个必要条件?
就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
处理死锁的方法:*死锁预防:通过设置某些限制条件,去破坏死锁的四个条件中的一个或几个条件,来预防发生死锁。但由于所施加的限制条件往往太严格,因而导致系统资源利用率和系统吞吐量降低。
*死锁避免:允许前三个必要条件,但通过明智的选择,确保永远不会到达死锁点,因此死锁避免比死锁预防允许更多的并发。
*死锁检测:不须实现采取任何限制性措施,而是允许系统在运行过程发生死锁,但可通过系统设置的检测机构及时检测出死锁的发生,并精确地确定于死锁相关的进程和资源,然后采取适当的措施,从系统中将已发生的死锁清除掉。
*死锁解除:与死锁检测相配套的一种措施。当检测到系统中已发生死锁,需将进程从死锁状态中解脱出来。常用方法:撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程。死锁检测盒解除有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。
五十六.View SurfaceView GLsurfaceView的区别与联系?
在2D游戏开发中,大致可以分为两种游戏框架,View和SurfaceView。
View和SurfaceView区别:
View:必须在UI的主线程中更新画面,用于被动更新画面。
surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面。
GLSurfaceView:基于SurfaceView视图再次进行拓展的视图类,专用于3D游戏开发的视图;是SurfaceView的子类,openGL专用。