复习之路,关注下细节和自我总结

1.选一个擅长的领域去处理
2.基础一定要背
3.试着去了解这个领域市面上的技术
4.如果有时间的话,研究其中一个众所周知的源码分析




surfaceView    为动画,特效设计高效管理的UI类
1.双缓冲
2.子线程绘制
surfaceView 主要两个方法  unlockCanvasAndPost  解锁并且发送到屏幕上    


surface类实现了一个parceable,主要不同线程中绘制完成界面显示出来


recyclerView 解析https://www.cnblogs.com/jiangbeixiaoqiao/p/5672766.html

动画解析:http://www.cnblogs.com/wondertwo/p/5295976.html

GLSurfaceView  继承于SurfaceView用于openGL  绘制3D图形






面试复习:




一、通过LayoutInflaterCompat.setFactory(getLayoutInflater(), mSkinInflaterFactory);可以改变从布局xml中设置的控件属性及控件本身mSkinInflaterFactory实现 LayoutInflaterFactory的onCreateView。AppCompatDelegate里createView,AppCompatViewInflater里具体实现createView。
及根据我们平常xml里用标签来初始化控件。
  switch (name) {
            case "TextView":
                view = new AppCompatTextView(context, attrs);
                break;
            case "ImageView":
                view = new AppCompatImageView(context, attrs);
                break;
            case "Button":
                view = new AppCompatButton(context, attrs);
                break;
            case "EditText":
                view = new AppCompatEditText(context, attrs);
                break;
            case "Spinner":
                view = new AppCompatSpinner(context, attrs);
                break;
            case "ImageButton":
                view = new AppCompatImageButton(context, attrs);
                break;
            case "CheckBox":
                view = new AppCompatCheckBox(context, attrs);
                break;
            case "RadioButton":
                view = new AppCompatRadioButton(context, attrs);
                break;
            case "CheckedTextView":
                view = new AppCompatCheckedTextView(context, attrs);
                break;
            case "AutoCompleteTextView":
                view = new AppCompatAutoCompleteTextView(context, attrs);
                break;
            case "MultiAutoCompleteTextView":
                view = new AppCompatMultiAutoCompleteTextView(context, attrs);
                break;
            case "RatingBar":
                view = new AppCompatRatingBar(context, attrs);
                break;
            case "SeekBar":
                view = new AppCompatSeekBar(context, attrs);
                break;
        }
通过以上就可以去实现改变多套皮肤。


二、AIDL原理
其实就是一种特殊的可以被外部bind的service,需要通过IBinder传递基础数据类型(除了short外),或者是实现了Parcel的数据类型。
1.定义服务端和客户端都同一样的接口,客户端服务端都有
interface ITestAidl {
 int test(int a,int b);
}
2.服务端,写一个service
[java] view plain copy
public class IRemoteService extends Service {  
  
  
    private final IBinder mBinder = new ITestAidl.Stub() {  
        @Override  
        public int test(int a, int b) throws RemoteException {  
            return 0;  
        }  
    };  
  
    @Nullable  
    @Override  
    public IBinder onBind(Intent intent) {  
        return mBinder;  
    }  
}  
3.客户端  
  private void bindService(){
        Intent intent =new Intent();
        intent.setComponent(new ComponentName("com.aidl.test.myaidlservice","com.aidl.test.myaidlservice.IRemoteService"));
        bindService(intent,conn,BIND_AUTO_CREATE);
    }
然后通过ServiceConnection 的onServiceConnected获取到远程服务的实例,并调用接口就可以了。
    private ServiceConnection conn=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
           ITestAidl t= ITestAidl.Stub.asInterface(iBinder);
        }




        @Override
        public void onServiceDisconnected(ComponentName componentName) {




        }
    };

三、自定义控件
1)改写原有控件  常用于滑动冲突处理,或者强制某种类型事件不被响应等
2)组合控件   例如APP中有相同样式的控件,大体布局都类似,就可以考虑使用组合控件,例如我有定义一个上传图片展示的横向列表图片控件。TAB下有小三角滑动控件。
3)完全重写自定义  
1.自定义属性
2.onmeasure   测量自己大小和子控件大小   可以通过requestlayout来触发,当位置改变或大小调整会触发,子控件Onmeasure被触发,父控件也会被触发,setMeasuredDimension
3.onlayout(viewGroup)  当时viewgropu类型时,包含子控件时,来布局子控件显示位置  当触发onmeasure就一定会触发onlayout
4.ondraw   会多次绘制,延时等定义对象不要放里面,会造成延时。通过Postinvalidate()其他线程可以触发,用invalidate()当前UI线程触发。
5.ontouchEvent  根据不同情况做触发响应,  多指触碰,最后一个落下的指头具有控制权,如果先后落下三个指头,然后
6.onintercepttouchEvent(viewGroup)  拦截子控件的触碰事件
 
