10年大牛所用过的东西。

Activity

问:Activity异常退出了怎么办(怎么保存数据)?

重写onSaveInstanceStateonRestoreInstanceState 两个方法

在onSaveInstanceState 用Bundle参数putString

在onRestoreInstanceState 用Bundle参数getString OK

问:Activity是如何显示视图的(源码|亮点)?

     每一个Activity都有一个Phone Window对象,

     Phone Window中mContentParent为空的时候(如果为空说明我们还没有DecorView,然后调用installDecor,之后我们的DecorView就准备好了)

     DecorView就准备好了mContentParent就指向了我们的ContentView(由于是新建的,我们的mContentParent中肯定没有子View,如果不是新建的,我们要先把mContentParent中的子View全部清干净。)

    接下来通过反射加载到我们传入的布局,接着下面会通过调用getCallBack得到一个CallBack对象cb,其实这个cb就是我们的Activity

    接着会调用Activity的onContentChanged方法,这个方法是一个空实现,然而View已经悄然显示了

问:Activity的回退栈(或启动模式或launchMode)?

       Standard 标准模式,没什么好说的每个Activity都进栈先进后出,是我们默认的模式

       SingleTop 栈顶复用模式,须要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity,我们{占位符}项目中的APP内支付页面是使用的SingleTop,就怕支付页面会因为用户快速连点出现多个支付页的问题,我们{占位符}页面朋友圈也是使用的栈顶复用模式|我们{占位符}页面搜索也是使用的栈顶复用模式。

      SingleTask 栈内复用模式,若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。我们{占位符}项目返回首页就是用的这种方式,不但省力还省内存。我们{占位符}页面大转盘也是使用SingleTask。

     SingleInstance 单栈模式,会创建一个新的任务栈并且站内只有一个Activity并不常用,如果我们把一个Activity设置为singleInstance模式,你会发现它启动时会慢一些,切换效果不好,影响用户体验。它往往用于多个应用之间,例如一个电视launcher里的Activity,通过遥控器某个键在任何情况可以启动,这个Activity就可以设置为singleInstance模式,当在某应用中按键启动这个Activity,处理完后按返回键,就会回到之前启动它的应用,不影响用户体验。

问:你们(项目中)是如何管理Activity的(如何安全退出指定的Activity或如何退出所有Activity|小细节|小亮点)?

创建一个ActivityManager管理类,搞一个ArrayList

给每个Activity添加一个TAG

填加删除都通过ActivityManager里的ArrayList就OK了

动画

问:插值器用过没(插值器的种类有哪些|怎么自定义插值器)?

插值器(Interpolator)决定值的变化模式。

默认种类有:

AccelerateDecelerateInterpolator :在动画开始与结束的地方速率改变比较慢,在中间的时候加速

AccelerateInterpolator:在动画开始的地方速率改变比较慢,然后开始速率变化加快

LinearInterpolator:以常量速率改变

AnticipateInterpolator:开始的时候向后然后向前甩

CycleInterpolator:动画循环播放特定的次数,速率改变沿着正弦曲线

PathInterpolator:动画执行的效果按贝塞尔曲线

anticipateOvershootInterpolator:开始的时候向后然后向前甩一定值后返回最后的值

OvershootInterpolator:向前甩一定值后再回到原来位置

BounceInterpolator:动画结束的时候有弹起效果

       自定义自己的动画插值器:写一个类实现Interpolator接口,Interpolator是一个空的接口继承了TimeInterpolator接口,定义getInterpolation方法即可。

问:属性动画是如何实现的(Property Animation或属性动画出现的版本或者关于属性动画的其他问题)?

       Android 3.0(API 11)后才提供的一种全新动画模式。

       其出现原因为作用对象局限于View,没有改变View的属性,只是改变视觉效果,动画效果单一。

       ValueAnimatorObjectAnimator是其重要的两个类。

       ValueAnimator有ofIntofFloatofObject三个重要的方法。

       这三个方法的作用有两个 1. 创建动画实例/ 2. 将传入的多个参数进行平滑过渡:此处传入0和1,表示将值从0平滑过渡到1 ,如果传入了3个Int参数 a,b,c ,则是先从a平滑过渡到b,再从b平滑过渡到c,以此类推,他们内置了估值器。

       插值器(Interpolator)决定值的变化模式。

       估值器(TypeEvaluator)决定值的具体变化数值。

       ObjectAnimator封装了ValueAnimator,自动赋值 给对象的属性从而实现动画;是直接对对象属性进行操作。

       ObjectAnimator.ofFloat();至少传三个参数,第一个是需要操作的view,第二个是需要操作的view的属性,第三个不固定,传2个就是a过度到b,传三个就abc,以此类推。

       当然了我们还可以将动画组合在一起使用AnimatorSet,AnimatorSet.play() 播放当前动画的同时可以.with() :将现有动画和传入的动画同时执行.after() :将现有动画插入到传入的动画之后执行 .before() : 将现有动画插入到传入的动画之前执行。

