android面试

四大组件content provider, service, activity, broadcast receiver

Activity

Android的交互视图

四种状态Running/paused/stopped/killed

生命周期

启动 oncreate(创建 初始化) onstart (可见 不可交互)onresume(可见 可交互)onstop,ondestroy

Home键 onpause(可见不可交互) onstop(被覆盖 会被回收)

返回 onrestart(初始化) onstart(可见) onresume(可交互)

退出 onpause onstop ondestroy(销毁 回收工作)

进程优先级 前台/可见/服务/后台/空

 

任务栈

Activity启动模式

Standard(不复用,都需要重新创建activity)

singletop(栈顶复用,判断是否在栈顶,在则复用)

singletask(栈内复用 判读是否有相同的activity 如果有则放到栈顶且移除上面的activity)

singleinstance(有且只有一个,单列独占一个activity)

在Manifest.xml 的activity里:android:launchMode = “standard”

 

Scheme跳转

App页面内部跳转 注册url scheme( h5 1app 2app之间跳转)uri

1,H5跳转到native页面

2,客户端获取推送消息后,点击消息跳转到APP内部页面

3,APP根据URL跳转到另外一个APP指定页面

第一页url=”scheme://mtime/goodsDetail?goodsId=1” new intent(Intent.ACTION_VIEW,Uri.parse(url)) startActivity(intent)

第二页

定义scheme的activity ,增加过滤器

获取参数  uri data = getIntent().getData(); data.gethost() data.getpath() data.getQueryparamter

 

Fragment 舒适轻便

有自己的生命周期 动态的加载到activity 必须依附activity

静态加载 xml中写

动态加载 fragmentmanager创建.fragmenttransaction() .add(资源,manager,名称).commit

.replace .remove .hide  .show .detach

Fragmentpageradapter(页面少 切换不回收内存) fragmentstatepageradapter(页面多 切换自动回收)

fragment和viewpager展示结合都是继承自pageradapter,负责数据 mViewPager.setAdapter(MyPagerAd)

MypagerAdapter extends pagerAdapter{getcount(){3};getitem(int postion){new fragment;return fragment}}

 

Fragment生命周期

onAttach–oncreateview–onviewcreated–activity oncreate–onactivitycreated–activity onstart–activity onresume—activity onpause—activity onstop—ondestoryview—activity ondestroy–ondetach

Fragment与activity通信

Fragment调用activity 用getactivity().findviewbyid(R.id.textview)方法

Activity调用fragment  fragmentA通知activity通知fragmentB:fragmentA中定义回调接口interface callback{void getResult();}和回调方法getfragmentAtext(callback){callback.getresult(msg);},activity实现这个接口getfragmentAtext (new callback(){getresult(msg){toast(msg)}})

Fragment的方法add remove replace(是栈顶替换)

 

Service后台服务

定义counterService extends service{onbind(intent){};onstartCommand(intent,flags,startId){intent.getintExtra(count);new Timer().schedule(new TimerTask(){run(){ sendBroadCast(count) }})}}

Service是主线程(不能进行耗时操作) 会阻塞

Service(可以和activity数据交互)intent.putextra(“counter”,counter); startService(intent)

共享文件交互,handler message信使交互

和thread区别service是主线程和thread是子线程

 

启动服务service(继承service manifest注册 start intent)

Startservice onbind(绑定) oncreate(一次) onstartcommand(正式开启)ondestroy(清理)

Stopservice

Service绑定activity:activity中bindservice(intent,conn,auto)和unbind和conn=new ServiceConnection(){onserviceConnected(){binder=bindservice.localbinder}};bindservice中写内部类bindservice{binder;public class localbinder extends Binder{BindService getService(){return BindService.this} onBind(intent){return binder;}}}

 

Broadcast receiver广播 观察者模式

观察者模式 发送intent   多端通信(教师端)

普通广播Normal broadcast 和系统广播 systembroadcat 和本地广播 local broadcat

实现

静态注册 mainefest中注册 不会失效

动态注册 跟随activity的生命周期而失效 注册registryreceiver()  ondestory中销毁unregistryreceiver()。

Bind机制向ams(activity manager service中介)注册 发送

Localbroadcast 内部有三张表存接收器actions对应recivercalls对应recevicers广播mainlooper中 通过handler发送send消息