四、事件拦截截止   假设子控件不是viewgroup
最外层父控件   dispatchTouchEvent -》到最外层父控件  onintercepttouchEvent(如果拦截就到 返回true则拦截)  -》 最外层父控件的 ontouchEvent  完结




最外层父控件   dispatchTouchEvent -》到最外层父控件  onintercepttouchEvent(不拦截)  -》 子控件的dispatchTouchEvent -》子控件的 ontouchEvent(处理)  完结




最外层父控件   dispatchTouchEvent -》到最外层父控件  onintercepttouchEvent(不拦截)  -》 子控件的dispatchTouchEvent -》子控件的 ontouchEvent(不处理)-》 外层父控件ontouchEvent 




五、系统垃圾回收进程
Android 基于进程中运行的组件及其状态规定了默认的五个回收优先级:


IMPORTANCE_FOREGROUND: 前台  最后才被回收


IMPORTANCE_VISIBLE: 可见


IMPORTANCE_SERVICE: 服务


IMPORTANCE_BACKGROUND:后台


IMPORTANCE_EMPTY:  空进程


六、okhttp
okhttp粗略来看就几步
//1.创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
//2.创建一个Request  不同文件,表单,其实都是request不同
final Request request = new Request.Builder()
                .url("https://github.com/hongyangAndroid")
                .build();
//3.new call    
Call call = mOkHttpClient.newCall(request); 
//4.请求加入调度
call.enqueue(new Callback()
        {
            @Override
            public void onFailure(Request request, IOException e)
            {
            }




            @Override
            public void onResponse(final Response response) throws IOException
            {
                    //String htmlStr =  response.body().string();
            }
        });    


由此http://blog.csdn.net/lmj623565791/article/details/49734867   一个封装库okhttputils就出现了
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0326/2643.html okhttp解析




七、canvas操作
首先我先画一个简单的矩形
p1.setColor(Color.argb(100,165,152,120));  
        canvas.drawRect(100,100,200,200,p1);  
然后我保存下画布当前状态  
        canvas.save();  
将画布旋转30度  
        canvas.rotate(30);  
再画一个矩形2,这个矩形被旋转30了,此时,看到矩形1是没有变化的,说明画布旋转对之前画上去的没有用  
        p1.setColor(Color.argb(100,199,0,120));  
        canvas.drawRect(100,100,200,200,p1);  
然后将画布还原  
        canvas.restore();  
再画个矩形3上去,发现矩形3的还是未旋转前画布的样子  
        p1.setColor(Color.argb(100,199,0,120));  
        canvas.drawRect(200,200,300,300,p1);  


八、性能优化
1.布局优化
 include merge viewstub减少无用层级    
2.内存优化
GC 会暂停一切,即时回收清空cursor,bitmap等占内存大的对象
代码优化 比如不在循环里定义对象,复用对象


3.网络请求优化  利用三级缓存机制来减少网络请求
ACache   存储到文件  
4.运算优化   
1)频繁耗时  提前准备预处理,比如排序等,
2)利用一些新的数据结构, 利用ArrayMap 等,千条数据以内
如果key的类型已经确定为int类型,那么使用SparseArray,因为它避免了自动装箱的过程,如果key为long类型,它还提供了一个LongSparseArray来确保key为long类型时的使用


如果key类型为其它的类型,则使用ArrayMap
3)减少终端数据运算,数据尽量由后台服务器组装处理
5.电量优化    减少频繁多次网络请求,尽量合并同次请求   


冷启动优化  Application不去做一些初始化操作,而是放到Activity的启动页里
webview 白屏问题  在首页启动时候创建一个带webview的fragment,而且后面不关闭fragment,每次去加载webview的fragment


九、webview漏洞
http://www.cnblogs.com/laughingQing/p/6392455.html
1、webview明文保存密码  mWebView.setSavePassword(false)解决
2、WebView 域控制不严格漏洞  其他APP可以通过export暴露出去的组件执行JS通过File协议去获取当前APP的本地文件
3、WebView 任意代码执行漏洞   可以通过addJavascriptInterface 反射拿到当前运行的类,执行
4.2以上版本Java的远程方法上面声明一个@JavascriptInterface,4.2以下就只能通过onJsPrompt自己拦截