问:ObjectAnimator需要操作的view的属性(Property)有

Alpha 控制View的透明度

float TranslationX 控制X方向的位移

float TranslationY 控制Y方向的位移

float ScaleX 控制X方向的缩放倍数

float ScaleY 控制Y方向的缩放倍数

float Rotation 控制以屏幕方向为轴的旋转度数

float RotationX 控制以X轴为轴的旋转度数

float RotationY 控制以Y轴为轴的旋转度数

问:补间动画都有哪些(Tween动画有哪些|怎么旋转、平移、缩放、透明度)?

        补间动画由Animation类来实现具体效果,包括平移(TranslateAnimation)、缩放(ScaleAnimation)、旋转(RotateAnimation)、透明度(AlphaAnimation)四个子类,四种变化。

问:项目实现过哪些动画、怎么实现的?

帧动画、补间动画、属性动画都用过

例如下拉刷新时头布局里我们使用了帧动画

{发现}页面有个弹出窗口使用了补间动画,还加入了BounceInterpolator插值器的效果

{下载进度条}使用了属性动画

ViewPager指示器

问:ViewPager指示器你们怎么做的(小细节|小亮点)?

     用MagicIndicator这个(库或lib),里面包含了市面上绝大部分效果,实例化以后直接设置就OK了。

    或者用NavigationTabStrip这个view做的,导包后,直接在布局里设置就好了,里面包含了市面上绝大部分效果。

问:ViewPager指示器你们怎么做的,不用库的情况下自定义过吗(自定义View|小细节|小亮点)?

首先在values文件夹下新建attrs定义一些参数:

指示器的文字和横线颜色(文字颜色包括被选中的和未被选中的)

文字大小以及横线的高度

tag之间的距离

布局模式,分为平衡模式和间距布局模式。平衡模式是为了所有tag的长度和不足以填满指示器时,将tags平均地进行分布

除此之外,还包括其他的一些常规view的熟悉,比如padding等等等

写一个类继承ViewGroup,用TypedArray对象拿到之前定义的参数,重写onMeasurec用固定写法MeasureSpecgetMode() getSize()方法获取父view传递给我们的宽和高的SpecMode和SpecSize后测量

然后就onDraw画layout

计算view的顶部到指示器顶部的距离和底部到横线顶部的距离

追问:怎么计算的?   

    getMeasuredWidth()减去getPadding左再减去getPadding右

    getMeasuredHeight()减去getPadding上再减去getPadding下

    计算横向所剩余的空间,再将这些空间平分,作为tag之间的间距和tag与指示器前端和后端的距离   追问:怎么计算的 答:减去view的宽然后平均除就OK了

    布局子view

Svn、Git

问:项目里用的SVN还是Git?

svn/git都用

问:代码冲突了怎么办?

改,在AS把冲突的部分解决了再上传,如果没用AS还不是用的SVN,git冲突会包留在文件中,两个部分被==================分割开,去修改整合就OK了。

问:怎么创建分支?

SVN的话直接右键选择Team然后选择创建。合并分支,和切换分支直接右键Team选择

Git的话git checkout -b list 其中-b表示:创建并切换,切会主线就git checkout master

问:怎么代码回滚?

SVN的话就右键选择Revert to this revision 或者Revert 回到上次提交代码

Git的话就git revert HEAD 回到上次提交代码

问:怎么拉取和提交代码?

从服务端拉取代码到本地并自动合并到本地分支

//将新建的文件或者修改过的文件添加到索引库。

$ git add .    //别忘记有个点,点前面有个空格

//本地分支代码保存到本地仓库

$ git commit -m " 提交的message"

//查询当前远程的版本

$ git remote -v

//直接拉取并合并最新代码

$ git pull origin master [示例1:拉取远端origin/master分支并合并到当前分支]

