1. How to conduct unit tests and ensure App stability?
- Reference Answer:
To test an Android application, the following types of automated unit tests are typically created
- Local testing: Run only on the local MACHINE JVM to minimize execution time. This unit testing does not depend on the Android framework, or if there are dependencies, it is easy to use a mock framework to simulate dependencies to achieve isolation of Android dependencies, such as Mockito recommended by Google.
- Detection tests: Unit tests run on a real machine or emulator, which are slow due to the need to run on the device. These tests can access instrument (Android) information, such as the context of the application under test. Generally, the dependency is not convenient to simulate through the simulation framework in this way;
- Note: Unit tests are not suitable for testing complex UI interaction events
- The stability of App is mainly determined by the overall system architecture design, while the details of code programming should not be ignored. Just as the so-called “a thousand miles of levees will collapse”, seemingly insignificant code fragments may lead to the collapse of the entire software system once they are not properly considered. So you need to perform Monkey stress tests in addition to your own localization tests before going live
- A few interviewers may extend, such as Gradle automated testing, machine fit testing, etc
2. How to check the recycle status of an object in Android?
- Reference Answer:
- Start by understanding the scenarios and use of the four Java reference types (strong, soft, weak, and virtual)
- Here’s an example scenario: The SoftReference object is used to hold a SoftReference, but it is also a Java object, so when the SoftReference object is reclaimed, the SoftReference object’s get method returns null, However, the SoftReference object is not null. In this case, the SoftReference object is no longer valid. Therefore, a clearing mechanism is required to avoid memory leakage caused by a large number of SoftReference objects
- Therefore, Java provides ReferenceQueue to handle the recycling of reference objects. After the SoftReference object is GC, the JVM adds the SoftReference object to the ReferenceQueue queue. When we call the poll() method of ReferenceQueue, if the queue is not empty, the Reference object is returned and removed.
3. How to compress Apk size?
- Reference Answer:
- A full APK contains the following directories (drag the APK files to AndroidStudio) :
- Meta-inf / : contains cert. SF and cert. RSA signature files as well as the manifest.mf MANIFEST file.
- Assets / : Contains the application resources that the application can retrieve using the AssetManager object.
- Res / : contains the uncompiled resource resources.arsc. lib/ : contains compiled code specific to the processor software layer. This directory contains subdirectories for each platform, such as Armeabi, Armeabi-v7A, ARM64-V8A, x86, X86_64, and MIPS.
- Resources.arsc: contains compiled resources. This file contains the XML content in all configurations of the RES /values/ folder. The packaging tool extracts this XML content, compiles it into binary format, and archives the content. This content includes language strings and styles, as well as content paths, such as layout files and images, that are directly contained in ** resources.arsc*8 files.
- Classes.dex: contains classes compiled in a dex file format that the Dalvik/ART virtual machine understands.
- Androidmanifest.xml: Contains the core Android manifest file. This file lists the application name, version, access rights, and referenced library files. This file uses Android’s binary XML format.
- A full APK contains the following directories (drag the APK files to AndroidStudio) :
– Lib, class.dex, and res take up more than 90% of the space, so these three blocks are important to optimize the size of Apk.
- Reduce res and compress graphic files
- Image file compression is for JPG and PNG images. We usually place multiple sets of images with different resolutions to fit different screens, and we can cut them down here. In practical use, it is enough to keep only one or two sets (it is recommended to keep one set
Xxhdpi, add hdPI for two sets), and then compress the rest of the images (JPG with excellent compression, PNG with PngQuant compression)
- Reduce the dex file size
- Add Resource Confusion
-ShrinkResources is true to remove unreferenced resources, working in conjunction with code compression. – If minifyEnabled is true, code compression is enabled through ProGuard, codes are confused and unused codes are removed together with the configuration of proguardFiles. – Code obfuscation improves security while compressing APK.
- Reduce the lib file size
- Because many third-party libraries are referenced, the lib folder can often take up a lot of space, especially if the so library is available. A lot so library
Armeabi, Armeabi-V7A, and x86 will be introduced at the same time. You can just keep one of armeabi or Armeabi-V7A here. In fact, wechat and other mainstream apps do this. – You only need to configure it directly in build.gradle. Same with NDK
4. How to configure multichannel packages using Gradle?
- Reference Answer:
- First, understand why you have multiple channels. Different marks are added in the installation package, and the application carries channel information when it requests the network, which is convenient for the background to do operation statistics, such as statistics on the downloads of our application in different application markets
- Take the UmENG statistics as an example
- Start by setting the dynamic channel variable in the manifest.xml file:
Gradle = Build. gradle = Build. gradle = productFlavors– Finally in the editor below the terminal output command line –Execute./gradlew assembleRelease, which will type the release package for all channels; – Executing./gradlew assembleVIVO will print the release and debug packages of VIVO channels. – Executing./gradlew assembleVIVORelease will generate VIVO’s release package.
5. Analysis of plug-in principle
- Reference Answer:
- pluggableAPK is divided intohostandThe plug-inPart. The module or function that needs to be implemented is extracted as a separate unit, and we can dynamically implement it while the APP is runningloadorReplace the pluginPart, decreasehostThe size of the
- Host: is the currently running APP.
- Plugins: As opposed to plugins, you load running APK class files.
- Hot fixes focus on fixing known bugs without having to install the application again.
- pluggableAPK is divided intohostandThe plug-inPart. The module or function that needs to be implemented is extracted as a separate unit, and we can dynamically implement it while the APP is runningloadorReplace the pluginPart, decreasehostThe size of the
- Class loading mechanism
- Two common loaders in Android, DexClassLoader and PathClassLoader, both inherit from BaseDexClassLoader. The difference is that the PathClassLoader can only load dex/ JAR/APK files of the internal storage directory. DexClassLoader supports loading dex/ JAR/APK files in specified directories (not limited to internal directories)
- Plug-in communication: Classes can be accessed by generating corresponding DexClassLoader for the plug-in APK, which can be divided into two structures: single DexClassLoader and multiple DexClassLoader.
- With the multi-classloader mechanism, the main project references classes in the plug-in
You need to load the class through the plug-in’s ClassLoader and then call its methods through reflection. Plug-in frameworks generally manage and restrict access to classes in each plug-in through a unified portal. – With the single ClassLoader mechanism, the main project can access the classes in the plug-in directly by the class name. The downside of this approach is that if two different plug-in projects reference different versions of a library, the program may fail.
- Resource to load
- The principle is to add the path of the plug-in APk to the AssetManager through reflection and create a Resource object to load the Resource. There are two ways to handle this:
- Merge: addAssetPath adds all plug-ins and the main project path; Due to the addition of the AssetManager
There are paths to the plug-in and the main project, so the generated Resource can access the resources of both the plug-in and the main project. However, since the main project and each plug-in are independently compiled, the generated resource ids will have the same situation, and resource conflicts will occur during access. – Independent: Each plug-in adds its own APK path. Resources of each plug-in are isolated from each other. However, if you want to share resources, you must obtain the corresponding Resource object.
6. Principle of componentization
- Reference Answer:
- Reasons for the introduction of componentization: Project with the increase of demand scale is becoming more and more big, the increase of the scale leads to the various business fault in complex intertwined, between each business module, code without constraint, the boundary fuzzy code, code conflict occurs frequently, change one small problem may cause some new problems, social phenomena, adding a new demand, Need to be familiar with the relevant code logic, increase development time
- Avoid duplication of wheel, can save development and maintenance costs.
- Components and modules can be used to rationalize manpower for business benchmarks and improve development efficiency.
- Different projects can share a single component or module to ensure the consistency of the overall technical solution.
- Prepare for future plug-ins sharing the same underlying model.
- Component development process is to divide an App or Module with complete functions into multiple sub-modules. Each sub-module can be compiled and run independently, or can be arbitrarily combined into another new App or Module. Each Module is not interdependent but can interact with each other. But in the final release, these components will be consolidated into a single APK, which can even be upgraded or downgraded in some special cases
- Take a simple model example
- Reasons for the introduction of componentization: Project with the increase of demand scale is becoming more and more big, the increase of the scale leads to the various business fault in complex intertwined, between each business module, code without constraint, the boundary fuzzy code, code conflict occurs frequently, change one small problem may cause some new problems, social phenomena, adding a new demand, Need to be familiar with the relevant code logic, increase development time
App is the main Application, ModuleA and ModuleB are two business modules (Relatively independent of each other), Library is the base module, which contains the dependent libraries required by all modules, as well as some utility classes, such as network access, time tools, etc
- Note: The basic components provided to each business module need to be divided into AAR or Library according to the specific situation. The relatively stable components, such as login and basic network layer, are generally packaged into AAR directly to reduce compilation time. Custom View components, for example, are abstracted directly into Library as source code because they will change over iteration
7. Communication across components
- Reference Answer:
- Cross-component communication scenarios:
- The first is page hopping between components (Activity to Activity, Fragment to Fragment, Activity to Fragment, Fragment to Activity) and data passing when jumping (base data types and serializable custom classes
- Cross-component communication scenarios:
Type). – The second is the invocation of custom classes and custom methods between components (components provide services externally). – Analysis of cross-component communication scheme: – The first kind of page hopping between components is simple to realize, and the corresponding API can be provided to transfer different types of data during the hopping. The second type of custom class and custom method invocation between components is slightly more complicated, requiring ARouter to work with the CommonService implementation in the architecture: – Declare the Service interface in the CommonService (with custom methods that need to be called), implement the Service interface in your own module, and expose the implementation class through the ARouter API. -Business modules that use services: -Get the Service interface from ARouter’s API (polymorphic holding, actually holding the implementation class), and then call the custom methods declared in the Service interface, so that modules can interact with each other. In addition, AndroidEventBus can use its unique Tag, which makes it easier to locate the code that sends and receives events during development. If the component name is used as the prefix of the Tag group, it can also better manage and view the events of each component. Using EventBus too much is not recommended either.
- How do I manage excessive routing tables?
- The RouterHub exists in the base library and can be viewed as a communication protocol that all components need to follow. It can contain not only routing address constants, but also various keys that are named when passing data across components, with appropriate annotations. Any component developer needs to rely on this protocol without prior communication. You know how to work together, which increases efficiency and reduces the risk of mistakes, and promises are better than words.
- Tips: If it is too much trouble to write each routing address into the base RouterHub, you can create a private RouterHub within each component and manage routing addresses that do not need to cross components in the private RouterHub. Only routing addresses that need to cross components are managed in the common RouterHub of the base library, which is also recommended if you don’t need to centrally manage all routing addresses.
- ARouter Routing principle:
- ARouter maintains a routing table Warehouse, which stores all module jumps. ARouter actually calls startActivity jumps, using the native Framework mechanism. It just makes jump rules in the form of APT annotations, and artificially intercepts jumps and sets jump conditions.
- Common componentization schemes are as follows
8, componentized route, buried point realization
- Reference Answer:
- In componentization, each business module is independent and does not depend on each other, so A business module cannot access the code of other business modules. If you want to jump from page A of A business module to page B of B business module, it cannot be realized by the module itself. This requires a cross-component communication solution — Router
- There are two routing scenarios:
- The first is page hopping between components (Activity to Activity, Fragment to Fragment, Activity to Fragment, Fragment to Activity) and data passing when jumping (base data types and serializable custom class types)
- The second is the invocation of custom classes and custom methods between components (components provide services externally)
- The principle is to generate a mapping table (data structure is usually Map, Key is a string, Value is a class or object) for some classes distributed in different component modules in accordance with certain rules, and then extract classes or objects from the mapping table according to the string when needed, which is essentially a class search
- Buried points are used to collect information about a particular process in an application to track responses
State of use
- Code burying point: when an event occurs, call the corresponding interface in SDK to send burying point data. Baidu Statistics, Umeng, TalkingData, Sensors Analytics and other third-party data statistics service providers mostly adopt this scheme
- Full buried point: Full buried point refers to the reporting of all behaviors that meet certain conditions generated in the Web page or App to the background server
- Visible buried points: Configure the collection node using a visual tool (such as Mixpanel), and automatically parse the configuration and report the buried point data on the Android terminal to achieve automatic buried points
- No burying point: It does not really need burying point, but the Android terminal automatically collects all events and reports burying point data, and filters out useful data during data calculation at the back end
9. Hook and pile insertion technology
- Reference Answer:
- Hook is a technology used to change the result of API execution, which can redirect the system’s API function execution (the triggering event and background logic processing of the application is executed step by step down according to the event flow. Hook means to intercept and monitor the transmission of the event before it is transmitted to the destination, just like the event on the Hook, and to deal with some specific events when the event is hooked, such as reverse cracking App).
- Hook mechanism in Android, there are roughly two ways:
- To root permission, Hook the system directly, you can kill all apps.
- No root permission, but can only Hook its own app, no other app in the system.
- Pegging is static modification of the third party’s code, that is, from the compile stage, the source code (intermediate code) is compiled, and then repackaged, is static tampering; Hook, on the other hand, does not need to modify the source code or intermediate code of the third party in the recompilation stage, but modifies the call at run time through reflection, which is a dynamic tampering
Android signature mechanism?
- Reference Answer:
- Android’s signature mechanism includes message digests, digital signatures, and digital certificates
- Message digest: Executes a one-way Hash function on the message data to generate a fixed-length Hash value
- Digital signature: A method of storing message signatures in electronic form. A complete digital signature scheme should consist of two parts: a signature algorithm and a verification algorithm
- Digital Certificate: A file digitally signed by the Certificate Authentication Center that contains information about the public key owner and the public key
- Android’s signature mechanism includes message digests, digital signatures, and digital certificates
What is the difference between v3 signature key, V2 and V1
- Reference Answer:
- In v1 signature, the signature exists as a file in the APK package. This APK package is a standard ZIP package. The difference between V2 and V1 is that V2 signs the entire ZIP package. In addition, an APK Signature block is added to the ZIP package, which stores signature information.
– The APK Signing Block itself is divided into three parts: –SignerDataSigner data: mainly includes the signer’s certificate, the entire APK integrity check hash, and some necessary information –Signature(Signature) : the developer to SignerData part of the data signature data –PublicKey(Public key) : public key data used for signature check – V3 version signature block is also divided into the same three parts. Different from V2, V3 adds attR block in SignerData part, which is composed of smaller level block. Each level block can store one certificate information. The previous level block certificate validates the next level certificate, and so on. The certificate for the last level block must match the certificate in SignerData itself, that is, the certificate to which the public key used to sign the entire APK belongs
Big changes between Android5.0 and 10.0
- Reference Answer:
- Android5.0 new features
- MaterialDesign design style
- Support for 64-bit ART virtual machines (ART virtual machines in 5.0, Dalvik before 5.0). The difference between Dalvik and Dalvik is that the bytecode needs to be converted to machine code (JIT) by the just-in-time compiler each time it is run. ART, bytecode is precompiled into machine code (AOT) when the application is first installed) notification details can be designed by the user
- Android6.0 new features
- Dynamic Rights Management
- Support quick charging switch
- Support folder drag and drop applications
- Added professional mode to camera
- Android7.0 new features
- Multi-window support
- V2 signature
- Enhanced Java8 language patterns
- Night mode
- New features for Android8.0 (O)
- Optimized Notification: Notification Channel Notification flag Sleep Notification Timeout Notification set Notification clear
- Picture in picture mode: list the Activity set android: supportsPictureInPicture
- Background restrictions
- Self-filling frame
- System optimization
- And so on and so forth
- New features for Android9.0 (P)
- Indoor WIFI positioning
- “Bangs” screen support
- Security enhancements
- And so on and so forth
- Android10.0 (Q) is currently exposing new features
- Night mode: Dark mode can be set for all apps, including those on your phone.
- *The desktop model: Provides a PC-like experience, but is far from a substitute for a PC.
- Screen recording: Enable by long pressing “Screen snapshot” in the “Power” menu.
- Android5.0 new features
13. Say Measurepec
- Reference Answer:
- WidthMeasureSpec and heightMeasureSpec determine the size of a View
- Composition: a 32-bit int value, with the higher 2 bits representing SpecMode and the lower 30 bits representing SpecSize for a certain measurement mode.
- Three modes:
- UNSPECIFIED: The parent container has no restrictions on how large the View is. Often used within the system.
- EXACTLY: The parent specifies the exact size of the child’s SpecSize. Corresponds to match_parent or a specific value in LyaoutParams.
- AT_MOST(maximum mode) : The parent container specifies a maximum SpecSize for the child View. The View cannot be larger than this value. Corresponds to wrap_content in LayoutParams.
- Determinants: The value is determined by the child View’s layout parameter LayoutParams and the parent container’s MeasureSpec value. The specific rules are shown below:
14. Please give examples of common layout types in Android, and briefly describe their usage and typography efficiency
- Reference Answer:
- Common Android layouts are divided into traditional layouts and new layouts
- Traditional layout (writing XML code, code generation) :
- FrameLayout (FrameLayout)
- LinearLayout;
- AbsoluteLayout;
- RelativeLayout;
- TableLayout;
- New layout (Visual drag and drop controls, write XML code, code generation) :
- Constraint Layout:
- LinearLayout = FrameLayout >> RelativeLayout
- Traditional layout (writing XML code, code generation) :
- Common Android layouts are divided into traditional layouts and new layouts
15. Distinguish the use of Animation and Animator, and outline their principles
- Reference Answer:
- Type of animation: the former only transparency, rotation, translation, telescopic four properties, and for the latter, as long as the control of the property, and setter the property of the method can be implemented on the property of a dynamic change effect.
- Actionable objects: The former can animate only UI components, but property animations can animate almost any object (whether it is displayed on the screen or not).
- Animation playback order: In Animator, AnimatorSet uses methods like playTogether(), playSequentially(), animset.play ().with(), before(), and after() to control how many animations work together. In order to achieve accurate control of the animation playback sequence
16. What image loading library have you used? What is subtle about Glide’s source code design?
- Reference Answer:
- The subtleties of O Glide’s design lie in:
- Glide life cycle binding: can control the picture loading state and the current page life cycle synchronization, so that the whole loading process with the page state and start/resume, stop, destroy
- Glide cache design: through (three level cache, Lru algorithm, Bitmap reuse) for Resource cache design
- Glide’s complete loading process: The use of the Engine class exposes a series of methods for Request operations
17. How do I get around the 9.0 limit?
- Reference Answer:
Which network loading libraries have you used? OkHttp, Retrofit implementation principle?
- Reference Answer:
- Network loading libraries: OkHttp, Retrofit, xUtils, Volley, etc
19. What is done with the application update section? (Grayscale, mandatory update, regional update)
- Reference Answer:
- Internal updates:
- Obtain the online version number and versionCode through the interface
- Compare the online versionCode with the local versionCode, and the update window is displayed
- Download APK file (File Download)
- Install the APK
- Gray update:
- Find a single channel for special releases.
- Upgrade the upgrade platform to allow some users to push upgrade notification or even forced version upgrade.
- Open a separate download entry.
- The code of both versions is typed into the APP package, and then the test framework is implanted in the APP side to control which version is displayed. The testing framework is responsible for communicating with the API on the server side, and the server side controls the distribution of A/B version on the APP, so that A specified group of users can see version A and other users can see version B. The server side will have corresponding reports to show the number of A/B versions and the effect comparison. Finally, it can be controlled by the background of the server, and all users can switch to version A or B online
- Either way, you need to do some versioning and assign special version numbers to distinguish them. Of course, since it is to do gray scale, data monitoring (conventional data, new feature data, main business data) or to do a bit, the data pile to play. Also, gray version had better have the ability to recover, is generally forced to upgrade the next official version.
- Forced update:
- The general processing is to enter the application popup to notify the user of a version update, popup can not be cancelled without a cancel button. This allows the user to update or close the app. You can also add a cancel button, but if the user chooses to cancel, the app will exit.
- ** Incremental update: **
- Binary difference tool BSDIff is the corresponding patch synthesis tool, according to two different versions of binary files, generate patch files. Patch files. Use bspatch to combine old APK files with new APK files. Notice Versions are distinguished by the MD5 value of apK files.
- Internal updates:
20. Can you use Kotlin and Fultter? Talk about your understanding
- Reference Answer:
- Kotlin is a cross-platform, statically typed general-purpose programming language with type inference. Kotlin is intended to be fully interoperable with Java, and the JVM version of its standard library relies on the Java class library, but type inference allows for a more concise syntax.
- Flutter is an open source mobile application development framework created by Google. It is used to develop applications for Android and iOS, as well as the main method of creating applications for GoogleFuchsia
- As for the importance of Kotlin, I’m sure you can appreciate it in your daily development. When applied to real development, you need to avoid syntactic sugar (such as single-column pattern, null value judgment, higher-order functions, etc.).
- As for Flutter, the official Documentation of Google is not perfect at present. There are few projects written in this language on the market. For more details, please refer to the official documentation of Xianyu.
The last
In order to help you switch to the state of learning more effectively and quickly and tread less pits, I put some of my previous learningAndroid knowledge points notes and so onSorted and uploaded toMaking project address: https://github.com/733gh/GH-Android-Review-masterYou want to know moreAndroid knowledgeYou can look it up yourself.