Android面试总结(持续更新修改)

###Android面试总结(持续更新修改)

1.Android 的四大组件是哪些,它们的作用/strong>
①Activity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各界面的状态,做很多持久化的事情,妥善管理生命周期以及一些跳转逻辑
②service:后台服务于 Activity,封装一个完整的功能逻辑实现,接受上层指令,完成相关的事物
③Content Provider:是 Android 提供的第三方应用数据的访问方案,可以派生 Content Provider 类,对外提供数据,可以像数据库一样进行选择排序,屏蔽内部数据的存储细节,向外提供统一的接口模型,大大简化上层应用,对数据的整合提供了更方便的途径
④BroadCastReceiver:接受一种或者多种Intent作触发事件,接受相关消息,做一些简单处理,转换成一条Notification,统一了 Android 的事件广播模型

2.Activity的生命周期,及每个周期的应用场景
比如说手机卫士每次进入某个界面的时候都要看到最新的数据,这个刷新列表的操作 就放在onStart()的方法里面.这样保证每次用户看到的数据都是最新的.
多媒体播放, 播放来电话.
onStop() 视频,
视频声音设置为0 , 记录视频播放的位置 mediaplayer.pause();
onStart() 根据保存的状态恢复现场. mediaplayer.start()

3.Activity的四种启动模式分别是什么,以及他们的特点
意义在于 : 记录这些activity开启的先后顺序,google引入任务栈(task stack)概念,帮助维护好的用户体验。
①standard 默认标准的启动模式, 每次startActivity都是创建一个新的activity的实例。
适用于绝大大数情况
②singleTop 单一顶部,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,而是调用 onNewIntent() 方法。应用场景: 浏览器书签。 避免栈顶的activity被重复的创建,解决用户体验问题。
③singletask 单一任务栈 ,activity只会在任务栈里面存在一个实例。如果要激活的activity,在任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity,调用 onNewIntent() 方法,并且清空这个activity任务栈上面所有的activity 应用场景:浏览器activity, 整个任务栈只有一个实例,节约内存和cpu的目的注意: activity还是运行在当前应用程序的任务栈里面的。不会创建新的任务栈。
④singleInstance 单态 单例模式单一实例,整个手机操作系统里面只有一个实例存在。不同的应用去打开这个activity共享 公用的同一个activity。他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。

5.你后台的Activity被系统 回收怎么办/strong>
答:重写onSaveInstanceState()方法,在此方法中保存需要保存的数据,该方法将会在activity被回收之前调用。通过重写 onRestoreInstanceState()方法可以从中提取保存好的数据

6.Fragment生命周期是什么/strong>
onAttach() – onCreate() – onCreateView()- onActivitCreated – onStart() – onResume() – onPause()
onStop() – onDestoryView() – onDestory() – onDetach()

7.Activity和Fragment如何进行通信,Activity之间通信有几种方式
①Activity向Fragment传递数据 :
一 通过bundle设置参数Bundle bundle = new Bundle();bundle.putString(“name”,“加多宝”);sf.setArguments(bundle);
二 通过调用接口设置接口 让被接收数据方 实现该方法让发送方调用该接口
②Fragment 向 A ctivity 传递数据 :
一 通过 getActivity 强转成 需要接收数据的Activity 调用其方法 ;
二 通过接口 还可以利用 sp sqLite 等
③Activity之间传递数据:通过全局application类共享数据;通过Intent传值;使用静态变量传递数据;使用剪切板传递数据;

8.Service 的生命周期(两种)/strong>
①onCreate – onStartCommand(每次开启都要执行,可以执行多次) – onDestory()——-只要不执行方法onStop(),在内存中永远驻留
②onCreate – onBind(只能执行一次) – onUnbind() – onDestory()——-依赖于Activity,随着Activity的销毁而关闭
注意:同一个服务可以被开启多次,但是关闭只需要一次

9.如何开机就启服务/strong>
通过广播接收者监听开机广播然后在onReceive(Context context, Intent intent)方法 里开启相应的服务

10.Service是否在mainThread中执行, service里面是否能执行耗时的操作/strong>
是 不能

11.Service和IntentService的区别/strong>
Service主要用于后台服务,当应用程序被挂到后台的时候,为了保证应用某些组件仍然可以工作而引入了Service这个概念,那么这里面要强调的是Service不是独立的进程,也不 是独立的线程,它是依赖于应用程序的主线程的,在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR。IntentService是继承Service的,那么它包含了Service的全部特性,当然也包含service的生命周期,那么与service不同的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去执行耗时操作

12.广播的两种注册方式/strong>
①清单文件注册

