Android面经-提升篇(持续更新...)

本文链接: Android面经-基础篇(持续更新…) - CSDN博客 ,在此说明本人可能用到很多博客的链接以及话语引用没有说明,请相关的博主莫怪,本人也没有想过靠这些来进行吸引来达到盈利的目的,纯碎是为了保存好这些自己觉得写得很好的博文


自定义View

这里写图片描述

探讨:加载布局inflate(int resource, ViewGroup root, boolean attachToRoot)

  1. 如果root为null,attachToRoot将失去作用,设置任何值都没有意义。
  2. 如果root不为null,attachToRoot设为true,则会给加载的布局文件的指定一个父布局,即root。
  3. 如果root不为null,attachToRoot设为false,则会将布局文件最外层的所有layout属性进行设置,当该view被添加到父view当中时,这些layout属性会自动生效。
  4. 在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。

郭霖先生的博客讲解到:Android LayoutInflater原理分析,带你一步步深入了解View(一) - 郭霖的专栏 - CSDN博客

验证代码:
1.activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/lyo_content"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="#ff0"
        android:orientation="vertical"/>

</LinearLayout>

2.button_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<Button
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="80dp"
    android:text="Button">

</Button>

3.button_layout1.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="300dp"
        android:layout_height="80dp"
        android:text="Button"/>

</RelativeLayout>

4.

        mainLayout = (LinearLayout) findViewById(R.id.main_layout);
        lyo_content = (LinearLayout) findViewById(R.id.lyo_content);
        LayoutInflater layoutInflater = LayoutInflater.from(this);


        View buttonLayout0 = layoutInflater.inflate(R.layout.button_layout, null);
        mainLayout.addView(buttonLayout0);

        View buttonLayout00 = layoutInflater.inflate(R.layout.button_layout, null);
        lyo_content.addView(buttonLayout00);


        View buttonLayout1 = layoutInflater.inflate(R.layout.button_layout, mainLayout, true);
        //mainLayout.addView(buttonLayout);不可以再设置父布局buttonLayout1,因为它有了父布局


        View buttonLayout2 = layoutInflater.inflate(R.layout.button_layout, mainLayout, false);
        mainLayout.addView(buttonLayout2);

        View buttonLayout22 = layoutInflater.inflate(R.layout.button_layout, mainLayout, false);
        lyo_content.addView(buttonLayout22);


        View buttonLayout3 = layoutInflater.inflate(R.layout.button_layout1, null);
        mainLayout.addView(buttonLayout3);

结果:
这里写图片描述

解释:当一个view加载的时候没有父布局(没有xml中设置以及代码加载时候没有指定),设置的layout_width跟layout_height都是无用的,一个布局有且仅有绑定在一个布局(只可以绑定一次),一旦绑定必须解绑才可以绑定到其他布局去

这里有两个有趣的问题:
1.如下面代码所示,两个加载布局都是用mainLayout属性属性进行加载的(当时都没有绑定),之后一个绑定在mainLayout,一个绑定在lyo_content上,造成了上面截图的结果

        View buttonLayout2 = layoutInflater.inflate(R.layout.button_layout, mainLayout, false);
        mainLayout.addView(buttonLayout2);

        View buttonLayout22 = layoutInflater.inflate(R.layout.button_layout, mainLayout, false);
        lyo_content.addView(buttonLayout22);

2.为什么activity_main布局的第一层是有效的
因为它预先加载了一个id为content的FrameLayout来装载activity_main这个布局

3.关于B拦截了子视图C的Move事件B本身不消费,是否上交给上司处理呢? - CSDN博客

4.Android关于触摸事件跟点击事件两个方法的关系 - CSDN博客

5.Android中事件分发机制 - qq97206858的博客 - CSDN博客

异步消息

  • Android异步消息处理机制完全解析,带你从源码的角度彻底理解 - CSDN博客
  • android 异步通信机制Handler的分析与运用 - 掘金
    • 在dispatchMessage里面
      • 第一个msg.callback指的callback接口是Message.obtain(handler,callback)
        ;这里的callback其实就是一个Runnable类型
      • mCallback是构造方法Handler(looper,callback,async)传进来;这里的callback
        是一个接口,里面有handleMessage方法
      • 最后一个handleMessage(msg)才是我们熟悉的handler创建时候需要重写的方法
        (这个方法本身为空实现,需要我们自己重写)。
    • tips:
      • Handler post()方法传入的runnable之后属于msg.callback
      • View post()方法调用的是 Handler post()方法
      • Activity runOnUiThread()方法如果当前线程是主线程,直接调用run方法;
        否则调用的是Handler post()方法

设计模式

网路框架

计算机网络(博客按顺序看)

Socket

Volley

OkHttp

OkHttp取消的问题

在3.0之后不可以通过okHttpClient.cancel(tag)来取消一个请求

        call.cancel();//直接取消当前的请求
        client.dispatcher().cancelAll();//取消当前客户端上的全部请求

你也可以自己封装一个方法,按TAG来取消所有请求:

    public void cancle(Object tag,OkHttpClient okHttpClient){
        Dispatcher dispatcher = okHttpClient.dispatcher();
        synchronized (dispatcher){
            //遍历请求队列里面的
            for (Call call : dispatcher.queuedCalls()) {
                if (tag.equals(call.request().tag())) {
                    call.cancel();
                }
            }

            //遍历在运行队列里面的
            for (Call call : dispatcher.runningCalls()) {
                if (tag.equals(call.request().tag())) {
                    call.cancel();
                }
            }
        }
    }

实际上,我们一般使用OkHttp开源库居多一点:OkHttpFinal OkHttp 封装的一个简单易用 HTTP 请求和文件下载管理框架。 @codeKK Android 开源站

Retrofit2


事件总线

函数式响应编程-RxJava2.0

注解与依赖注入框架

图片框架

Glide


Gradle

项目框架

MVP

Git

推荐阅读

Android源码级分析

性能优化

Android面经

面试通用

如果对你有帮助,可以点击“推荐”哦`(*∩_∩*)′

猜你喜欢

转载自blog.csdn.net/simplebam/article/details/78436471