四大组件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
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
2创建retrofit对象 New Retrofit.builder().baseurl(“域名”).build();
3创建请求接口 netApi api= retrofit.creat(传入okhttpcall对象netapi.class)
4调用接口方法返回Call
5 Call.enqueue(new Callback
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文件就不会执行网盘下载