②代码注册
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
filter.addAction(Intent.ACTION_MEDIA_EJECT);
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addDataScheme(“file”);
sdcardStateReceiver = new SdcardStateChanageReceiver();
registerReceiver(sdcardStateReceiver,filter);

13.IPC(Inter-Progress-Communication)哪些方式述AIDL
Messenger Socket AIDL ContentProvider Intent

14.数据存储几种方式别是什么/strong>
Android 提供了 5 种方式存储数据:
①使用 SharedPreferences 存储数据:它是 Android 提供的用来存储一些简单配置信息的一种机制,采用了 XML 格式将数据存储到设备中。只能在同一个包内使用,不能在不同的包之间使用。
②文件存储数据:文件存储方式是一种较常用的方法,在 Android 中读取/写入文件的方法,与 Java 中实现 I/O 的程序是完全一样的,提供了 openFileInput()和
openFileOutput()方法来读取设备上的文件。
③SQLite 数据库存储数据:SQLite 是 Android 所带的一个标准的数据库,它支持SQL 语句,它是一个轻量级的嵌入式数据库。
④使用 ContentProvider 存储数据:主要用于应用程序之间进行数据交换,从而能够让其他的应用保存或读取此 Content Provider 的各种数据类型
⑤ 络存储数据:通过 络上提供给我们的存储空间来上传(存储)和下载(获取)我们存储在 络空间中的数据信息。

15.listView的优化
①第一层: 复用converterView
if(converterView==null) {
converterView = View.inflate(R.layout.xxx); 10–>11
}
问题: 每次执行getView()都需要执行converterView.findViewById()得到子View
②第二层: 使用ViewHolder, 减少findViewById()的次数
③第三层: 对数据列表进行分页加载显示
1). 自己做: 通过Scroll监听listView.setonScrollListener(scrollListener), 当到达底部时加载下一页列表数据并显示
2). 使用第方开源框架: Android-PullToRefresh或其它
④第四层优化: 图片级缓存处理 参见图片级缓存机制
⑤Item布局,层级越少越好,使用hierarchyview工具查看优化。
⑥item中图片时,异步加载
⑦快速滑动时,不加载图片、
⑧item中图片时,应对图片进行适当压缩

16.简述三级缓存的实现/strong>
例如: 如何根据url根据图片显示br> ①根据url从一级缓存(Map)中取图片对象, 如果取到了, 直接显示 注意: 真实项目中使用LruCache来缓存图片
②如果没, 根据url中包含图片名称(文件名), 手机的sd卡或内部找对就图片文件加载成bitmap如果找到了, 显示并保存到一级缓存
③ 如果没, 显示一个默认的图片, 根据url联 请求获取bitmap如果没, 显示一张代表错误的图片 如:
a. 保存到一级缓存 b. 保存到二级缓存 c. 显示图片

17.简述Handler运行原理
andriod提供了 Handler 和 Looper 来满足线程间的通信。Handler 先进先出原则。
Looper类用来管理特定线程内对象之间的消息交换(Message Exchange)。
1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列)。
2)Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;或者接收Looper从Message Queue取出)所送来的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。
4)线程:UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。
总结:默认主线程中维护了一个Looper,而Looper中维护了MessageQueue消息池。Looper通过死循环一直检测消息池是否有消息进来,如果有则交给Handler处理。而Handler就是当时发送消息进来的对象

18.AsycTask主要用到哪些方法们分别运行在哪个线程/strong>
onPreExecute()在主线程中执行异步开始前调用做一些准备工作
doInBackground(Params…params)分线程,…可以通过publishProgress来更新任务
onProgressUpdate(Progress…values)主线程中执行后台任务
onPostExecute(Result result) 主,异步任务执行之后
onCancelled 主当异步任务取消的时候会被调用这个时候onPostExecute(将不再被调用)

19.图片的加载与优化(还可以说颜色值的更改 三级缓存等)
把整张图片加载到内存中还是加载一个压缩版的图片到内存中。以下几个因素是我们需要考虑的:
? 预估一下加载整张图片所需占用的内存。
? 为了加载这一张图片你所愿意提供多少内存。
? 用于展示这张图片的控件的实际大小。
? 当前设备的屏幕尺寸和分辨率。

20.Android中常用的五种布局分别是什么/strong>
LinearLayout线性布局;AbsoluteLayout绝对布局;TableLayout表格布局;RelativeLayout相对布局;FrameLayout帧布局