广播接受者Myreceiver extends broadcastReceiver{onreceiver{…}} 静态和动态注册

New myreceiver new intentfilter().addaction(CONNECTIVITY_CHANGE) registerreceiver(receiver,filter)

本地广播接受者 localBroadcastManager localm = localBroadcastManager.getInstance(this),.registerReceiver(receiver,intentFilter)

广播发送者 intent  sendBroadcast(intent) 本地发送 localbroadcastmanager.sendbroadcast(intent)

 

Webview

Jsbridge  必须调用webchromeclient.Onprogresschanged

ondestroy必须销毁webview  耗电问题

 

binder(跨进程通信)  相对于socket通信机制   managerservice都是系统服务binder

跨进程间通信, binder调用系统服务 binder驱动 客户端只持有服务端的binder代理对象

客户端调用add—binder驱动(电话机 代理对象)【注册servicemanager(通讯录)】—-服务端add方法

Aidl  binder实例

服务端进程:右键创建aidl 和 一个依赖有内部类Mybinder继承aidl的stub的myservice

客户端进程:复制aidl文件 然后绑定myservice serviceconnection中{onserviceConnected{调用AIDL iMyAidlInterface =iMyAidlInterface.Stub.asInterface(service)}}

 

Handler

Android的ui非安全 子线程中耗时发送消息looper通知主线程更新ui

 

使用

1.downloadThread extends Thread{run(){new runable{};handler.post(runable)}}

2.内部类downloadthread extends thread{run(){ new message,msg.what=1 , handle.sendmessage(msg)}}

New mhandler(){handlemessage(msg){switch(msg.what)case:1,}}

 

内部机制      主线程创建handler

Threadlocal.get创建唯一Looper.loop轮训.messagequeue.next(message1,2,3)到 handler中dispathmessage处理 先进先出

 

Handler内存泄漏

Activity释放的时候必须释放handler的handlerwithrunnable,activity设置handler为static和ondestroy中写handler.removecallback方法

 

Asynctask

封装了线程池和handler的异步抽象类 耗时短

Extends asynctask, onpreexecute(初始化 放ui) doinbackground(异步处理数据 publishprogress(i))onpostexecute(string result 返回数据) onprogressupdate(进度条 progressbar.setprogress(value))

Asynctask内存泄漏 与handler一样  ondestroy中.cancel掉

asynctask结果丢失 acitivity销毁后

MyTask extends AsyncTask{doInBackGround(处理,publishProgress(value));void publishProgress()}

 

handlerthread=thread+handler+looper

继承thread 内部创建了looper对象 传递给handler对象处理异步任务 不会阻塞且是单任务串行执行

Extends thread   mlooper 构造handlerthread(name,proority优先级) onlooperprepared(重写此方法) run方法(looper.prepare notifyall(通知阻塞当前线程) wait直到looper创建完成后面执行) getlooper()quit(退出looper)quitsafe()

先定义callbackNew Callback implements Handler.Callback{handleMessage(message){handler.sendMessage(msg)}}

再定义Handler handler = new Handler(MyHandlerThread.getLopper(),new callback())

启动MyHandlerThread().Start()

 

Intenservice

是继承service的高优先级服务 集成了handler异步串行队列的类且任务完成自动停止

Extends service   构造(名称)  onhandleintent异步处理(intent){message msg, msg.obj=,}回调updateui(更新ui) ,  activity中  implements myintenservice 重写updateui()方法

 

intenservice生命周期

oncreate(定义一个handlerthread().getLopper;然后传入一个servicehandler(servicelooper))servicehandler{handlermessage(msg)}

onstart(message  servicehandler.sendmessage(msg) 处理)

 

view

view绘制流程就是从根视图ViewRoot的performTraversals方法开始,从上到下遍历整个视图树,每个 子view负责绘制自己然后递归测量返还给父view绘制,主要经过三个步骤

measure(测量)—》layout(布局)—》draw(绘制)

 

 

measurespec(测量规格前2位模式和后30位大小)

MeasureSpec 由父视图的 MeasureSpec 和其本身的 LayoutParams 共同决定。三种模式 unspecified(不控制) exactly(控制) at_most(最大控制)

 

Onmeasure 计算大小

从performmeasure开始,从viewgroup的measurechild传递给子view,遍历调用子view的measure

 

