I promise, I stepped on a pit stop you stepped Okay, those in society trick of potholes

Recall about two years ago, when the recruit themselves to society, a series of down and asked a lot are now vividly. Back before it felt paper come Zhongjue know this practice is essential

All face questions answer is not a hundred percent standard, rely on your own perception and have their own ideas, unique to stand out. All are for reference
I promise, I stepped on a pit stop you stepped Okay, those in society trick of potholes
all of this have been summarized in the PDF, 983 spent dozens of hours sorting out. There is quite comprehensive Android, Java little knowledge, to performance optimization. Threads .View.OpenCV.NDK. Dachang interview, algorithms, etc., you can contact me there is no use of their own

(.... To be continued more complete project source code download graphic knowledge subsequent upload github)
can contact me for a full PDF
( VX: mm14525201314 )

1 Dian how to unit test, how to ensure stable App?

To test Android applications usually create the following types of automated unit testing
  • Local Test: only runs on the local machine the JVM, to minimize execution time, this test does not depend on the Android unit frame, or, if dependent on, and very easy to use simulation to simulate the dependent frame, for the purpose of isolating Android dependent simulation framework as recommended by GoogleMockito;
  • Detection Test: real machine or run on the simulator unit tests, because of the need to go on the device, is relatively slow, these tests can be accessed instrument (Android system) information, such as the context of the application under test, in general, depend very convenient In this way through the analog simulation framework;

Note: Unit testing is not suitable for testing complex UI interaction events

  • App 的稳定主要决定于整体的系统架构设计,同时也不可忽略代码编程的细节规范,正所谓“千里之堤,溃于蚁穴”,一旦考虑不周,看似无关紧要的代码片段可能会带来整体软件系统的崩溃,所以上线之前除了自己 本地化测试之外还需要进行 y Monkey 压力测试
  • 少部分面试官可能会延伸,如 Gradle自动化测试、机型适配测试等

    2 、 Android 中如何查看一个对象的回收情况 ?

    首先要了解 Java 四种引用类型的场景和使用(强引用、软引用、弱引用、虛引用)

  • 举个场景例子: SoftReference 对象是用来保存软引用的,但它同时也是一个 Java 对象,所以当软引用对象被回收之后,虽然这个 SoftReference 对象的 get 方法返回null,但 SoftReference 对象本身并不是 null,而此时这个 SoftReference 对象已经不再具有存在的价值,需要一个适当的清除机制,避免大量SoftReference 对象带来的内存泄露
  • 因此,Java 提供 ReferenceQueue 来处理引用对象的回收情况。当 SoftReference 所引用的对象被 GC 后,JVM 会先将 softReference 对象添加到ReferenceQueue 这个队列中。当我们调用 ReferenceQueue 的 的 poll() 方法,如果这个队列中不是空队列,那么将返回并移除前面添加的那个Reference 对象

    public static void main(String[] args) throws InterruptedException {
    
          //假设当前JVM内存只有8m
         Person person = new Person( "/K=" );
         ReferenceQueue Person> queue = new ReferenceQueue>( );
         Sof tReference Person> softReference = new SoftReference<Person>(person, queue );
    
         реrѕоn = null;// 去掉强引用, new Person ( "/K=" );的这个对象只有软引用了
    
         Person anotherPerson = new Person( "/L=" )//没有足够的空间同事保留两个Person对象,所以触发GC机制
         Thread.sleep(1000);
    
         Sys tem. err . println( "软引用的对象 ------" > softReference.get( ));
    
         Reference softPollRef = queue . poll( );
         if (softPollRef != null) f
              System.err.println( " SoftReference对象中保存的软引用对象已经被GC,准备清理SoftReference对象");
                //清理softReference
         }
    }

    3丶压缩APK大小

    一个完整 APK 包含以下目录(将 APK 文件拖到 Android Studio):
  • META-INF/: 包含 CERT.SFCERT.RSA 签名文件以及 MANIFEST.MF 清单文件。
  • assets/: 包含应用可以使用 AssetManager 对象检索的应用资源。
  • res/: 包含未编译到的资源 resources.arsc
  • lib/: 包含特定于处理器软件层的编译代码。该目录包含了每种平台的子目录,像 armeabi armeabi-v7aarm64-v8ax86x86_64 ,和mips
  • resources.arsc 包含已编译的资源。该文件包含res/values/ 文件夹所有配置中的 XML 内容。打包工具提取此 XML 内容,将其编译为二进制格式,并将内容归档。此内容包括语言字符串和样式,以及直接包含在resources.arsc8文件中的内容路径 ,例如布局文件和图像。
  • classes.dex:包含以 Dalvik / ART 虚拟机可理解的X DEX 文件格式编译的类。
  • AndroidManifest.xml 包含核心 Android 清单文件。该文件列出应用程序的名称,版本,访问权限和引用的库文件.该文件使用 Android 的二进制XML 格式。
    I promise, I stepped on a pit stop you stepped Okay, those in society trick of potholes
  • libclass.dex 和 res 占用了超过 90%的空间,所以这三块是优化 Apk 大小的重点(实际情况不唯一)