$ git pull origin dev [示例2:拉取远端origin/dev分支并合并到当前分支]

从本地提交代码到服务器

$ git push origin dev [示例2:将当前分支提交到远端origin/dev分支]

Fragment

问:Fragment的懒加载是怎么实现的?(为什么要用懒加载|小亮点)

       ViewPager的每一个Fragment都需要通过网络拉取数据加载,而ViewPager是默认加载前两项的,很容易造成网络丢包或者网络堵塞等问题,使用懒加载是非常有必要的。

       在Fragment中有一个setUserVisibleHint这个方法,它优于onCreate()方法,其中的setUserVisibleHintture的时候就说明Fragment可见,这个时候我们就可以进行网络加载,反之则不加载。这就是懒加载

问:Fragment嵌套Fragment容易出现什么问题?

一般不会出现问题

当然有需要注意的点,比如直接在父Fragment的onActivityCreated方法中调用子Fragment更新View的方法就会抛出异常!

因为在父Fragment的onActivityCreated方法中虽然实例化了子Fragment但是子Fragment的生命周期方法并没有被调用

在onStart方法中更新子Fragment View即可

Xutils

问:Xutis有几个模块?(技术选型为什么选)

xutils主要有4个模块:注解模块,网络模块,图片加载模块,数据库模块。

之前项目用过xutils,现在已经弃用几年了,后来出了xutils3又尝试了下还可以

选择它是因为强大而且包也不太大

数据库:而且拥有ORM, 不次于greenDao,当然说法很牵强

Http请求:有了强大的http及其下载缓存、支持超大文件(超过2G)上传

Image:模块的实现相当的简洁, 并且支持回收被view持有但被Mem Cache移除的图片, 减少页面回退时的闪烁,而且支持gif,支持圆角, 圆形, 方形等裁剪, 支持自动旋转...

绑定View:更多的事件注解支持且不受混淆影响...

最重要的是AbsTask和统一的回调接口Callback, 任何异常, 即使咱的回调方法实现有异常都会进入onError, 任何情况下onFinished总会让你知道任务结束了

问:Xutils怎么操作数据库?

用DButils增删改查更新数据库

问:Xutils怎么断点续传?

utils.download的第个参数设为true

问:Xutils做项目时使用get请求的接口发现明明数据变更了,返回却是上一次的结果,连续好几次,过个一会才能请求到最新数据,遇到过这种情况吗?

没有遇到过。

一般可设置缓存默认过期时间和针对当前请求的过期时间。

sHttpUtils.configCurrentHttpCacheExpiry(0*1000);这样就是不缓存

这样就不会出现过一会子才请求到最新数据了

问:你使用Xutils做项目时就没有遇到过问题吗?

有一些不太方便的地方

有一次,项目{首页}的一个Web接口包含“&”这个特殊的字符

直接报了一个java.net.URISyntaxException

后来把String 直接转成URL就好了

当然以前用的时候也会莫名其妙的报EOFException,貌似是它源码的问题,后来就没报过,应该是被修复掉了

Json

问:可以手写Json吗?

{"firstName": "ba", "lastName": "wei"}

问:会原生解析Json吗?

使用JSONObject JSONArray一层一层解析

当然一般都用Gson Jackson FastJson

ContentProvider

问:你们一般用它来做什么?

进程间进行数据交互and共享,跨进程通信

当然包括跨进程操作某些系统自带进程,比如通讯录、相册等

就是用ContentProviderContentResolver增删改查

问:ContentProvider的底层原理是?

ContentProvider的底层是采用 Android中的Binder机制

问:当外部数据发生变化ContentProvider是如何知道的?

通过ContentObserver

它就是一个观察者

枚举类,工具类

问:使用过枚举类吗(Enum)?

不可否认enums会使得代码更易读更安全

当然在编写高效Android代码时避免使用枚举

特别是大型的App中,能不用则不用

因为它会牺牲执行的速度和并大幅增加文件体积

Android官方已经说明了最好不用enums

问:使用过工具类吗(项目中用到了哪些工具类)?

屏幕工具类、

时间获取转换类、

加密工具类、

键盘监听工具类、

图片处理工具类、

网络工具类、

Log日志打印工具类、

SD卡文件处理工具类、

正则验证工具类、

数不胜数,当然也可以依赖最为流行的万能工具类

Retrofit+RxJava

问:使用过Retrofit+RxJava实现网络请求吗?