十、6.0/7.0版本更新最大改变
1、运行权限申请   一些敏感权限不通过androidmainfest.xml里直接申请,在使用的时候申请
2、Android N 删除了三项隐式广播,以帮助优化内存使用和电量消耗。 此项变更很有必要,因为隐式广播会在后台频繁启动已注册侦听这些广播的应用
3、应用间共享文件   若要在应用间共享文件,您应发送一项 content:// URI




1、activity 生命周期   oncreate ->  onstart ->  onresume -> onpasue ->  onstop(未销毁又重新打开->onrestart->onstart...) ->  ondestory  


2、前台  可见   服务  后台   空  


3、singleTop(只有在栈顶复用)  singleTask(当栈内存在就清空上面,让该Activity置顶)  singleInstance  


4、scheme 协议   H5跳转打开APP  服务器跳转页面   其他APP跳转页面 通知打开APP 


5、fragment  onattach->oncreate -> oncreateView ->onViewcreated -> activity oncreate  -> onActicityCreated ->activity onstart   -> onstart 
-> activity onresume -> onresume    ->onpasue  -> activity onpasue   -> onstop -> activity onstop -> ondestoryview -> ondestory -> ondettach
-> activity ondestory


6、fragment 通讯
a.fragment 获取Activity  getActivity()
b.fragment间 findFragmentByID
c.Actvity 获取Fragment  接口回调


7、fragmentPagerAdapter 切换不销毁fragment(适合少)        fragmentStatePagerAdapter 切换就销毁fragment(适合多fragment)


8、replace 替换最上层fragment   add  加某个值到最上层   remove 从最上层移除


9、service 后台运行在主线程中  Activity的最长执行时间是5秒,BroadcastReceiver的最长执行时间则是10秒,service最长是20秒,


10、oncreate 调用一次,onstartCommand多次   多个实例也可以绑定同一个服务
bindService  与bind的Activity生命周期一致   startservice 必须自己结束,不然会一直在后台运行
bindService   oncreate -> onbind ->Activity(sericeConnection里可以IBINDer获取服务 onServiceConnected onServiceDisconnected ) ->  unbind -> ondestory
startserice   oncreate->onstart(被废弃) ->onstartCommand-> 运行中 ->ondestory




11、broadcast 
a.localbroadcast   内部使用handle 比Binder更高效,更安全,APP内部传递
b.normalbroadcast 
c.orderbroadcast  有序广播  有顺序通知,优先级高可以终止后面接收广播


12、webview   内存泄漏(持有activity引用)  安全漏洞(addJavascriptInterface在16及16前可以随意被引用)
a.独立进程  给webview使用,退出时候直接关闭该进度
b.动态添加webview  当结束remove掉webview


13、binder   进程通讯一种(pipe管道  socket binder)
a.优点    安全(校验通讯双方) 性能高效    进程隔离
b.服务通过向ServiceManager注册,然后client端向ServiceManager查询服务,并且拿到service的代理对象,binder对serivce来说就是client对象,binder对于client来说就是service的代理对象
中间会有一个Binder驱动来做转换数据和对象

14、okhttp   通过一层层封装,多个拦截器来完成缓存,网络请求等操作
a.httpclient初始化
b.build一个request
c.生成一个call
d.执行 enquene(异步) 或者 excecute(同步)   会有一个拦截器链,实际是通过拦截器去操作网络请求  CallServerInterceptor这个拦截器okio来读写真实请求

15、butterknife 原理   依托JAVA注解原理。注解解释器生成新的JAVA,而不是通过反射
a.开始扫描Butterknife注解
b.ButterKnifeProcessor-><calssName>$$ViewBinder
c.调用bind方法加载生成的ViewBinder类


16、Glide   
a.采用Builder模式创建Request,DrawableTypeRequest,加入到队列中,然后发送出去
b.绑定Activity生命周期。原理为创建一个空白的Fragment,并添加到当前Activity或Fragment中
c.Engine,缓存,编解码和网络请求。这个部分是实现request发送的底层。分为request任务的发送和request任务的执行两个部分。
先尝试从内存缓存中获取Resources,再在线程池内新建子线程,并提交任务。等子线程执行时,进入到任务的执行阶段。
先尝试从磁盘缓存中获取Resources,然后利用DataFetcher从网络或本地文件中获取原始数据,解码并转码为我们所需的格式

17、ANR Activity的最长执行时间是5秒,BroadcastReceiver的最长执行时间则是10秒,service最长是20秒
解决思路  就是在主线程中不要做耗时操作

18、OOM  性能优化    OOM(主要Bitmap)   内存抖动(快速创建并快速释放大量内存,过多后可能OOM)  内存泄漏(未即时释放cursor,bitmap等)