减少 res ,压缩图文文件

图片文件压缩是针对 jpgpng 格式的图片。我们通常会放置多套不同分辨率的图片以适配不同的屏幕,这里可以进行适当的删减。在实际使用中,只保留一到两套就足够了(保留一套的话建议保留xxhdpi,两套的话就加上 hdpi),然后再对剩余的图片进行压缩(jpg 采用优图压缩,png 尝试采用pngquant 压缩)

减少 dex
  • 添加资源混淆
    buildTypes {
      release  {
            shrinkResources true
            minifyEnabled  true
            proguardFiles  getDefaultProguardFile("proguard-android. txt"),’proguard-rules.pro’
      }
    }
  • shrinkResources 为 true 表示移除未引用资源,和代码压缩协同工作。
  • minifyEnabled 为 true 表示通过 ProGuard 启用代码压缩,配合 proguardFiles 的配置对代码进行混淆并移除未使用的代码。
  • 代码混淆在压缩 apk 的同时,也提升了安全性。
    减少 lib
  • 由于引用了很多第三方库,lib 文件夹占用的空间通常都很大,特别是有 so 库的情况下。很多 so 库会同时引入 armeabiarmeabi-v7ax86 这几种类型,这里可以只保留 armeabiarmeabi-v7a 的其中一个就可以了,实际上微信等主流 app 都是这么做的。
  • 只需在 build.gradle 直接配置即可,NDK 配置同理
    defaultConfig {
      ndk  {
             abiFilters 'armeabi'
      }
    }

    4丶插件化原理分析

    插件化是指将 APK 分为 宿主插件的部分。把需要实现的模块或功能当做一个独立的提取出来,在 APP 运行时,我们可以动态的 载入或者 替换插件部分,减少 宿主的规模

  • 宿主: 就是当前运行的 APP。
  • 插件: 相对于插件化技术来说,就是要加载运行的apk 类文件

热修复则是从修复 bug 的角度出发,强调的是在不需要二次安装应用的前提下修复已知的 bug。

类加载机制:

Android 中常用的两种类加载器, DexClassLoaderPathClassLoader,它们都继承于BaseDexClassLoader,两者 区别在于PathClassLoader 只能加载 内部存储目录dex/jar/apk 文件。DexClassLoader 支持加载 指定目录(不限于内部)的 dex/jar/apk 文件

插件通信:

通过给插件 apk 生成相应的 DexClassLoader 便可以访问其中的类,可分为单 DexClassLoader 和多DexClassLoader 两种结构。

  • 若使用多 ClassLoader 机制,主工程引用插件中类需要先通过插件的 ClassLoader 加载该类再通过 反
    射调用其方法。插件化框架一般会通过统一的入口去管理对各个插件中类的访问,并且做一定的限制。
  • 若使用单 ClassLoader 机制,主工程则可以 直接通过类名去访问插件中的类。该方式有个弊端,若两个不同的插件工程引用了一个库的不同版本,则程序可能会出错。
    资源加载:

    原理在于通过反射将插件 apk 的路径加入AssetManager 中并创建 Resource 对象加载资源,有两种处理方式:

  • 合并式: addAssetPath 时加入所有插件和主工程的路径;由于 AssetManager 中加入了所有插件和主工程的路径,因此生成的Resource 可以同时访问插件和主工程的资源。但是由于主工程和各个插件都是独立编译的,生成的资源 id 会存在相同的情况,在访问时会产生资源冲突。
  • 独立式: 各个插件只添加自己 apk 路径,各个插件的资源是互相隔离的,不过如果想要实现资源的共享,必须拿到对应的 Resource对象。

    5 、组件化原理

    引入组件化的原因: 项目随着需求的增加规模变得越来越大,规模的增大导致了各种业务错中复杂的交织在一起,每个业务模块之间,代码没有约束,带来了代码边界的模糊,代码冲突时有发生, 更改一个小问题可能引起一些新的问题, 牵一发而动全身,增加一个新需求,需要熟悉相关的代码逻辑,增加开发时间

  • 避免重复造轮子,可以节省开发和维护的成本。
  • 可以通过组件和模块为业务基准合理地安排人力,提高开发效率。
  • 不同的项目可以共用一个组件或模块,确保整体技术方案的统一性。
  • 为未来插件化共用同一套底层模型做准备。

组件化开发流程就是把一个功能完整的 App 或模块拆分成多个子模块( Module ),每个子模块可以 独立编译运行,也可以任意组合成另一个新的 App 或模块,每个模块即不相互依赖但又可以相互交互,但是最终发布的时候是将这些组件合并统一成一个 apk,遇到某些特殊情况甚至可以升级或者

6、跨组件通信

跨组件通信场景:
  • 第一种是组件之间的页面跳转 (Activity 到Activity, Fragment 到 Fragment, Activity 到Fragment, Fragment 到 Activity) 以及跳转时的数据传递 (基础数据类型和可序列化的自定义类型)
  • 第二种是组件之间的自定义类和自定义方法的调用(组件向外提供服务)
    跨组件通信方案分析:
  • 第一种 组件之间的页面跳转实现简单,跳转时想传递不同类型的数据提供有相应的 API 即可。
  • 第二种组件之间的自定义类和 自定义方法的调用要稍微复杂点,需要 ARouter 配合架构中的 公共服务(CommonService) 实现:
    • 提供服务的业务模块: 在公共服务(CommonService) 中声明 Service接口 (含有需要被调用的自定义方法), 然后在自己的模块中实现这个 Service 接口, 再通过 ARouter API 暴露实现类。
    • 使用服务的业务模块: 通过 ARouter 的 API 拿到这个Service 接口(多态持有, 实际持有实现类), 即可调用 Service 接口中声明的自定义方法, 这样就可以达到模块之间的交互。
  • 此外,可以使用 AndroidEventBus 其独有的Tag, 可以在开发时更容易定位发送事件和接受事件的代码, 如果以组件名来作为 Tag 的前缀进行分组, 也可以更好的统一管理和查看每个组件的事件, 当然也不建议大家过多使用 EventBus
如何管理过多的路由表?
  • RouterHub 存在于基础库, 可以被看作是所有组件都需要遵守的通讯协议, 里面不仅可以放路由地址常量, 还可以放跨组件传递数据时命名的各种 Key 值,再配以适当注释, 任何组件开发人员不需要事先沟通只要依赖了这个协议, 就知道了各自该怎样协同工作, 既提高了效率又降低了出错风险, 约定的东西自然要比口头上说强。
  • Tips: 如果您觉得把每个路由地址都写在基础库的RouterHub 中, 太麻烦了, 也可以在每个组件内部建立一个私有 RouterHub, 将不需要跨组件的路由地址放入私有 RouterHub 中管理, 只将需要跨组件的路由地址放入基础库的公有 RouterHub 中管理, 如果您不需要集中管理所有路由地址的话, 这也是比较推荐的一种方式。
    ARouter 路由原理:

    ARouter维护了一个路由表 Warehouse,其中保存着全部的模块跳转关系,ARouter 路由跳转实际上还是调用了 startActivity 的跳转,使用了原生的Framework 机制,只是通过 apt 注解的形式制造出跳转规则,并人为地拦截跳转和设置跳转条件

    7 、 Hook 以及插桩技术

    Hook 是一种用于 改变 API执行结果的技术,能够将系统的API 函数执行 重定向(应用的 触发事件后台逻辑处理是根据事件流程一步步地向下执行。而 Hook 的意思,就是在事件传送到终点前截获并监控事件的传输,像个钩子钩上事件一样,并且能够在钩上事件时,处理一些自己特定的事件,例如逆向破解 App)
    I promise, I stepped on a pit stop you stepped Okay, those in society trick of potholes

    Android 中的 Hook 机制,大致有两个方式:
  • 要 root 权限,直接 Hook 系统,可以干掉所有的App。
  • 无 root 权限,但是只能 Hook 自身 app,对系统其它 App 无能为力。