用过,先说Retrofit吧,先定义一个接口,然后实例化异步请求就OK

常有的操作符有:

GET查找资源

POST 修改资源

PUT ----------上传文件

DELETE ----删除文件

  再说RxJava,其实是一个在Java VM上使用可观测的序列来组成异步的、基于事件的程序的库,就是个实现异步的库。Retrofit+RxJava就是再创建Retrofit对象的时候多点出一个方法:addCallAdapterFactory(RxJavaCallAdapterFactory.create()然后在定义的Retrofit接口里把Call改为Observable,也就是被观察者。然后再创建一个rxjava中的observable,再弄一个观察者subscribe订阅就OK了,当然Retrofit RxJava都是2.0的。

问:能简单说几个Rxjava操作符吗?

创建操作的话有createfromjustemptytimer等等

合并操作的话有concatstartWithmerge等等,还有zip

过滤操作的话有filterofType

条件操作有all什么的

聚合操作有reduce

转换操作有toListtoMap

变换操作有mapwindow

错误处理的话:

        处理所有错误用onErrorResumeNext

       如果只处理异常用onExceptionResumeNext

       阻塞操作的话用forEach

       缓存Observable发射的数据序列并发射相同的数据序列给后续的订阅者的话用cache

GreenDao

问:为什么要选择GreenDao?

使用简单、快、还能加密

问:GreenDao怎么使用?

直接在实体类里加注解就OK,每个实体类都会生产一个与之对应的Dao类

DaoMaster下的DevOpenHelper增insert删delete改update查load

问:GreenDao的注解有哪些呢?

实体@Entity注解:

schema:告知GreenDao当前实体属于哪个schema

active:标记一个实体处于活跃状态,活动实体有更新、删除和刷新方法

nameInDb:在数据库中使用的别名,默认使用的是实体的类名 indexes:定义索引,可以跨越多个列

createInDb:标记创建数据库表

基础属性注解:

@Id:主键 Long 型,可以通过@Id(autoincrement = true)设置自增长

@Property:设置一个非默认关系映射所对应的列名,默认是使用字段名,例如:@Property(nameInDb = "name")

@NotNull:设置数据库表当前列不能为空

@Transient:添加此标记后不会生成数据库表的列

索引注解:

@Index:使用@Index作为一个属性来创建一个索引,通过name设置索引别名,也可以通过unique给索引添加约束

@Unique:向数据库添加了一个唯一的约束 关系注解

@ToOne:定义与另一个实体(一个实体对象)的关系

@ToMany:定义与多个实体对象的关系

问:使用GreenDao遇到哪些问题呢?

更新数据时,一直无法插入

解决办法:如果想要进行数据更新,则必须在创建表时,添加addIdProperty属性,否则会报错抛出异常无法进行数据更新。

进行单条数据查询时uniqueOrThrow()方法会抛出异常导致退出:

解决办法:GreenDao 此方法未对异常进行处理,查询结果为空时会异常退出程序,使用unique()方法,然后对结果为空的情况进行判断。

当使用unique()方法进行数据查询时如果有多条数据存在,则会抛出异常,退出程序:

解决办法:unique()方法别查多条数据

webView

问:JS跟Android怎么互调?

首先Android调用JS的方法

写一个WebView

WebView.getSettings()得到WebSettings

webSettings.setJavaScriptEnabled(true);得到和JS交互的权限

WebView.loadUrl("url");加载JS代码

使用WebView.post(new Runnable() {})

在其中WebView.loadUrl("javascript:JS代码中的方法名()");

第6步也可以替换为WebView.evaluateJavascript()

Android4.4以后使用evaluateJavascript效率更高

可以写个判断4.4之前使用loadUrl,之后使用evaluateJavascript

JS调用Android中的JAVA代码

定义JS需要调用的方法,被JS调用的方法必须加入@JavascriptInterface注解,将JS方法中的对象通过addJavascriptInterface映射进来,WebView.addJavascriptInterface(new 方法名(), "JS中的对象");当然也需要开启JS交互和加载JS布局,之后JS就可以正常调用Android中的方法了,注意方法名和JS中的方法名必须一致。我们也可以用其他方式,Android通过 WebViewClient 的回调方法shouldOverrideUrlLoading ()拦截 url,解析该 url 的协议,如果检测到是预先约定好的协议,就调用相应方法。

问:JS跟Android互调需要注意什么?

        Java 调用 Js 里面的函数、效率并不是很高、估计要200ms左右吧、做交互性很强的事情、这种速度很难让人接受、而js去调Java的方法、速度很快、50ms左右、所以尽量用js调用Java方法

      Java 调用 Js 里面的函数、没有返回值、调用了就控制不到了

Js 调用 Java 的方法、返回值如果是字符串、你会发现这个字符串是 native的、转成 locale 的才能正常使用、使用 toLocaleString() 函数就可以了、不过这个函数的速度并不快、转化的字符串如果很多、将会很耗费时间

对Web同事的要求网页中尽量不要使用jQuery、执行起来需要5-6秒、最好使用原生的JS写业务脚本、以提升加载速度、改善用户体验

问:为什么要加@JavascriptInterface注解?

4.4之后调用需要在调用方法加入加入@JavascriptInterface注解

如果代码无此申明,那么也就无法使得js生效,也就是说这样就可以避免恶意网页利用js对安卓客户端的窃取和攻击。

问:为什么要用WebViewJavascriptBridge框架?

      我们很多时候需要在js记载本地代码的时候,要做一些判断和限制,或者有可能也会做些过滤和对用户友好提示

因此JavascriptInterface也就无法满足我们的需求了,特此有大神就写出了WebViewJavascriptBridge框架

问:怎么加快HTML网页装载完成的速度?

       默认情况html代码下载到WebView后,webkit开始解析网页各个节点,发现有外部样式文件或者外部脚本文件时,会异步发起网络请求下载文件,但如果在这之前也有解析到image节点,那势必也会发起网络请求下载相应的图片。网络情况较差的情况下,过多的网络请求就会造成带宽紧张,影响到css或js文件加载完成的时间,造成页面空白loading过久,解决的方法就是告诉WebView先不要自动加载图片,等页面finish后再发起图片加载。

问:怎么解决ViewPager里非首屏WebView点击事件不响应?

继承WebView类,在子类覆盖onTouchEvent方法

ACTION_DOWN的时候写onScrollChanged就OK了

Pulltorefresh

问:使用过Pulltorefresh吗?

      项目里用到了PullToRefreshScrollView,在ScrollView下拉刷新时去服务端获取数据并展示,获取数据的过程采用线程池管理线程,进行到该步发现一下拉刷新APP就闪退了,查看Log错误显示ThreadPoolExecutor队列满了RejectedExecutionException,怀疑我的ThreadPoolExecutor容量不够大,虽扩大至20,再次测试依然闪退,仍然是队列已满错误。之后层层源码追看,发现了端倪,onPullDownToRefresh该方法一直不断的在调用,导致ThreadPoolExecutor里面的任务一直变多,导致容量急剧增加,进而闪退。这样问题就很容易解决了在SmoothScrollRunnable当中增加一个标志位,标志我当次已经在初始化中就OK了。

问:使用PullToRefreshScrollView应该不多吧?

一般项目里都是用PullToRefreshListView多一些,现在都用XRecyclerView了,支持下拉上拉,而且还没有List View的错位问题,当然了之前还是用PullToRefresh比较多一点,也会自定义PullToRefresh,不过在定义PullToRefresh的时候也经常遇到一些问题比如写项目的时候,自已定义的时候继承了PullToRefreshBase类实现了相关方法,为recyclerView添加了上拉和下拉功能后。发现正在刷新的时候recyclerView不能滑动。根据事件分发的顺序,我首先想到的就是正在刷新的时候PullToRefreshBase把事件给拦截了,所以查看PullToRefreshBase源码的onInterceptTouchEvent方法,可以看到switch里第一个if条件如果正在刷新并且!mScrollingWhileRefreshingEnabled的时候就对事件进行拦截,所以我们可以尝试看看有没有提供可以改变mScrollingWhileRefreshingEnabled变量的方法。果然,提供了setScrollingWhileRefreshingEnabled方法,所以如果要让自定义的view刷新的时候可以滑动,只需要在初始化的时候setScrollingWhileRefreshingEnabled(true)就ok了。

问:有没有遇到过pullToRefresh数据未充满界面的bug?

项目里的某些遇到过:

                                  Item大于15个的时候

                                  使ListView或RecyclerView设置模式setMode为Mode.BOTH

                                  Item大于等于15个的时候

                                  使ListView或RecyclerView设置模式setMode为Mode.PULL_FROM_START就OK了

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值