Layout 布局位置

父view获取子view的位置后,调用子view的layout方法

 

Draw

绘制流程从performdraw开始,最终调用每个子view的draw方法

 

事件分发(解决view重叠的点击事件不同) 责任链向下传递拦截

Activity—》Decorview(phonewindow)—-》rootview—-》viewgroup—-》view

三个重要方法Dispathtouchevent和ontouchevent和onintercepttouchevent

Dipatchtouevent负责分发—-》phonewindow dipatchtouevent分发decorview  —>rootview(interceptortouchevent拦截 如果true则不向下传递)  dipatchtouevent分发view

 

Listview.setadapter(myAdapter)

Datasource  ——》 myAdapter(getcount,getview(绘制item) ) -> listview

Listview(内部类recyclebin存储划出的view)(item划入划出后的内存复用)

源码中setviewtypecount(子view的类型) fillactivityview(存储子view)

Listview优化

viewholder中定义子控件 getview中读取viewholder的xml,如果null创建convertview少做耗时操作

 

Android构建

gradle相当于maven,父项目 子项目 阿里镜像 jcenter有时候不行

Git svn差不多 命令 init创建仓库 status仓库状态 diff文件历史 clone克隆地址 branch查看分支 add放入缓存 pull推送到公服 放到私服 rm删除 fork复制到私服 commit缓存提交到master push推送到私服 checkout拉出新分支

Proguard混淆插件

 

Okhttp 精髓dispatch.execute_>  getresponsewithinterceptorchain()请求链方法Interceptor.add(拦截器,通信拦截器 连接拦截器等各种拦截器)  > dispatch.finish

okhttpResponse = new Okhttpclient.newcall(new request.biilder(“”).url().build().execute(同步)

或者enqueue(异步)){onresponse(),onfail()}

Dispatch的enqueue方法, threadpool线程池后台执行

 

Retrofit

Invoke动态代理实体类 okhttpcall

1配置okhttpcall    名称netapi

#GET(“repo/{id}/{name}”)

Call getuser(#path(“id”) string id,#path(“name”) string name)

2创建retrofit对象 New Retrofit.builder().baseurl(“域名”).build();

3创建请求接口 netApi api= retrofit.creat(传入okhttpcall对象netapi.class)

4调用接口方法返回Call call = api. Getuser(id,name)

5 Call.enqueue(new Callback(){onresponse(){Gson…};onfail(){…}})

 

Volley 小数据请求

添加权限 volley.newrequestqueue(activity.this) string equeue{fail response}  requstqueue.add(stringrequeue)   缓存取数据

 

Butterknife

注解反射 扫描java中注解-》buterknifeprocessor生成类》调用bind方法生产viewbinder

@bindview(r.id.textview)    @onclick(r.id.mlistview,r.id.textview)

Textview mtext;             onclick();

Butterknife.bind();

 

Glide

Glide.with(mainactivity.this).load(“http://www”).into(imgaeviewbtn);

 

Anr异常无响应

主线程做了耗时操作 主线程(activity、 service、broadcast的onreceive 没有子线程的 )

5秒内无响应 broadcast10秒

解决 asynctask处理io耗时 handlerthread提高优先级 oncreate和onresume中避免耗时

 

Oom超出内存限制

释放bitmap的c内存gc   inbitmap属性

 

架构

Mvc/mvp/mvvm

Mvp:presenter层  切断model层和view层的交互

 

Android插件化

利用java反射加载apk、资源和生命周期

两个重要方法 dexclassloader(加载apk)和pathclassloader(加载文件目录下)

Loadclass = dexclassloader.loadclass(myactivity.class).getmethod(“myat”,new class[]{myactivity.class})

Resources( AssetManager.class.newInstance().getClass().getMethod(“addPath”,String.class).invoke())

Loadclass.getDeclaredMethod(“on_create”,new Class[]{Bundle.class}); oncreate.setaccessible(true)

热更新流程:集成crash检测插件,bugfix分支修复,jenkins构建补丁,app推送补丁,bugfix合并到master

热更新框架Dexposed andfix nuwa

热更新概念 就是不断的轮训dex文件 将新的dex文件放到最前面 后面的有问题dex文件就不会执行网盘下载

你可能感兴趣的:(技术)