21.dp,px,sp区别及使用场景
①px (pixels)(像素:屏幕上的点 ,与密度相关。密度大了,单位面积上的px会比较多。
②dip或dp(与密度无关的像素。一种基于屏幕密度的抽象单位。设置一些view的宽高可以用这个,一般情况下,在不同分辨率,都不会有缩放的感觉。
③sp(与刻度无关的像素放大像素– 主要处理字体的大小。

22.gravity和layout_gravity的区别
android:gravity 属性是对该view中内容的限定.比如一个button 上面的text. 你可以设置该text 相对于view的靠左,靠右等位置.也可以在父布局控制所有子布局的位置
android:layout_gravity是用来设置该view相对与父view 的位置.比如一个button 在linearlayout里,你想把该button放在linearlayout里靠左靠右等位置就可以通过该属性设置

23.Padding和Margin什么区别
Padding 文字对边框, margin是控件对父窗体.Margin:一个控件与另一个控件之间的间距
Padding:一个控件的内容与边框之间间距

24.自定义view的流程(常用的方法以及作用)
继承View完全自定义或继承View的派生子类 定义自定义属性
获取自定义属性 添加属性和事件 自定义测量 重写onMesure
系统帮我们测量的高度和宽度都是MATCH_PARNET,当我们设置明确的宽度和高度时,系统帮我们测量的结果就是我们设置的结果,当我们设置为WRAP_CONTENT,或者MATCH_PARENT系统帮我们测量的结果就是MATCH_PARENT的长度。
所以,当设置了WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法”:
重写之前先了解MeasureSpec的specMode,一共三种类型:
EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
UNSPECIFIED:表示子布局想要多大就多大,很少使用
自定义绘制
绘制自定义视图里最重要的一步是重写onDraw()方法. onDraw()的参数是视图可以用来绘制自己的Canvas对象. Canvas定义用来绘制文本、线条、位图和其他图像单元. 你可以在onDraw()里使用这些方法创建你的自定义用户界面(UI).
android.graphics框架把绘图分成了两部分:
l 画什么, 由Canvas处理
l 怎么画, 由Paint处理
例如, Canvas提供画线条的方法, 而Paint提供定义线条颜色的方法. Canvas提供画矩形的方法, 而Paint定义是否用颜色填充矩形或让它为空. 简而言之, Canvas定义你可以在屏幕上画的形状, 而Paint为你画的每个形状定义颜色、样式、字体等等.
onDraw()不提供3d图形api的支持。如果你需要3d图形支持,必须继承SurfaceView而不是View,并且通过单独的线程画图。

降低刷新频率
为了提高view的运行速度,减少来自于频繁调用的程序的不必要的代码。从onDraw()方法开始调用,这会给你带来最好的回 。特别地,在onDraw()方法中你应该减少冗余代码,冗余代码会带来使你view不连贯的垃圾回收。初始化的冗余对象,或者动画之间的,在动画运行时,永远都不会有所贡献。
加之为了使onDraw()方法更有依赖性,你应该尽可能的不要频繁的调用它。大部分时候调用 onDraw()方法就是调用invalidate()的结果,所以减少不必要的调用invalidate()方法。有可能的,调用四种参数不同类型的invalidate(),而不是调用无参的版本。无参变量需要刷新整个view,而四种参数类型的变量只需刷新指定部分的view.这种高效的调用更加接近需求,也能减少落在矩形屏幕外的不必 要刷新的页面。

25.View中的RequestLayout()和invalidate()区别nvaldate()和postInvalidate()区别/strong>
requestLayout:当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent view重新调用他的onMeasure onLayout来对重新设置自己位置。
特别的当view的layoutparameter发生改变,并且它的值还没能应用到view上,这时候适合调用这个方法。
invalidate:View本身调用迫使view重画。是在UI线程自身使用。
postInvalidate:是在非UI线程使用。

26.SufaceView和View的区别/strong>
surfaceView是在一个新起的单独线程中可以重新绘制画面,
而View必须在UI的主线程中更新画面。
那么在UI的主线程中更新画面,那么你的主UI线程会被你正在画的函数阻塞。当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中 thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。

27.简述事件分发
http://www.cnblogs.com/linjzong/p/4191891.html

28.recycleView分类型使用哪个方法/strong>
public int getItemViewType(int position);

27.H5和WebView如何实现交互/strong>
①如果向h5里传数据:
首先设置settings.setJavaScriptEnabled(true);
wv.loadUrl(“javascript:javacalljswithargs(” + name + “)”);
②如果让h5调用java方法:
也必须先设置settings.setJavaScriptEnabled(true);
wv.addJavascriptInterface(this, “wst”);
把自身传给h5然后调用相应的方法即可
Java方法上要加注解@JavascriptInterface

28.如何实现图文混排/strong>
①Html.fromHtml(sb.toString(),imageGetter , null)
②SpannableStrinbBuilder

29.Android的5.0,6.0,7.0的新特性哪些/strong>
①5.0
采用了 Google 最新推行的 Material Design 设计语言 比如RecyleView控件等 加入了阴影
锁屏通知
多用户设备共享相关功能 (类似windows的多用户)
支持 64 位 ARM、X86 和 MIPS 架构 SoC 的 Android 操作系统。
迁移数据的功能
拍照图片保存RAW格式
重启保留后台应用
②6.0(HTTP PDF)
App Permissions(软件权限管理)
Chrome Custom Tabs( 页体验提升)
Android Pay(安卓支付)
Fingerprint Support(指纹支持)
去除httpClient
USB Type-C端口支持
DataBinding 数据绑定
③7.0
安卓7.0加入了全新的API,支持第三方应用通知的快捷操作和回复,例如来电会以横幅方式在屏幕顶部出现,提供接听/挂断两个按钮;信息/ 交类应用通知,还可以直接打开键盘,在输入栏里进行快捷回复。

流量保护模式
安卓7.0新增的流量保护模式不仅可以禁止应用在后台使用流量,还会进一步减少该应用在前台时的流量使用。其具体实现原理目前尚不清楚,推测其有可能使用了类似Chrome浏览器的数据压缩技术。

谷歌还扩展了ConnectivityManager API的能力,使得应用可以检测系统是否开启了流量保护模式,或者检测自己是否在白名单中。安卓7.0允许用户单独针对每个应用,选择是否开启数据保护模式
超快应用安装速度
安卓7.0中采用了一项具有实时代码剖析功能的ARI JIT编译器,它能够在安卓应用程序在运行时不断提高自身的性能,其带来的另一项优势就是能够为应用安装引入一种新的“快速通道”(quick path),能够大大加快应用安装和系统更新的速度,即便是那些大型的应用程序如游戏,在安卓6.0中需要几分钟时间才能安装和优化完成的,在安卓7.0中仅仅需要几秒钟就可以搞定。同时,因为省去了一些优化步骤,安卓7.0的系统更新速度也会大大提升。

Android N正式支持Vulkan API,包括其全部特性,尤其是能够大大降低CPU系统开销,提升描绘指令(Draw Call),当然也支持预编译着色器,这对于应用、游戏开发无疑是个大好消息。

安全方面,Android N将会支持基于文件的加密、媒体框架硬化、无缝升级,特别是最后一点,Android N会使用两个系统镜像来确保OTA更新顺利、安全。

④8.0
通知渠道 — Notification Channels
通知渠道是由应用自行定义的通知内容类别,借助渠道,开发者可以让用户对不同种类的通知进行精细控制,用户可以单独拦截或更改每个渠道的行为,而不是统一管理应用的所有通知。

画中画模式 — PIP
Android O 现已支持 Activity 的画中画模式。PIP 是一种多窗口显示模式,多用于视频播放,即你可以一边发微信一边看视频。

自适应图标 — Adaptive Icons

固定快捷方式和小部件 — Pinning shortcuts
30.这是一张数据库表(表名user 字段(id,name任意插入一条数据和修改id为1的姓名为美女br> Insert into user(id,name) values(1,”zhangsan”)
update table user set username =”美女” where id=1

31.什么是ANR何避免它br> ①什么事ANRbr> 在android上,如果你的应用程序有一段时间响应不移灵敏,系统会向用户提示“应用程序无响应”(ANR:application Not Responding)对话框。因此,在程序里对响应性能的设计很重要,这样,系统不会显示ANR给用户。
分类:
KeyDispatchTimeout(5 seconds) –主要是类型按键或触摸事件在特定时间内无响应
BroadcastTimeout(10 seconds) –BroadcastReceiver在特定时间内无法处理完成
ServiceTimeout(20 secends) –小概率事件 Service在特定的时间内无法处理完成
②如何避免:
UI线程尽量只做跟UI相关的工作
耗时的操作(比如数据库操作,I/O,连接 络或者别的有可能阻塞UI线程的操作)把它放在单独的线程处理
尽量用Handler来处理UIThread和别的Thread之间的交互

32.Anadroid动画一共有几种们的区别是什么br> ①补间动画(Tween):这种实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化
②帧动画(Frame):传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影
③属性动画():属性动画可以对任意对象的属性做修改

33.Android中哪些情况会导致内存泄漏和内存溢出br> ①加载大图片时会内存溢出
②Android应用内存泄漏的的原因有以下几个:(abrcc)
查询数据库后没有关闭游标cursor
构造Adapter时,没有使用 convertView 重用
Bitmap对象不在使用时调用recycle()释放内存
对象被生命周期长的对象引用,如activity被静态集合引用导致activity不能释放
注册没取消造成的内存泄漏

34.说说MVC和MVP的原理和他们的区别/p>

01.Model
Model层代表了描述业务逻辑和数据的一系列类的集合。它也定义了数据修改和操作的业务规则。
02.View
View代表了UI组件他只负责展示从Presenter接收到的数据。也就是把模型(译者注:非Modle层模型)转化成UI。
03.Presenter
Presenter负责处理View背后所有的UI事件。它通过View接收用户输入,之后利用Model来处理用户的数据,最后把结果返回给View。与View和Controller不同,View和Presenter之间是完全解耦的,他们通过接口来交互。另外,presenter不像controller处理进入的请求。

这个模式被普遍的引用于ASP.NET Web Forms 应用程序。并且也应用于windows form。

MVC即Model-VIew-Controller。他是1970年代被引入到软件设计大众的。MVC模式致力于关注点的切分,这意味着model和controller的逻辑是不与用户界面(View)挂钩的。因此,维护和测试程序变得更加简单容易。
MVC设计模式将应用程序分离为3个主要的方面:Model,View和Controller
01.Model
Model代表了描述业务路逻辑,业务模型、数据操作、数据模型的一系列类的集合。这层也定义了数据修改和操作的业务规则。
02.View
View代表了UI组件。他只负责展示从controller接收到的数据。也就是把model转化成UI。
03.Controller
Controll负责处理流入的请求。它通过View来接受用户的输入,之后利用Model来处理用户的数据,最后把结果返回给View。Controll就是View和Model之间的一个协调者。

其实最明显的区别就是,MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成。还有一点就是Presenter与View之间的交互是通过接口的。

35.如何优化APK
1、代码
(1保持良好的编程习惯,不要重复或者不用的代码
(2谨慎添加libs,移除使用不到的libs。
(3使用proguard混淆代码,它会对不用的代码做优化,并且混淆后也能够减少安装包的大小。
(4native code的部分,大多数情况下只需要支持armabi与x86的架构即可。如果非必须,可以考虑拿掉x86的部分。

2、资源
(1使用Lint工具查找没有使用到的资源。去除不使用的图片,String,XML等等。
(2assets目录下的资源请确保没有用不上的文件。
(3生成APK的时候,aapt工具本身会对png做优化,但是在此之前还可以使用其他工具如tinypng对图片进行进一步的压缩预处理。
(4jpg还是png,根据需要做选择,在某些时候jpg可以减少图片的体积。
(5对于9.png的图片,可拉伸区域尽量切小,另外可以通过使用9.png拉伸达到大图效果的时候尽量不要使用整张大图。

3、策略
(1择性的提供hdpi,xhdpi,xxhdpi的图片资源。建议优先提供xhdpi的图片,对于mdpi,ldpi与xxxhdpi根据需要提供有差异的部分即可。
(2尽可能的重用已的图片资源。例如对称的图片,只需要提供一张,另外一张图片可以通过代码旋转的方式实现。
(3能用代码绘制实现的功能,尽量不要使用大量的图片。例如减少使用多张图片组成animate-list的AnimationDrawable,这种方式提供了多张图片很占空间。

4、图片优化 : https://tinypng.com/
(1tinypng是一个支持压缩png和jpg图片格式的 站,通过其独特的算法(通过一种叫“量化”的技术,把原本png文件的24位真彩色压缩为8位的索引演示,是一种矢量压缩方法,把颜色值用数值123等代替。)可以实现在无损压缩的情况下图片文件大小缩小到原来的30%-50%。
(2需要说明的是:tinypng支持png和jpg图片的压缩,并且也支持9图的压缩。
(3tinypng的缺点是在压缩某些带有过渡效果(带alpha值)的图片时,图片会失真,这种图片可以将png图片转换为下面介绍的webP格式,可以在保证图片质量的前提下大幅缩小图片的大小。

5、使用webP图片格式:https://developers.google.com/speed/webp/
(1WebP是谷歌研发出来的一种图片数据格式,它是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。目前很多公司已经将webP技术运用到Android APP中,比如FaceBook、腾讯、淘宝。webP相比于png最明显的问题是加载稍慢,不过现在的智能设备硬件配置越来越高,这都不是事儿。
(2假如你打算在 App 中使用 WebP,除了 Android4.0 以上提供的原生支持外,其他版本以可以使用官方提供的解析库webp-android-backport编译成so使用。
(3通常UI提供的图片都是png或者jpg格式,我们可以通过智图或者isparta将其它格式的图片转换成webP格式,isparta可实现批量转换,墙裂推荐!

6、使用tintcolor实现按钮反选效果:
通常钮的正反旋图片我们都是通过提供一张按钮正常图片和一张按钮反选图片,然后通过selector实现,两张图片除了alpha值不一样外其它的内容都是重复的,在Android 5.0及以上的版本可以通过tintcolor实现只提供一张按钮的图片,在程序中实现按钮反选效果,前提是图片的内容一样,只是正反选按钮的颜色不一样。

37.项目中你都用到了哪种加密方式如何使用的br> 对称加密 非对称加密 base64 md5

38.简述HTTP 请求头都哪些表什么意思何发送数据到服务器/p>

39.如何优化WebViewbr> WebView缓存
资源文件本地存储
先加载 页后加载图片
加快HTML 页装载完成的速度
自定义出错界面
是否存在滚动条
远程 页需访问本地资源
ViewPager里非首屏WebView点击事件不响应
WebView硬件加速导致页面渲染闪烁
避免addJavaScriptInterface带来的安全问题
关于web页面如何通知WebView

WebView缓存
开启WebView的缓存功能可以减少对服务器资源的请求,一般使用默认缓存策略就可以了。

//设置 缓存模式
w
webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);

// 开启 DOM storage API 功能
w
webView.getSettings().setDomStorageEnabled(true);

资源文件本地存储
资源等文件(不需要更新)本地存储,在需要的时候直接从本地获取。哪些资源需要我们去存储在本地呢,当然是一些不会被更新的资源,例如图片文件,js文件,css文件,替换的方法也很简单,重写WebView的方法即可。
{

}
}

appRm为app资源管理器,读取drawable,assets,raw下的资源,都是android系统的一些很简单的函数调用。
getInputStream的参数代表资源具体位置
WebResourceResponse后的资源类型需要写正确

先加载 页后加载图片
首先阻塞 络图片的加载
mContentWV.getSettings().setBlockNetworkImage(true);
然后在 页加载完毕时加载图片
@Override
public void onPageFinished(WebView view, String url) {

加快HTML 页装载完成的速度

public void int () {
if(Build.VERSION.SDK_INT >= 19) {
webView.getSettings().setLoadsImagesAutomatically(true);
} else {
webView.getSettings().setLoadsImagesAutomatically(false);
}
}

同时在WebView的WebViewClient实例中的onPageFinished()方法添加如下代码:

@Override
public void onPageFinished(WebView view, String url) {
if(!webView.getSettings().getLoadsImagesAutomatically()) {
webView.getSettings().setLoadsImagesAutomatically(true);
}
}

从上面的代码,可以看出我们对系统API在19以上的版本作了兼容。因为4.4以上系统在onPageFinished时再恢复图片加载时,如果存在多张图片引用的是相同的src时,会只有一个image标签得到加载,因而对于这样的系统我们就先直接加载。

自定义出错界面

当WebView加载页面出错时(一般为404 NOT FOUND),安卓WebView会默认显示一个卖萌的出错界面。但我们怎么能让用户发现原来我使用的是 页应用呢,我们期望的是用户在 页上得到是如原生般应用的体验,那就先要从干掉这个默认出错页面开始。当WebView加载出错时,我们会在WebViewClient实例中的onReceivedError()方法接收到错误,我们就在这里做些手脚:

@Override
public void onReceivedError (WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
loadDataWithBaseURL(null, “”, “text/html”, “utf-8”, null);
mErrorFrame.setVisibility(View.VISIBLE);
}

从上面可以看出,我们先使用loadDataWithBaseURL清除掉默认错误页内容,再让我们自定义的View得到显示(mErrorFrame为蒙在WebView之上的一个LinearLayout布局,默认为View.GONE)。

3.是否存在滚动条

当我们做类似上拉加载下一页这样的功能的时候,页面初始的时候需要知道当前WebView是否存在纵向滚动条,如果有则不加载下一页,如果没有则加载下一页直到其出现纵向滚动条。首先继承WebView类,在子类添加下面的代码:

public boolean existVerticalScrollbar () {
return computeVerticalScrollRange() > computeVerticalScrollExtent();
}

computeVerticalScrollRange得到的是可滑动的最大高度,computeVerticalScrollExtent得到的是滚动把手自身的高,当不存在滚动条时,两者的值是相等的。当有滚动条时前者一定是大于后者的。

是否已滚动到页面底部

同样我们在做上拉加载下一页这样的功能时,也需要知道当前页面滚动条所处的状态,如果快到底部,则要发起 络请求数据更新 页。同样继承WebView类,在子类覆盖onScrollChanged方法,具体如下:

@Override
protected void onScrollChanged(int newX, int newY, int oldX, int oldY) {
super.onScrollChanged(newX, newY, oldX, oldY);
if (newY != oldY) {
float contentHeight = getContentHeight() * getScale();
// 当前内容高度下从未触发过, 浏览器存在滚动条且滑动到将抵底部位置
if (mCurrContentHeight != contentHeight && newY > 0 && contentHeight // TODO Something…
mCurrContentHeight = contentHeight;
}
}
}

上面mCurrContentHeight用于记录上次触发时的 页高度,用来防止在 页总高度未发生变化而目标区域发生连续滚动时会多次触发TODO,mThreshold是一个阈值,当页面底部距离滚动条底部的高度差

远程 页需访问本地资源

当我们在WebView中加载出从web服务器上拿取的内容时,是无法访问本地资源的,如assets目录下的图片资源,因为这样的行为属于跨域行为(Cross-Domain),而WebView是禁止的。解决这个问题的方案是把html内容先下载到本地,然后使用loadDataWithBaseURL加载html。这样就可以在html中使用 file:///android_asset/xxx.png 的链接来引用包里面assets下的资源了。示例如下:

private void loadWithAccessLocal(final String htmlUrl) {
new Thread(new Runnable() {
public void run() {
try {
final String htmlStr = NetService.fetchHtml(htmlUrl);
if (htmlStr != null) {
TaskExecutor.runTaskOnUiThread(new Runnable() {
@Override
public void run() {
loadDataWithBaseURL(htmlUrl, htmlStr, “text/html”, “UTF-8”, “”);
}
});
return;
}
} catch (Exception e) {
Log.e(“Exception:” + e.getMessage());
}

TaskExecutor.runTaskOnUiThread(new Runnable() {
@Override
public void run() {
onPageLoadedError(-1, “fetch html failed”);
}
});
}
}).start();
}

上面几点需要注意:

从 络上下载html的过程应放在工作线程中
html下载成功后渲染出html的步骤应放在UI主线程,不然WebView会 错
html下载失败则可以使用我们前面讲述的方法来显示自定义错误界面

ViewPager里非首屏WebView点击事件不响应

如果你的多个WebView是放在ViewPager里一个个加载出来的,那么就会遇到这样的问题。ViewPager首屏WebView的创建是在前台,点击时没有问题;而其他非首屏的WebView是在后台创建,滑动到它后点击页面会出现如下错误日志:

20955-20968/xx.xxx.xxx E/webcoreglue﹕ Should not happen: no rect-based-test nodes found

解决这个问题的办法是继承WebView类,在子类覆盖onTouchEvent方法,填入如下代码:

@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onScrollChanged(getScrollX(), getScrollY(), getScrollX(), getScrollY());
}
return super.onTouchEvent(ev);
}

该方法的最先提出在WebView in ViewPager not receive user inputs。

WebView硬件加速导致页面渲染闪烁

4.0以上的系统我们开启硬件加速后,WebView渲染页面更加快速,拖动也更加顺滑。但有个副作用就是,当WebView视图被整体遮住一块,然后突然恢复时(比如使用SlideMenu将WebView从侧边滑出来时),这个过渡期会出现白块同时界面闪烁。解决这个问题的方法是在过渡期前将WebView的硬件加速临时关闭,过渡期后再开启,代码如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

避免addJavaScriptInterface带来的安全问题

使用开源项目Safe Java-JS WebView Bridge可以很好替代addJavaScriptInterface方法,同时增加了异步回调等支持,并且不存在了安全风险。

@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean ret = super.onTouchEvent(ev);
if (mPreventParentTouch) {
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
requestDisallowInterceptTouchEvent(true);
ret = true;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
requestDisallowInterceptTouchEvent(false);
mPreventParentTouch = false;
break;
}
}
return ret;
}

public void preventParentTouchEvent () {
mPreventParentTouch = true;
}

代码控制的关键在于mPreventParentTouch这个变量,mPreventParentTouch默认为false,当用户touchdown页面元素时通知该WebView将mPreventParentTouch设置为true。示意代码如下:

关于web页面如何通知WebView(即调用Java方法)请参看第8条。

刚提到了上面是一种简单的做法,并不能很好的解决手指滑动过快带来的误操作问题,即当用户快速地滑动时,还是有一定机率会出现ViewPager拦截TouchMove事件而发生了Tab切换而非页面元素做出了响应。要完美解决此问题,就要用到稍微复杂一点的方法(仅是整体消息传递流程复杂一点)。

首先假设在ViewPager之上还有一个父元素叫做ParentViewOnViewPager,当我们接收到页面preventParentTouchEvent通知时就先于ViewPager而进行拦截。如下:
ParentViewOnViewPager.java

public class ParentViewOnViewPager extends FrameLayout {
private MineWebView mDispatchWebView;

public void preventParentTouchEvent (WebView view) {
mDispatchWebView = (MineWebView)view;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_MOVE && mDispatchWebView != null) {
mDispatchWebView.ignoreTouchCancel(true);
return true;
}
return false;
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
if (mDispatchWebView != null){
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
mDispatchWebView.onTouchEvent(ev);
break;
default:
mDispatchWebView.ignoreTouchCancel(false);
mDispatchWebView.onTouchEvent(ev);
mDispatchWebView = null;
break;
}
return true;
}
return super.onTouchEvent(ev);
}
}

即当ParentViewOnViewPager接收到通知时,发起TouchEvent拦截,将拦截到的Touch事件转嫁到装载页面的mDispatchWebView进行事件派发。这样就直接跳过了ViewPager这一层。这里需要注意的是当ParentViewOnViewPager发起拦截时,WebView会接收到一个TouchCancel事件,WebView应该忽略这个事件,以避免页面接收到这个事件而打断整个处理流程。如下代码所示:
MineWebView.java

public class MineWebView extends WebView {
boolean mIgnoreTouchCancel;

public void ignoreTouchCancel (boolean val) {
mIgnoreTouchCancel = val;
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
return ev.getAction() == MotionEvent.ACTION_CANCEL && mIgnoreTouchCancel || super.onTouchEvent(ev);
}
}

另外针对这种解决方案,页面端的JS脚本不用做任何变动。

42.如何优化布局br> 1、场景:些布局会隐藏显布局会展示

把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。

2、替换方式:
推荐的做法是使用android.view.ViewStub,ViewStub是一个轻量级的View,使用非常简单:
mViewStub = (ViewStub) this.findViewById(R.id.viewstub);
mViewStub.inflate();
它是一个占用资源非常小的控件,相当于一个“占位控件”。使用时可以为ViewStub指定一个布局,在Inflate布局的时候,只有ViewStub会被初始化,然后当ViewStub被设置为可见的时或调用了ViewStub.inflate()的时候,ViewStub所指向的布局就会被inflate实例化,此布局文件直接将当前ViewStub替换掉,然后ViewStub的布局属性都会传给它所指向的布局。这样,就可以使用ViewStub在运行时动态显示布局,节约内存资源。

3、布局重用可以通过这个标签直接加载外部的xml到当前结构中,是复用UI资源的常用标签

4、减少视图层级

标签在UI的结构优化中起着非常重要的作用,它可以删减多余的层级,优化UI。多用于替换FrameLayout(因为所有的Activity视图的根结点都是FrameLayout,如果当前的布局根结点是Framelayout,那么可以用merge替代,减少多余的层级)或者当一个布局包含另一个时,标签消除视图层次结构中多余的视图组。例如你的主布局文件是垂直布局,又include引入了一个垂直布局,这是如果include布局使用的LinearLayout就没意义了,使用的话反而减慢你的UI渲染。这时可以使用标签进行优化。

43.强引用,软引用,弱引用,虚引用的区别br> 1、强引用
如果一个对象具有强引用,GC绝不会回收它;当内存空间不足,JVM宁愿抛出OutOfMemoryError错误。一般new出来的对象都是强引用
2、软引用
如果一个对象具有软引用,当内存空间不足,GC会回收这些对象的内存,使用软引用构建敏感数据的缓存。
3、弱引用
如果一个对象具有弱引用,在GC线程扫描内存区域的过程中,不管当前内存空间足够与否,都会回收内存,使用弱引用 构建非敏感数据的缓存。

4、虚引用
虚引用主要用来跟踪对象被垃圾回收的活动。

虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃 圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是 否已经加入了虚引用,来了解
被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

44.二维码的原理维码可以加前景色吗br> 暂没整理

45.Apk怎么打包签名的根据自己的理解描述下Android数字签名br> 数字签名的两种模式

我们都知道Android系统不会安装运行任何一款未经数字签名的apk程序,无论是在模拟器上还是在实际的物理设备上。所以我们会一个疑问,为何在日 常开发过程中我没有进行任何签名的操作,程序都会在模拟器和真机上运行面我们来讲讲APK程序的两种模式: 调试模式(debug mode)和发布模式(release mode)

1、调试模式(debug mode) : 在调试模式下,ADT会自动的使用debug密钥为应用程序签名,因此我们可以直接运行程序。
debug密钥:一个名为debug.keystore的文件。
存放位置:C:UsersXiaopeng.androiddebug.keystore Xiaopeng对应替换为自己操作系统的用户名

两个风险:
debug签名的应用程序这样两个风险:
1debug签名的应用程序不能在Android Market上架销售,它会强制你使用自己的签名;

2、发布模式(release mode) : 当要发布程序时,开发者就需要使用自己的数字证书给apk包签名。

Android程序编译、打包、签名、发布的种方式
方式一:使用eclipse+ADT编译打包
方式二:命令行手动编译打包
方式:使用ant自动编译打包
1.利用Eclipse工具打包签名AndroidApk文件:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2017年7月22日
下一篇 2017年7月22日

相关推荐