插桩是以静态的方式修改第三方的代码,也就是从编译阶段,对源代码(中间代码)进行编译,而后重新打包,是静态的篡改; 而 Hook则不需要再编译阶段修改第三方的源码或中间代码,是在运行时通过反射的方式修改调用,是一种 动态的篡改

8 、说下 Measurepec 这个类

作用: 通过宽测量值 widthMeasureSpec 和高测量值heightMeasureSpec 决定 View 的大小

组成: 一个 32 位 int 值,高 2 位代表 SpecMode(测量模式),低 30 位代表 SpecSize( 某种测量模式下的规格大小)。

三种模式:

  • UNSPECIFIED: 父容器不对 View 有任何限制,要多大有多大。常用于系统内部。
  • EXACTLY(精确模式): 父视图为子视图指定一个确切的尺寸 SpecSize。对应 LyaoutParams 中的match_parent 或具体数值。
  • AT_MOST(最大模式): 父容器为子视图指定一个最大尺寸 SpecSize,View 的大小不能大于这个值。对应LayoutParams 中的 wrap_content。

9丶图片加载库Glide

图片加载库:Fresco 丶Glide 、o Picasso 等

Glide 的设计:
  • Glide 的生命周期绑定: 可以控制图片的加载状态与当前页面的生命周期同步,使整个加载过程随着页面的状态而启动/恢复,停止,销毁
  • Glide 的缓存设计: 通过(三级缓存,Lru 算法,Bitmap 复用)对 Resource 进行缓存设计
  • Glide 的完整加载过程: 采用 Engine 引擎类暴露了一系列方法供 Request 操作

    10 、区别 Animation 和 和 Animator

  • 动画的种类: 前者只有 透明度, 旋转, 平移, 伸缩 4 种属性,而对于后者,只要是该控件的属性,且有 setter 该属性的方法就都可以对该属性执行一种 动态变化的效果。
  • Operable objects: the former only, but the property can be performed almost animated animation (regardless of whether it is displayed on the screen) to I UI component performs animation of any object.
  • Animation sequence: In the Animator, AnimatorSetit is by
    playTogether(), playSequentially(), animSet.play().with(), before(), after()of these methods to control the plurality of animation work, thereby to achieve precise control of the animation sequence
// animation主要用于tween动画
   //根据资源得到动画
   Animation roitateAnimation = AnimationUtils.loadAnimation(this,R.anim.rotata_anim);
  //播放动画完成之后,保留动画最后的状态
   rotateAnimation.setFillAfter(true);
 //播放动画
  btnRotate.startAnimation(rotateAnimation);

// animator主要用于属性动画
   objectAnimator animator = objectanimator.ofFloat(textview,"alpha,1f,0f,1f);
   animator.setDuration(5000);
   animator,start();

   AnimatorSet animatorSet = new AnimatorSet();
    //移动
        objectAnimator ty = object Animator.ofFloat(btn,"translationY",0,300);
          ty.setDuration(1000);
   //旋转
       objectAnimator ty = objectAnimator.ofFloat(btn, "rotationY", 0,1080);
   //透明度
       objectAnimator alpha = objectAnimator.ofFloat(btn, "alpha", 1,0,0.5f,1);
   //缩放
       objectAnimator sx = objectAnimator.ofFloat(btn, "scaleX",1,0.5f);
   //一起播放
        // animatorSet.playTogether(items);
        animatorSet.play(ry),with(sx).after(ty).before(alpha);
        animatorSet.start();

See the full PDF version
(.... To be continued more complete project source code download graphic knowledge subsequent upload github)
can contact me for a full PDF
( VX: mm14525201314 )

Guess you like

Origin blog.51cto.com/14541311/2454806