19、UI卡顿
a.人为UI线程执行轻微耗时操作
b.布局过于复杂,无法16ms内完成绘制
c.同一时间动画执行次数过多,导致CPU或GPU负载过重
d.View 过度绘制,某些像素在同一帧时间内重复多次绘制
e.View 频繁触发measure layout draw 导致卡顿
f.内存频繁GC过多,因为GC操作时候所有处理都停止
g.冗余资源及逻辑导致加载和执行缓慢
h.ANR

优化
a.布局优化,避免复杂的布局,多用include,merge,ViewStub
b.列表及Adapter优化,图片滑动时不加载
c.禁止过多不必要的背景,对图片进行压缩
d.避免ANR

20、内存泄漏
a.内部类持有外部类的引用  静态内部类解决
b.单例  如果有引用context,那么采用ApplicationContext
c.handler 如果有消息待处理或者没处理,不会随着Activity结束而结束      
private MyHandler myHandler=new MyHandler(this);
    private static class MyHandler extends Handler{
        private WeakReference<Context> reference;
        public  MyHandler(Context context){
            reference=new WeakReference<Context>(context);
        }


        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    }
d.避免static变量
e.资源未关闭造成的内存泄漏  cursor bitmap broadcastReciver等
f.AsyncTask造成内存泄漏  


21、内存管理
a.

22、插件化  基础原理都是反射,反射会有效率损耗
a.动态APK  dexclassloader   PathClassLoader(只能加载自己内部/data/app/目录下的内容)
b.资源加载  assetManager
c.代码加载   主要是生命周期

23、注解   
系统标准注解  
1、overiide 重载父类方法
2、Deprecated 不建议使用,标注某类,那么某类的子类也自动被标记(deprecated是文档类型标识,注意大小写区分,仅用来写注释)
3、SuppressWarnnings 忽视警告 
元注解
1、target  注解修饰对象的范围
2、Retention注解 三种注解
  a、源码注解    编译时就会抛弃,不会有任何影响
b、编译注解    编译时根据注解生成源码和.class   默认 @Retention(CLASS)
c、运行注解    运行时,根据反射机制去执行 反射影响效率
3、Documented 注解
Documented 注解表明这个注解应该被 javadoc工具记录


4、inherited  可以被继承的
Android support annotations
1、Nullness注解 如果为空编译器警告  Nullable 可以为空
2、Resourece Type注解  区分资源ID和数字类型资源 
3、Threading 注解  WorkerHhread子线程,不是就会警告    @UiThread 主线程,不是就会警告 
4、Overriding Methods 注解:@CallSuper 重写父类又要调用调用父类方法


24.synchronized 
1)synchronized   阻塞等待线程使用,方法对象变量都可以使用
  volatile 只能变量,所有修改都同步所有存储地,不加锁,可以同时访问
2)synchronized 悲观锁机制,阻塞等待线程,虚拟机自动处理,性能低效
  lock  乐观锁机制(假设没有加锁),指定起始位置和终止位置,手动处理
  
  
25.threadpoolexecutor
ThreadPoolExecutor(int corePoolSize,//线程池维护线程的最少数量
 int maximumPoolSize,//线程池维护线程的最大数量
long keepAliveTime, //线程池维护线程所允许的空闲时间,超过会自动关闭空闲进程
TimeUnit unit,//线程池维护线程所允许的空闲时间的单位
BlockingQueue<Runnable> workQueue,//运行线程池超过最大值,等待队列
RejectedExecutionHandler handler) //线程池饱和之后的自定义规则  


ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
 
ThreadPoolExecutor.CallerRunsPolicy()
用于被拒绝任务的处理程序,它直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
当抛出RejectedExecutionException异常时,会调用rejectedExecution方法
(如果主线程没有关闭,则主线程调用run方法,源码如下
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
)
 
ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
 
ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务


26.工程模式
饿汉
懒汉
线程安全懒汉
DCL
静态变量懒汉
枚举




27.观察者模式


28.建造模式
1. builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
2. ConcreteBuilder:实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例。
3. Director:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
4. Product:要创建的复杂对象。


重点关注建造次序,例如buiildPartA()->buildPartB()->buildPartC()->getResult()   生成对象


public class ConcreteBuilder(){
private void buiildPartA(){
system.out.println(A);
}
private void buiildPartB(){
system.out.println(B);
}
private void buiildPartB(){
system.out.println(C);
}

private Product getResult(){
}
}


public class Director(){
private Builder builder;
private Product constructor(){
builder.buiildPartA();
//builder.buiildPartB();//可以随便定义建造顺序
builder.buiildPartC();
return builder.getResult();
}
}


Builder builder=new ConcreteBuilder();
Director dirctor=new  Director(builder);
Product  product=dirctor.constructor();


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值