Android FAQ summary

1. Four characteristics of object-oriented development:

  • Encapsulation : Encapsulation combines data and methods, hides implementation details from the outside, and only exposes externally provided interfaces. This increases security, reliability and flexibility.

  • Inheritance (Inheritance) : Inheritance is to derive a new class from an existing class. The new class has the properties and methods of the existing class, and can extend or modify these properties and methods. This improves code reusability and scalability.

  • Polymorphism (Polymorphism ) : Polymorphism means that the same operation acts on different objects, and can have different interpretations and implementations. It can be implemented through interfaces or inheritance, which can improve code flexibility and readability.

  • Abstraction : Abstraction is to extract common features from specific instances to form abstract classes or interfaces for easy code reuse and expansion. Abstract classes and interfaces allow programmers to focus on high-level design and business logic without having to worry about low-level implementation details.

2. Four major components

  • What are the four components? Activity visual interface, Service interfaceless background service, ContentProvider data sharing content provider, BroadcastReceiver message delivery broadcast
  • When the Activity switches between horizontal and vertical screens, it will go through the life cycle again , from onstop to onCreate. If you configure android:configChanges="orientation|keyboardHidden|screenSize" in the manifest file, you can avoid this situation
  • When onNewIntent is called , Intent is used for communication between components, then onNewIntent is used to handle new data communication, and it is called every time it is reused, that is, it is called when the onRestart() life cycle is taken.
  • The size of the Intent transmission data is limited , because the Bundle in the Intent uses the Binder mechanism for data transmission, and the data will be written to the kernel space, that is, the Binder buffer area. The buffer size is generally 1-2M.
  • Activity startup mode , standard default mode (every startActivity will create a new Activity); SingleTop stack top reuse mode; SingleTask stack singleton mode; SingleInstance global system singleton mode
  • The Service communicates with the Activity , and the Activity can call the method in the Service through bindService(); the Service can send a message to the Activity through broadcasting
  • In the startup process of the Activity , after calling startActivity(), it will transfer to the startActivity() of the ActivityManagerService after many methods, and return to the internal class ApplicationThread of the ActivityThread through an IPC, and call its scheduleLaunchActivity() to send the message of starting the Activity and hand it over to Handler H for processing. Handler H's processing of the message will call handleLaunchActivity()->performLaunchActivity() to complete the creation and startup of the Activity object
  • onSaveInstanceState(), onRestoreInstanceState call timing , when the system recycles the Activity due to insufficient memory, onSaveInstanceState() will be called to save data before the Activity is destroyed; onRestoreInstanceState() will be called when the recycled Activity is started again; if the life cycle of switching between horizontal and vertical screens is as follows onPause() –> onSaveInstanceState() –> onStop() –> onDestroy() –> onCre ate() –> onStart() –> onRestoreInstanceState() –> onResume()

3, RecyclerView cache

Advantages of RecyclerView compared with Listview:

  • Cache mechanism , recycleView four-level cache, listView two levels, and the cache in the screen is placed in a list
  • The writing of ViewHolder is standardized, and it is no longer necessary to call setTag by yourself like ListView
  • Support multiple layouts , LayoutManage built-in linear layout, grid layout, waterfall flow layout
  • It is more convenient to add item animation , control sliding, and modify Item dividing line
  • ItemClick is not supported , but touch events are detected through the RecyclerView.OnItemTouchListener interface. Although slightly 

RecyclerView L4 cache

  • Level 1 cache : mAttachedScrap and mChangedScrap are used to cache the ViewHolder that is still on the screen.
  • Second level cache : mCachedViews, used to cache ViewHolder removed from the screen, the default size is 2.
  • Level 3 cache : ViewCacheExtension, a custom extended cache developed for users, requires users to manage the creation and caching of View by themselves. (uncommonly used)
  • Level 4 cache : RecycledViewPool, the cache pool of ViewHolder, the default size is 5.

RecyclerView's sliding recycling and reuse mechanism 

  • Create an item . For example, 10 ViewHolders can be displayed on the screen. At the beginning, 10 ViewHolders will be created for display, and 5 ViewHolders will be created and placed in the buffer pool.
  • When sliding up, the ViewHolder that slides into the top of the screen will be put into the second-level cache first. Since the default size is 2, the extra 3 ViewHolders will be recycled to the fourth-level recycling. At this time, there are 10 ViewHolders in the first-level cache, 2 ViewHolders in the second-level cache, and 3 ViewHolders in the fourth-level cache.
  • In the process of continuing to slide up , the first-level cache needs to display 15 ViewHolders. At this time, 5 ViewHolders need to be taken out from the fourth-level cache. Since there are only 3 ViewHolders, two caches need to be created
  • After sliding up , 5 ViewHolders of the first-level cache will move out of the screen, and 2 ViewHolders of the first-level cache will be stored in the second-level cache. The previous two ViewHolders of the second-level cache and three ViewHolders of the first-level cache will be cleared and stored in the fourth-level cache

4. The relationship between Activity, Window, DecorView and ViewRoot 

  • Acitiviy is not a real display window, but exists as a carrier and entrance.
  • PhoneWidow is the real display window, there is a PhoneWindow on an Activity, and a DecoView on PhoneWinow
  • The ContentView (R.id.content) above DecoView is where the layout file we really wrote is displayed. PhoneWindow manages DecoView through WindowManager
  • ViewRoot is the manager of DecorView, which is responsible for the measurement, layout, drawing, and event distribution entry of the View tree.
  • WMS is the manager of PhoneWindow. It is a system service that manages the display and hiding of the window and the location to be displayed.

5. View drawing process

The coordinate system of View is relative to the parent control, and the upper left corner of the parent control is the origin:

  • getTop() //Get the distance from the top of the child View to the top of the parent View
  • getLeft() //Get the distance from the leftmost of the child View to the left of the parent View
  • getBottom() //Get the distance from the bottom of the child View to the top of the parent View
  • getRight() // Get the distance from the far right of the child View to the left of the parent View

So the width and height of the control can be calculated as follows:

  • View height = getBottom() - getTop()
  • Width of View = getRight() - getLeft()

The difference between getX and getRawX in MotionEvent:

The coordinates of the touch point relative to its parent view :

  • event.getX()  
  • event.getY()

The coordinates of the touch point relative to the screen coordinate system:

  • event.getRawX()    
  • event.getRawY()      

Meaning of MeasureSpec digits:

  • Simply put, it is an int value, the upper 2 bits indicate the measurement mode, and the lower 30 bits are used to indicate the size

Measurement mode:

  • EXACTLY : the case of match_parent and specific values
  • AT_MOST : wrap_content adaptive mode
  • UNSPECIFIED : Indicates that the measurement mode is not limited, and the parent container does not impose any restrictions on the View. This is suitable for the internal system, and we generally do not use it 

OnMeasure measurement:

  • When customizing View: measure its own size
  • When customizing ViewGroup: You also need to test the size of the sub-View

Measuring subview size code :

  • measureChild(childview, widthMeasureSpec, heightMeasureSpec);

Measure your own size code:

  • setMeasuredDimension(parentWidth,(heightMode == MeasureSpec.EXACTLY) ? parentHeight: parentautoHeight);

padding

  • Custom ViewGroup is generally processed in OnMeasure
  • Custom View is generally processed in onDraw

margin

  • Custom ViewGroup, custom implementation in onlayout
  • Custom View does not need to be processed, it is effective

OnLayout layout:

  • Traversing the position of the child view (you don't need it yourself), child.layout(l,t,r,b)
  • In other words, it is only needed when customizing the ViewGroup, and if there is no sub-View, there is no need to overwrite it.

OnDraw draws:

  • paint is a brush, you can set the color thickness
  • Canvas is a canvas that can draw points, lines, circles, squares, etc., and can also be scaled, displaced, rotated, etc.
  • Matrix is ​​a matrix, and the practice of canvas is the underlying implementation of scaling and translation operations through matrix.

The difference between RequestLayout and invalidate: 

  • requestLayout is a new measure-layout-draw process
  • invalidate is to go through the draw process again.    

6. Thread

process and thread 

  • Process is the basic unit of resource (CPU, memory, etc.) allocation, and it is an instance of program execution.
  • Thread is the smallest unit of program execution. It is an execution flow of a process and the basic unit of CPU scheduling and dispatching.

type of process

  • Foreground process, visible process, service process, background process, empty process

Android inter-process data sharing

  • BroadcastReceiver Broadcast
  1. Advantages: simple and easy to use real-time communication
  2. Disadvantages: only supports one-way data transmission, low efficiency and low security
  3. Scenario: One-to-many low-frequency one-way communication
  • ContentProvider content provider
  1. Advantages: Support one-to-many real-time concurrent communication, powerful in data source sharing, and can expand other operations through the Call method
  2. Disadvantages: It can be understood as constrained AIDL, which mainly provides CRUD operations on data sources
  3. Scenario: One-to-many inter-process data sharing
  • AIDL
  1. Advantages: powerful, support one-to-many real-time concurrent communication
  2. Disadvantages: It is a bit complicated to use, and the relationship between threads needs to be handled well
  3. Scenario: One-to-many communication with RPC requirements
  • File Sharing
  1. Pros: Ease of use
  2. Disadvantages: It is not suitable for high concurrency scenarios, and instant communication between processes cannot be achieved
  3. Scenario: It is suitable for scenarios where simple data is exchanged without high real-time requirements without concurrency.
  • Bundle
  1. Pros: Ease of use
  2. Disadvantage: only data types supported by Bundle can be transferred
  3. Scenario: Process communication between four major components
  • Socket
  1. Advantages: powerful, can transmit byte stream through the network, support one-to-many real-time concurrent communication
  2. Disadvantages: low transmission efficiency, high overhead, slightly cumbersome implementation details, and does not support direct RPC
  3. Scenario: data exchange between networks
  • Messenger
  1. Advantages: general function, support one-to-many serial communication, support real-time communication
  2. Disadvantages: Can't handle high concurrency very well, does not support RPC, because data is transmitted through Message, so only data types supported by Bundle can be transmitted
  3. Scenario: One-to-many real-time communication with low concurrency, no RPC requirements, or no RPC requirements that need to return results

Implementation of threads 

  • basic use
  1. Inherit the Thread class
  2. Implement the Runnable interface
  3. Handler
  • Combined use
  1. AsyncTask
  2. HandlerThread
  3. IntentService
  • advanced use
  1. Thread Pool (ThreadPool)

 Thread state and life cycle

  • New state (New) : After the thread object is created, it enters the new state. For example, Thread thread = new Thread().
  • Ready state (Runnable) : also known as "executable state". After the thread object is created, other threads call the object's start() method to start the thread. For example, thread. start(). Threads in the ready state may be scheduled for execution by the CPU at any time.
  • Running state (Running) : The thread obtains CPU permission for execution. It should be noted that a thread can only enter the running state from the ready state.
  • Blocked state (Blocked) : The blocked state is that the thread gives up the right to use the CPU for some reason and temporarily stops running. Until the thread enters the ready state, it has the opportunity to go to the running state. There are three types of blocking: - Waiting for blocking > By calling the thread's wait() method, let the thread wait for the completion of a certain job. - Synchronous blocking > The thread fails to acquire the synchronized synchronization lock (because the lock is occupied by other threads), it will enter the synchronous blocking state. - Other blocking > When calling sleep() or join() of the thread or issuing an I/O request, the thread will enter the blocked state. When the sleep () state times out, the join () waits for the thread to terminate or time out, or when the I/O processing is completed, the thread is transferred to the ready state again.
  • Dead state (Dead) : The thread finishes executing or exits the run() method due to an exception, and the thread ends its life cycle.
  • Waiting state (Waiting) : Threads in this state will not be allocated CPU execution time, they will wait to be woken up explicitly by other threads

thread termination

  • Use the exit flag to terminate the thread . An exit flag exit is defined in the code. When exit is true, the while loop exits. The default value of exit is false. When defining exit, a Java keyword volatile is used. The purpose of this keyword is to synchronize exit, that is to say, only one thread can modify the value of exit at the same time
  • Use the stop method to terminate the thread , thread.stop(); You can directly use thread.stop() in the program to forcibly terminate the thread, but the stop method is very dangerous, just like turning off the computer power suddenly instead of shutting down according to the normal procedure, it may produce unpredictable results
  • Use the interrupt method to terminate the thread , and use while (!isInterrupted()) {...} to determine whether the thread is interrupted. The principle is that the bit difference of the root flag is not all, but the interrupt is implemented internally, and the flag bit is global and can be set manually.

thread synchronization

  • Use lock objects : By using ReentrantLock and synchronized keywords to lock objects, thread synchronization is achieved. This method is the most basic thread synchronization technology in Java.
  • Use the volatile keyword : Declare a volatile variable to ensure its visibility to all threads, and each write operation will force the cache to be refreshed. This method is suitable for situations where only one thread performs write operations and other threads perform read operations.
  • Use the wait/notify mechanism : The wait/notify mechanism is an advanced and flexible thread synchronization method. The wait and notify methods need to be called inside the synchronized block, release the lock through wait, and let other threads occupy the lock, and notify is to wake up the thread waiting for the lock.
  • Use auxiliary classes such as CountDownLatch and CyclicBarrier : These classes provide more advanced thread synchronization functions, which can realize synchronization between multiple threads. Among them, CountDownLatch is used to wait for multiple threads to complete before executing code, while CyclicBarrier is used to wait for all threads to be ready before executing code.
  • Use the Atomic class : The Atomic class provides some atomic operations, which can avoid data competition problems when multiple threads operate on the same variable at the same time. It is often used for operations on basic data types, such as AtomicInteger, AtomicBoolean, etc.
     

7. Handel principle

Handler management message:

  • Handler sends messages through sendMessage or post
  • The inside of post is also in the form of sendMessage, but the incoming Runnable parameter is packaged into the callback of Message.

MessageQueue message queue:

  • MessageQueue is actually maintaining a Message linked list, which will be sorted according to the when time of the Message, and the delayed message is just the delay time plus the current time
  • The looper is an infinite loop. After reading the source code of messageQuqe, we know that messageQuqe saves and fetches messages is an infinite loop.
  • Internally implement the Parcelable (Android serialization method, storage memory) interface. It is recommended to use obtain to instantiate an object when instantiating message, because the obtain method is obtained from the message pool by default.

Looper transmits messages cyclically:

  • Looper has been calling the next method of MessageQueue to get the message, and then distribute the message
  • Then use the target of the Message to dispatchMessage to distribute the message, and finally recycle the message

The next of MessageQueue is also an infinite loop, why not get stuck:

  • This involves the pipeline mechanism of the linux system, writing data into the pipeline to wake up the cpu, using the nativeWake method
  • When messageQuqe has no data, the CPU is in a dormant state (calling nativePollOnce), and it will only wake up when a message arrives, so it will not take up a lot of CPU resources.

How Message inserts and recycles messages :

  • We can insert new, or use the obtain method to obtain from the message pool (recommended),
  • When recycling, when the message is taken from messageQuqe, just call the recycling method, empty the message and put it into the message pool.

How to implement delayed loading of Message :

  • All sendMessage methods will call the sendMessageDelayed method (only delayMillis=0),
  • When sending a message to messageQuqe, it will carry the execution time parameter (current time + delay time),
  • When fetching a message from the message queue, first compare the size of now and delayMillis, if now<delay, make a difference to the delay time, and then use the difference to delay the wake-up.

8. Android system startup process

When the power is pressed : After the system starts, the order of each layer is executed
BootLoader layer : load the boot program
Linux Kernel layer : start the Linux kernel, load the Linux driver
C++Framework layer : start the first user process: init process, start adb process, log process, meadia service
and then hatch the first java process : Zygote process (connecting java and native)
AndroidFramework layer : start all system services such as AMS and WMS through SystemService.java More than one hundred, manage the
App layer through SystemServiceManager : find the Launcher and start the Launcher 

The difference between subprojects and allprojects in Gradle:

/build.gradle
buildscript {
    repositories {
        jcenter()
        google()
        maven {
            url 'https://maven.google.com/'
            name 'Google'
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
    }
}

allprojects {
    repositories {
        jcenter()
        google()
        maven {
            url "http://maven.xxxxxxxx/xxxxx"
        }
    }
}
  • allprojects is the configuration for all projects, including Root Project; and subprojects is the configuration for all Child Projects
  • The buildscript is the dependencies required for the execution of the gradle script, as shown above, corresponding to the maven library and plug-ins 
  • Allprojects is the dependency required by the project itself. For example, a class in the code is packaged into the maven private library, then the maven private library needs to be configured in allprojects—>repositories instead of buildscript, otherwise it cannot be found

9. Event distribution

The core concept of event distribution

  1. Event Source (Event Source): The event source refers to the object that generates the event, usually the user's input device, such as a touch screen, physical buttons, etc. The event source is responsible for converting the user's operation into an event object and sending it to the application for processing.
  2. Event Dispatch: Event dispatch refers to the process of passing event objects to the correct View for processing. In Android, event distribution is handled by ViewGroup, which is the base class of all Views. When an event occurs, the system will pass the event down from the top-level ViewGroup until it finds a suitable View for processing.
  3. Event intercept (Event Intercept): Event intercept means that during the event distribution process, a ViewGroup can intercept the transmission of the event and prevent it from being passed to the child View. If a ViewGroup intercepts the event, the event will stop passing down and will not be processed by other Views.
  4. Event Handling: Event handling means that after the event distribution reaches the target View, the View performs corresponding operations to respond to the event. Each View can implement its own event processing logic, such as handling touch events, click events, and so on.

Handling Events for Event Distribution

  1. dispatchTouchEvent(MotionEvent event): Used to distribute touch events. In ViewGroup, it will judge whether to pass the event to the child View or intercept the event according to the type and location of the event. If the event is intercepted, the onInterceptTouchEvent() method will be called; otherwise, the event will be passed to the dispatchTouchEvent() method of the child View.
  2. onInterceptTouchEvent(MotionEvent event): Used to intercept the delivery of events. In a ViewGroup, it can decide whether to intercept the event and prevent it from being passed on to the child View. If true is returned, the event is intercepted; if false is returned, the event is not intercepted.
  3. onTouchEvent(MotionEvent event): Used to handle touch events. In View, it is responsible for the logic of actually handling touch events, such as handling touch position, gesture judgment, etc. If the event is consumed, true will be returned; otherwise, false will be returned so that the event can continue to be passed to the upper View.

Event Distribution Mechanism Process

  1. When the user performs a touch operation, the event source (such as touching the screen) will convert the user's operation into a MotionEvent object and pass it to the dispatchTouchEvent() method of the top-level ViewGroup.
  2. In the dispatchTouchEvent() method, ViewGroup will judge whether to intercept the event according to the type and location of the event. If the ViewGroup returns true, it means that the event is intercepted and will not be passed down; if it returns false, it means that the event will not be intercepted and will continue to be passed to the child View.
  3. If the event is intercepted, the onInterceptTouchEvent() method will be called for processing. In the onInterceptTouchEvent() method, ViewGroup can judge whether to intercept the event as needed, and return the corresponding result.
  4. If the event is not intercepted, it will continue to be passed to the dispatchTouchEvent() method of the child View. The child View can process events according to its own needs, such as judging click events, sliding events, and so on.
  5. Finally, the event will be delivered to the onTouchEvent() method of the target View, which is responsible for the specific event processing logic. In the onTouchEvent() method, corresponding operations can be performed according to the type of event, such as processing touch position, gesture judgment, etc.

Explanation of the key methods of event distribution

  1. dispatchTouchEvent(MotionEvent event): This method is used for event distribution, usually located in ViewGroup. In this method, the event can be intercepted or passed to the child View as needed
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        // 在此处进行事件的分发和拦截判断
        boolean handled = false;
        // 拦截事件的逻辑
        if (需要拦截事件) {
            handled = true;
        } else {
            // 继续传递事件给子View
            handled = super.dispatchTouchEvent(event);
        }
        return handled;
    }
    
  2. onInterceptTouchEvent(MotionEvent event): This method is used to intercept events, usually located in ViewGroup. In this method, you can judge whether to intercept the event according to your needs, and return the corresponding result.
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        // 在此处进行事件的拦截判断
        boolean intercepted = false;
        // 拦截事件的逻辑
        if (需要拦截事件) {
            intercepted = true;
        } else {
            intercepted = super.onInterceptTouchEvent(event);
        }
        return intercepted;
    }
    
  3. onTouchEvent(MotionEvent event): This method is used to handle specific events, usually located in View. In this method, corresponding operations can be performed according to the type of the event.
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 在此处处理具体的事件逻辑
        boolean handled = false;
        // 处理事件的逻辑
        if (需要处理事件) {
            handled = true;
            // 执行事件处理的代码
        } else {
            handled = super.onTouchEvent(event);
        }
        return handled;
    }
    

Example of use

  1. Sliding conflicts caused by the nesting of multiple sliding controls, such as the nesting of two Recycleviews in the horizontal and vertical directions, need to be intercepted to determine whether to slide left or optimize, so as to determine which Recycleview consumption event is handed over
  2. Scrollview and Viewpager are nested, and sliding conflicts are handled as above the root, and parent class interception or subclass consumption can be selected
  3. Sliding ceiling effect, after the parent control slides up for a certain distance, it is handed over to the child class to slide.

10. Types of animation

  1. Frame-by-frame animation [Frame Animation], that is, sequentially play the pictures prepared in advance
  2. Tween animation [Tween Animation], the animation effect of View can realize simple translation, scaling, and rotation.
  3. Property Animation [Property Animation], an enhanced version of tween animation, supports animation on objects.
  4. Transition animation [Transition Animation], to achieve Activity or View transition animation effect. Including MD transition animation after 5.0, etc.

11. Persistence scheme

  • File storage : File storage is the most basic data storage method in Android. It does not perform any formatting on the stored content. All data is saved in the file intact, so it is more suitable for storing some simple text data and binary data.
  • SharedPreferences storage : SharedPreferences uses key-value pairs to store data, suitable for storing lightweight data, such as login status, login Token, some configuration and other information
  • SQLite database storage : suitable for complex types and storage of large amounts of data, such as applications that rely on web servers with little data.
  • ContentProvider : system content provider, similar to root SQLite, can customize data type storage
  • Network storage: That is, the data is stored on the remote server, the main server is not destroyed, and the data can be permanently retained.

12. Serialization scheme

 The role of serialization:

  • Serialization is the process of converting an object's state information into a form that can be stored or transmitted. During serialization, an object writes its current state to temporary or persistent storage. Later, the object can be recreated by reading or deserializing the object's state from the store
  • In a word, serialization converts the object state at runtime into binary, and then saves it to stream, memory or transmits it to other ends through the network.
  • Serialization in Android usually uses Serializable or Parcelable 

Differences between Serializable or Parcelable implementations:

  • The implementation of Serializable only needs to implement the Serializable interface. This just marks the object (UID), and the system will automatically serialize it
  • The implementation of Parcelabel not only needs to implement the Parcelabel interface, but also needs to add a static member variable CREATOR to the class. This variable needs to implement the Parcelable.Creator interface and implement the abstract method of reading and writing

Serializable or Parcelable efficiency comparison

  • The use of Serializable is relatively simple, just create a version number; while Parcelable is relatively complicated, there will be four methods to implement
  • Generally, it is recommended to use Serializable when saving data to SD card or network transmission. Although the efficiency is lower, it is convenient to use
  • It is recommended to use Parcelable when transferring data at runtime, such as Intent, Bundle, etc. The bottom layer of Android has been optimized, which is very efficient

13. The difference between MVC, MVP, and MVVM

MVC pattern:

  • M (Model): Model (used to encapsulate data related to the business logic of the application and the processing method for the data)
  • V (View): View (rendered page)
  • C (Controller): Controller (the connector between M and V, used to control the process of the application and the business logic of the page) 

MVP mode:

  • M (Model) model: dedicated to encapsulating and processing data
  • V (View) view: display data
  • P (Presenter) middle layer: responsible for communication between MVs

MVVM pattern:

  • M (Model) model: specially used to prepare data
  • V (View) view: display page
  • V (ViewModel) view: view and model (conversion of view and data)

14,Window,Activity,View

Activity

  • Activity is not responsible for view control, it just controls the life cycle and handles events. What really controls the view is the Window. An Activity contains a Window, and the Window really represents a window.
  • Activity is like a controller, coordinates the addition and display of views, and interacts with Window and View through other callback methods.

Window

  • Window is an abstract class, and what is actually held in Activity is its subclass PhoneWindow. There is an internal class DecorView in PhoneWindow, by creating DecorView to load the layout R.layout.activity_main set in Activity
  • Window is the carrier of the view, which holds a DecorView inside, and this DecorView is the root layout of the view.
  • Window loads DecorView through WindowManager, and hands DecorView to ViewRoot for view drawing and other interactions

View

  • DecorView is a subclass of FrameLayout, which can be thought of as the root node view of the Android view tree.
  • DecorView is the top-level View. Generally, it contains a vertical LinearLayout inside. There are three upper and lower parts in this LinearLayout. The upper part is a ViewStub, which is a lazy-loaded view (should be set to ActionBar, according to Theme settings), the middle part is the title bar (according to the Theme setting, some layouts do not), and the bottom part is the content bar.
  • The layout file set by setContentView in the Activity is actually added to the content bar and becomes its only child View, that is, in the FrameLayout above whose id is content, the corresponding loaded layout can be obtained through the content in the code.

Summarize:

  • An Activity corresponds to a Window, which is PhoneWindow, and a PhoneWindow holds an instance of DecorView, which itself is a FrameLayout

14,JetPack

What is JetPack:

  • Jetpack is a rich component library. Its component library is divided into 4 categories by category, namely architecture (Architecture), interface (UI), behavior (behavior) and foundation (foundation)
  • Each component can be used individually or together

Advantages of JetPack:

  • UI and business logic are decoupled.
  • Effectively avoid memory leaks in lifecycle components.
  • Improve module testability.
  • Improve application stability and effectively reduce the probability of the following abnormal occurrences

JetPack Family:

  • Foundation : AppCompat, Android KTX, Multidex, Test
  • 架构(Architecture)Data Binding , Lifecycles , LiveData , Navigation , Paging , Room , ViewModel , WorkManager
  • 界面(UI)Animation & Transitions , Auto, TV & Wear , Emoji , Fragment , Layout , Palette
  • 行为(behavior)Download Manager ,Media & Playback ,Permissions ,Notifications,Sharing

15 ,ViewBindding,DataBindding

ViewBinding (view binding):

The view binding feature makes it easier for you to write code that interacts with views. When view binding is enabled in a module, a binding class is generated for each XML layout file in the module. Instances of the binding class contain direct references to all views with IDs in the corresponding layout. View binding replaces findViewById in most cases.

android {

   viewBidding {

       enabled=true

   }

}
DataBinding (data binding):

You can use a declarative format (rather than programmatically) to bind UI components in your layout to data sources in your app. It is a tool to realize the binding of view and data, map the data to the xml of the view, and realize the assignment and method call of the view in the xml layout file. After using DataBinding, we no longer need to write findViewById, no need to get control objects, no need to set up monitors, which can save a lot of codes needed to get controls, assign values, and add monitors in our activity

android {

   dataBidding {

       enabled=true

   }

}

16. Network related

network layering

  • Physical layer: network jumper, according to the target ip address, the network card starts routing distribution
  • Link layer: ARP, encapsulating the MAC address corresponding to the current device ip, encapsulating the MAC address of the current gateway ip
  • Network layer: IP, encapsulates the ip address of the current device, the server ip address
  • Transport layer: TCP (connection-oriented) UDP (connectionless protocol), encapsulates the port of the current application on the machine, and the listening port of the server program
  • Application layer: DHCP (Dynamic Host Configuration), DNS (Domain Name System), http (common transmission), https (encrypted transmission), DNS (resolve the domain name of the server to the corresponding ip address -> https/http

The difference between TCP and UDP

  • TCP is connection-oriented; UDP is connectionless, that is, no connection is required before sending data
  • TCP provides reliable service. That is to say, the data transmitted through the TCP connection has no error, no loss, and no repetition; UDP does its best to deliver, that is, it does not guarantee reliable delivery
  • TCP is byte-oriented, in fact, TCP regards data as a series of unstructured byte streams; UDP is packet-oriented. UDP has no congestion control, so network congestion will not slow down the sending rate of the source host (useful for real-time applications, such as IP telephony, real-time video conferencing, etc.)
  • Each TCP connection can only be point-to-point; UDP supports one-to-one, one-to-many, many-to-one and many-to-many interactive communications
  • The TCP header overhead is 20 bytes; the UDP header overhead is small, only 8 bytes
  • The logical communication channel of TCP is a full-duplex reliable channel, while UDP is a full-duplex unreliable channel

HTTP protocol

  • The HTTP protocol is the abbreviation of Hyper Text Transfer Protocol (Hypertext Transfer Protocol), which is a transmission protocol for transmitting hypertext from a World Wide Web server to a local browser.
  • It is based on the TCP/IP communication protocol to transfer data (HTML files, picture files, query results, etc.)
  • It belongs to the application layer protocol in the protocol layering.

HTTP features

  • Simple and fast: When a client requests a service from the server, it only needs to transmit the request method and path. Due to the simplicity of the HTTP protocol, the program size of the HTTP server is small, so the communication speed is very fast
  • Flexible: HTTP allows the transmission of any type of data object, and the type being transmitted is marked by Content-Type
  • No connection: Only one request is processed per connection. After the server processes the client's request and receives the client's response, it disconnects. This method can save transmission time.
  • Stateless: The protocol has no memory for transaction processing, that is, HTTP requests can only be initiated by the client, and the server cannot actively send data to the client

HTTP complete request message

The request message of the HTTP protocol consists of four parts: request line, request header, blank line, and request data

POST http://www.baidu.com HTTP/1.1 HTTP/1.1
cache-control: no-cache
Postman-Token: 800ec750-6ee8-4b2b-a879-f5d854115862
Content-Type: application/json
User-Agent: PostmanRuntime/3.0.11-hotfix.2
Accept: */*
Host: sitapp.2ncai.com
accept-encoding: gzip, deflate
content-length: 38
Connection: close
 
{"seeType":1,"source":1,"userId":"30"}
  • request header
POST http://www.baidu.com HTTP/1.1

GET:请求获得Request-URL所标识的资源
POST:在Request-URL所标识的资源后附加新的数据,即可以向服务端发送请求数据
HEAD:请求获取Request-URL所标识的资源的响应消息报头
PUT:请求服务器存储一个资源,并用Request-URL作为其标识
DELETE:请求服务器删除Request-URL所标识的资源
TRACE:请求服务器回送收到的请求信息,主要用于测试或者诊断
CONNETC:HTTP1.1中预留的能够将连接改为管道方式的代理服务器
OPTIONS:请求查询服务器性能,或者查询与资源相关的选项或需求
  • request header
cache-control: no-cache
Postman-Token: 800ec750-6ee8-4b2b-a879-f5d854115862
Content-Type: application/json
User-Agent: PostmanRuntime/3.0.11-hotfix.2
Accept: */*
Host: sitapp.2ncai.com
accept-encoding: gzip, deflate
content-length: 38
Connection: close
  • blank line
在HTTP协议中,规定空行是必须需要的,即使后面的请求数据为空,也必须有空行
  • request data
{"seeType":1,"source":1,"userId":"30"}

HTTP complete response message

HTTP/1.1 200 
Date: Sat, 11 Aug 2022 04:24:25 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: close
X-Application-Context: application:test:5673
Server: my_server
HTTP/1.1 200 
Date: Sat, 11 Aug 2022 04:24:25 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: close
X-Application-Context: application:test:5465
Server: my_server

{"success":1,"errorCode":"10001","message":"正确","data":{"userName":"CCCC","userId":30,"headPic":"https://www.baidu.com/upload_images/456346235342.png"}}
  • status line
100-199:指示信息,收到请求后,需要请求者继续执行操作
200-299:请求成功,请求已被成功接收并处理
300-399:重定向,要完成请求需要进行更进一步操作
400-499:客户端错误,请求有语法错误或者请求无法实现
500-599:服务端错误,服务器执行错误,无法正确处理请求
  • Common Status Codes
200 OK:客户端请求成功
400 Bad Request:客户端请求有语法错误,服务端无法理解
403 Forbidden:服务端收到请求,但是拒绝提供服务
404 NOT FOUND:服务器无法正常提供信息,或是服务器无法回应
500 Internal Server Error:服务器内部错误,无法完成请求
503 Server Unavailable:服务器当前无法处理客户端请求,一段时间后可能恢复正常
  • response header
Date: Sat, 11 Aug 2022 04:24:25 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: close
X-Application-Context: application:test:8160
Server: my_server
  • blank line
在HTTP协议中,规定空行是必须需要的,即使后面的响应正文为空,也必须有空行。
  • response body
{"success":1,"errorCode":"10001","message":"正确","data":{"userName":"CCCC","userId":30,"headPic":"https://sitres.2ncai.com/_upload_images/user/head/1711181009252.png"}}

The difference between HTTPS and HTTP

  • The https protocol needs to go to CA to apply for a certificate. Generally, there are few free certificates, so a certain fee is required.
  • Http is a hypertext transfer protocol, information is transmitted in plain text, and https is a secure ssl encrypted transfer protocol.
  • http and https use completely different connection methods and different ports. The former is 80 and the latter is 443.
  • The http connection is very simple and stateless; the HTTPS protocol is a network protocol constructed by the SSL+HTTP protocol that can perform encrypted transmission and identity authentication, which is safer than the http protocol

17. Notes

The nature of annotations

  • An annotation is an interface that inherits the Annotation (annotation) interface, public interface Override extends Annotation{}
  • Annotations are just metadata and do not contain any business logic

Annotation features

  • Annotation is a new technology introduced by JDK5.0
  • The format of the annotation: @ annotation name, you can also add parameters
  • Annotations are not the program itself, but they can explain the program. In this regard, annotations and annotations have similar functions
  • Annotations can be read by other programs, such as compilers, etc.
  • Annotations can annotate Java packages, types (classes, interfaces, enumerations), constructors, methods, fields, parameters, and local variables, which is equivalent to adding some additional auxiliary information to them
  • Features of annotations: inspection, constraint, flexibility, convenience and conciseness, let static language have dynamic mechanism
  • Similarities and differences between annotations and XML: XML is loosely coupled and includes all configurations in the project. The larger the project, the more complex the XML. Annotation is a tagged and highly coupled configuration method, which can provide greater convenience and easy maintenance and modification

Compile-time annotations and runtime annotations

  • The retention phase is different: runtime annotations can be accessed at runtime, compile-time annotations are retained until compile time, and cannot be accessed at runtime
  • The principle is different: runtime annotation is a Java reflection mechanism, and Retrofit is runtime annotation, which is only used when needed; compile-time annotation is realized through APT and AbstractProcessor
  • Different performance: runtime annotations use Java reflection, so they have an impact on performance; compile-time annotations have no impact on performance, which is why ButterKnife switched from runtime annotations to compile-time annotations
  • The products are different: runtime annotations only need to customize the annotation processor, and no other files will be generated; new Java source files are usually generated during compilation

Common Notes

  • @Override - Checks if the method is an overriding method. If it is found that the parent class or the referenced interface does not have this method, a compilation error will be reported.
  • @Deprecated - Marks a method as deprecated. If this method is used, a compilation warning will be reported.
  • @SuppressWarnings - instructs the compiler to ignore warnings declared in the annotation.
  • @Retention - Identifies how this annotation is saved, whether it is only in the code, or compiled into the class file, or can be accessed through reflection at runtime.
  • @Documented - Marks whether these annotations are included in user documentation.
  • @Target - Marks which Java member this annotation should be.
  • @Inherited - marks which annotation class this annotation is inherited from (the default annotation is not inherited from any subclass)
  • @SafeVarargs - Supported since Java 7, ignores warnings from any method or constructor invocation that uses a generic variable as an argument.
  • @FunctionalInterface - Supported in Java 8, identifies an anonymous function or functional interface.
  • @Repeatable - Supported by Java 8, it indicates that an annotation can be used multiple times on the same declaration.

18. reflection

reflection definition

  • Reflection is in the running state. For any class, you can know all the properties and methods of this class.
  • For any object, you can call any of its methods and properties
  • This dynamically obtained information and the function of dynamically calling the method of the object are called the reflection mechanism

Reflection pros and cons

  • Advantages: It can be executed dynamically, dynamically execute methods and access attributes according to business functions during operation, and maximize the flexibility of java.
  • Disadvantages: have an impact on performance, such operations are always slower than directly executing java code

use of reflection

  • Use the newInstance() method of the Class object to create an instance of the class corresponding to the Class object
//获取 Person 类的 Class 对象 
Class clazz=Class.forName("com.dong.Person"); 
//使用.newInstane 方法创建对象 
Person p=(Person) clazz.newInstance(); 
  • Use the Class object to obtain the specified Constructor object, and then call the newInstance() of the Constructor object
//获取构造方法并创建对象 
Constructor c=clazz.getDeclaredConstructor(String.class,String.class,int.class); 
//创建对象并设置属性 
Person p1=(Person) c.newInstance("张三","男",24);
  • Obtain an attribute object through the class object
Field c=cls.getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段
Field c=cls.getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced
//获取 Person 类的所有成员属性信息
Field[] field=clazz.getDeclaredFields();
for(Field f:field){
   System.out.println(f.toString());
}
  • Obtain a method object through the class object
Cls.getMethod(),只能获取公共的
Cls.getDeclareMethod(),获取任意修饰的方法,不能执行私有
M.setAccessible(true),让私有的方法可以执行
Method[] method=clazz.getDeclaredMethods();
 for(Method m:method){
    System.out.println(m.toString());
 }
  • Execute method Method.invoke()
Class ownerClass = Class.forName(className);
Class[] argsClass = new Class[args.length];
for (int i = 0, j = args.length; i < j; i++) {
  argsClass[i] = args[i].getClass();
}
Method method = ownerClass.getMethod(methodName,argsClass);
method.invoke(null, args);

19, Binder principle

Linux inter-process communication method

  • pipes, semaphores/semaphores, message queues, shared memory, sockets

Android inter-process communication method

  • Intent, ContentProvider, File Sharing, AIDL, Messenger, Socket

Binder definition

  • The mechanism of inter-process communication: it can be understood as the blood vessel of android, when Activity and Service need to communicate with AMS, Binder is needed
  • Virtual physical device driver: map virtual memory to /dev/binder file when mapping through mmap, which represents a driver in linux
  • Java classes that can initiate inter-process communication: For example, Stub, Proxy, and AMS in AIDL also implement IBinder. In addition, when searching for services in ServiceManager, the value of the Map collection used is also of type IBinder

Advantages

  • Performance: Compared with other methods such as Socket, which need to be copied twice in memory, Binder only needs to be copied once, so the performance is better than other methods
  • Security: The IPC mechanism of Linux has no security measures in its own implementation, while the UID/PID of the Binder mechanism is added by the Binder mechanism itself in the kernel space, which has high security; and Binder can establish a private channel, which cannot be realized by the communication mechanism of Linux
  • Stability: Binder is based on the C/S architecture. If the client (Client) has any needs, it will be thrown to the server (Server) to complete. The structure is clear, the responsibilities are clear and independent of each other, and the natural stability is better.
  • Easy to use: the name, parameters and return value of the client-side function are exactly the same as those of the server, eliminating the gap between the client and server

memory isolation

  • Linux process memory isolation: processes are isolated, memory between processes is not shared, user space and kernel space are isolated, user mode and kernel mode are isolated, and IPC must be used to communicate
  • Memory mapping: The memory mapping involved in the Binder IPC mechanism is implemented through mmap(), which is a method of memory mapping in the operating system. Simply speaking, memory mapping is to map a memory area in user space to kernel space. After the mapping relationship is established, the modification of this memory area by the user can be directly reflected in the kernel space; otherwise, the modification of this area in the kernel space can also be directly reflected in the user space

Binder cross-process process

  • Communication process: First, the Binder driver creates a data receiving buffer in the kernel space;
  • Then open up a kernel buffer area in the kernel space, establish the mapping relationship between the kernel buffer area and the data receiving buffer area in the kernel, and the mapping relationship between the data receiving buffer area in the kernel and the user space address of the receiving process;
  • The sender process copies the data to the kernel buffer in the kernel through the system call copy_from_user(). Since there is a memory mapping between the kernel buffer and the user space of the receiving process, it is equivalent to sending the data to the user space of the receiving process, thus completing an inter-process communication.

operating mechanism

  • Client: The process that uses the service, obtains the corresponding Binder from the ServiceManager by name
  • Server: The process that provides the service, registers the created Binder and its name in character form with the ServiceManager through the Binder driver in the form of a data packet, for remote calling by other processes.
  • ServiceManager: An independent process that converts the Binder name in character form into a corresponding Binder instance, and it maintains a table of Binder names and Binder entities. Registering and obtaining services both use the Binder mode of inter-process communication, and the Binder provided by ServiceManager is different from others. First, the process uses the BINDERSETCONTEXT_MGR command to register it as ServiceManager, and the Binder driver will create a Binder entity for it; when obtaining it in other processes, it is obtained through reference 0 to communicate with ServiceManager.
  • Binder driver: Provides support for some underlying operations such as the establishment of communication between processes and Binder transfer.

    Registration service: Server registers Binder with ServiceManager through Binder driver, and the driver creates a node in the kernel for this Binder and packages its reference and name to ServiceManager, and ServiceManager can fill them into the table.

    Use service: Client is driven by Binder, and uses Binder name to obtain the corresponding Binder reference from ServiceManager. Through this reference, the service provided by Server can be used.

20, ClassLoader class loader

The role of ClassLoader

  • ClassLoader is mainly used to dynamically load Java classes and resource files, these Java classes include applications, Java core library programs, etc.
  • ClassLoader can also load classes used in applets, plug-ins and web applications
  • The loaders in ClassLoader are called the parent class loader and the child class loader in turn, and the parent class plus

entrusted by parents

  • When a class loader looks for classes and resources, it is done through the "delegate mode"
  • It first judges whether the class has been loaded successfully. If not, it does not search by itself, but first through the parent loader
  • Then recurse until Bootstrap ClassLoader, if the Bootstrap classloader is found, return directly
  • If it is not found, it will return level by level, and finally reach itself to find these objects. This mechanism is called parent delegation.

Types of ClassLoaders

  • BootstrapClassLoader : This is the default ClassLoader of the Java Virtual Machine (JVM), which is used to load the Java core class library (such as the classes in the java.lang package). In the Android system, since the Dalvik virtual machine is used, Bootstrap ClassLoader is not used.

  • PathClassLoader : This is an important ClassLoader in the Android system, used to load classes and resource files in apk files, odex files, dex files and jar files. In Android applications, each Module has its own PathClassLoader.

  • DexClassLoader : This is a special ClassLoader in the Android system, which is used to load the classes and resource files in the dex file. Unlike PathClassLoader, DexClassLoader can load dex files from any location, including dex files generated when the application is running.

  • BaseDexClassLoader : This is the common parent class of PathClassLoader and DexClassLoader, which defines some common methods and fields, such as obtaining the parent class ClassLoader, obtaining the class path, and so on.

  • WebViewClassLoader : This is a special ClassLoader in the Android system, which is used to load the classes and resource files in the WebView component.

21 , componentization, modularization, plug-in

  • Modularization : Modularization refers to dividing a project into several modules according to business logic. For example, a shopping app can be divided into product display module, shopping cart module, order module, customer service module, etc., and a project is divided into several layers, so as to ensure that each module has a single function
  • Componentization : Although modularization has been developed hierarchically, the code reusability is not high. Therefore, componentization is a further evolution on the basis of modularization. It is divided into finer parts. Each component is independent. You can select the required components according to your needs and combine them to form the entire project.
  • Plug-in : It is also a kind of modularization in essence. It is also divided according to business logic, but it is not divided into modules, but into plug-ins. These plug-ins can be independently compiled and packaged into an independent sub-app. Because plug-in loading is dynamic, hot fixes can be implemented

22 , hotfix

what is hotfix

  • A hotfix is ​​a silent update to the live version
  • After the APP is released and launched, if there is a serious bug, it usually needs to be re-released to fix it, but the re-release process may take a long time, and the user experience of re-installing the APP is not friendly, so there is a hot fix
  • Hot fix is ​​to release a plug-in, so that the code in the plug-in is loaded when the APP is running, so as to solve the defect, and it is insensitive to the user

Implementation of hot fixes

  • The class loading scheme, that is, dex instrumentation, is also used in plug-in. Such as WeChat’s Tinker, QZone’s QZone, Meituan’s Robust, and Ele.me’s Amigo
  • The underlying replacement scheme, that is, modify and replace ArtMethod, Ali's AndFix, etc.

Principle of Hot Repair

  • According to the class loading mechanism, we can know that the principle of hot repair is to put the patch package dex file in the front position of the dexElements array
  • In this way, when the class is loaded, the dex file in the patch package is first found, and it is no longer searched after it is loaded into the class, so that the class with the same name in the original apk will not be used again to achieve the purpose of repair

hotfix process

  • Get the PathClassLoader of the current application;
  • Obtain the DexPathList attribute object pathList through reflection;
  • Reflection modifies the dexElement of pathList:
  • Convert patch package patch.dex to Element[](patch)
  • Get the dexElements attribute of pathList (old)
  • patch+dexElements merge, and reflect the dexElements assigned to patchList

23. Class loading process

Class loading has five processes

  • Load->Validate->Prepare>Parse->Initialize

load

  • Get the bytecode file of a class by its fully qualified name
  • Convert bytecode to runtime data structures
  • Generate a class object in memory as the method area to enter the human entrance
  • For the process that the array does not need to be loaded through the class, it is dynamically constructed by the JVM, but the internal elements still need to be loaded through the process of the class.

verify

  • Verification is the first step of the link, mainly to verify whether it conforms to the class file format specified by the JVM
  • File format verification: mainly judge whether it conforms to the class file format: whether it starts with a magic number, whether the JVM version conforms, the constant tag of the constant pool Q, etc.
  • Metadata verification: determine whether the loaded class has a parent class, whether it inherits a class that is not allowed to be inherited, whether it is an abstract class, and if not, whether it implements all the methods of the parent class or interface
  • Bytecode verification: verify whether the semantics of the program are legal and logical, and verify and analyze the method body of the class
  • Symbol reference verification: Verify whether the resources (classes, variables, methods) referenced in the class exist and whether the access rights are legal

Prepare

  • Preparation is the second step of the link, the purpose is to allocate only memory for static variables of the class, initialize default values, mainly eight data types, and reference types
  • Note that when boolean is stored in memory, it is stored as int type, 0 means true, 1 means false

analyze

  • Parsing is the second step of linking, which mainly converts indirect references of classes, interfaces, variables and methods into direct references
  • Symbol reference: Use a set of symbols to describe the target of the lock reference, and this symbol can locate the target
  • Direct References: Direct pointers to targets, offsets, and handles that can indirectly locate targets

initialization

  • This is the final stage of JVM class loading. The <cinit> method in the class constructor is executed to initialize the static variables and static methods of the class.

24. Garbage collection mechanism

What is Garbage Collection

  • Most of what we are currently in contact with are high-level languages, that is, object-oriented programming languages. Every time an object is created, a certain amount of space will be allocated in the memory. In this way, when the object dies, it needs to be cleared from the memory, so as to avoid memory leaks caused by full memory, causing the system to freeze or even crash.

how to recycle

  • Manual recycling: such as C/C++, etc., you need to manually mark the reference number of the object, and the reference can be recycled if the reference is 0.
  • Automatic recycling: such as java, the operating environment is in the java virtual machine, which can automatically mark, organize, and clear useless objects

Java memory area

  • Objects referenced in the virtual machine stack (local variable table in the stack frame)
  • Objects referenced by class static properties in the method area
  • Objects referenced by constants in the method area
  • The object referenced by JNI (generally speaking, Native method) in the local method stack

Memory recovery mechanism

  • Young generation: All newly generated objects are placed in the young generation. The young generation is divided into one Eden area and two Survivor areas. During GC, when the Eden area is full, the surviving objects will be copied to one of the Survivor areas (A). When this Survivor area (A) is also full, it will be copied to another Survivor area (B). When the Survivor area (B) is also full, the objects copied from the first Survivor (B) and still alive will be copied to the old age.
  • Old generation: Objects that survive N garbage collections in the young generation are placed in the old generation.
  • The persistent generation mainly stores static files, such as Java classes and methods. The PermGen has no noticeable effect on garbage collection. If the persistent generation space is too small, it can be configured by -XX:MaxPermSize =< N.

GC collector principle

  • Reachability algorithm: Starting from the GCRoot object, search downward. Reachable objects are called GC reachable, and the GC collector will not recycle them. Unreachable objects are called unreachable by GC, and are objects reclaimed by the GC collector.
  • GCRoot object: (1) Objects in the virtual machine stack (the local variable table for the stack frame); (2) Objects referenced by class static variables in the method area; (3) Objects referenced by constants in the method area.

garbage collection algorithm

  • Reference counting algorithm (Reachability Counting): By allocating a space in the object header to save the number of times the object is referenced (Reference Count). If the object is referenced by other objects, its reference count is incremented by 1. If the reference to the object is deleted, its reference count is decremented by 1. When the reference count of the object is 0, the object will be recycled
  • Reachability Analysis: Use some objects called reference chains (GC Roots) as the starting point to search downwards from these nodes. The path traveled by the search is called (Reference Chain). When an object does not have any reference chain connection to GC Roots (that is, it is unreachable from the GC Roots node to the node), it proves that the object is unavailable.

garbage collection algorithm

  • Mark-Sweep algorithm (Mark-Sweep): It is the most basic garbage collection algorithm. It is divided into two parts. First, these objects in the memory area are marked, which are recyclable and marked, and then these garbage are picked out and cleaned up. Just like the picture above, the cleaned up garbage becomes an unused memory area, waiting to be used again. This logic couldn't be clearer, and it's easy to operate, but it has a big problem, that is, memory fragmentation
  • Copying algorithm (Copying): It is evolved from the mark clearing algorithm to solve the memory fragmentation problem of the mark clearing algorithm. It divides the available memory into two pieces of equal size according to the capacity, and only uses one of them at a time. When the memory of this block is used up, copy the surviving object to another block, and then clean up the used memory space at one time. The continuous availability of memory is guaranteed, and there is no need to consider complex situations such as memory fragmentation when allocating memory. The logic is clear and the operation is efficient.
  • Mark-Compact: The marking process is still the same as the mark-clear algorithm, but the subsequent steps do not directly clean up recyclable objects, but move all surviving objects to one end, and then clean up the memory area outside the end boundary.

    On the one hand, the mark-and-sweep algorithm has been upgraded on the mark-sweep algorithm, which solves the problem of memory fragmentation and avoids the disadvantage that the copy algorithm can only use half of the memory area. It looks beautiful, but as can be seen from the above figure, it changes the memory more frequently and needs to sort out the reference addresses of all surviving objects, which is much worse than the copy algorithm in terms of efficiency

  • Generational Collection Algorithm Generational Collection (Generational Collection): Strictly speaking, it is not an idea or theory, but a combination of different algorithms for different situations generated by combining the above three basic algorithm ideas. The difference in the life cycle of the object divides the memory into several blocks. Generally, the Java heap is divided into the new generation and the old generation, so that the most appropriate collection algorithm can be adopted according to the characteristics of each age. In the new generation, it is found that a large number of objects die and only a small number of objects survive each time garbage is collected. Then, a copy algorithm is used, and the collection can be completed only by paying the cost of copying a small number of surviving objects. In the old generation, because the object has a high survival rate and there is no additional space for its allocation guarantee, it is necessary to use the mark-cleanup or mark-organization algorithm for recycling

25. Memory leak

Memory leaks and out-of-memory

  • Memory leak (memory leak): It means that after the program applies for memory, it cannot release the applied memory space, which causes the system to fail to reclaim the memory in time and allocate it to other processes for use. Usually, if the memory cannot be recovered in time for a small number of times, it will not have any impact on the program. However, if the memory itself is acquired too few times and the memory cannot be recovered normally, it will lead to insufficient memory and eventually lead to memory overflow.
  • Out of memory: When the program applies for memory, there is not enough memory for the applicant to use, resulting in the data not being stored in the memory normally. That is to say, you are given a space of int type to store data size, but you store a long type of data, which will cause memory overflow

Common memory leak causes and solutions

  • Memory leak caused by static variables : A static variable and a non-static inner class will always hold a reference to the outer class, resulting in the failure of the outer class Activity to be recycled. Solution: Set the inner class as a static inner class or separate it; use context.getApplicationContext().
  • Memory leaks caused by the singleton mode : The singleton incoming parameter this comes from the Activity, making it hold a reference to the Activity. Solution: pass parameter context.getApplicationContext().
  • Memory leaks caused by property animation : The property animation that does not stop the infinite loop in onDestroy() makes the View hold the Activity. Solution: Call Animator.cancel() in Activity.onDestroy() to stop the animation.
  • Memory leak caused by Handler : Message holds a reference to Handler, while Handler of non-static inner class implicitly holds a reference to external class Activity, so that the reference relationship will be kept until the message is processed, thus preventing the recycling of Activity. Solution: Use static inner class + WeakReference weak reference; clear the message queue when the outer class ends its life cycle.
  • Memory leaks caused by threads : AsyncTask/Runnable exists as an anonymous inner class and implicitly holds a reference to the Activity in which it resides. Solution: Set AsyncTask and Runnable as static inner classes or separate them; use weak references to save Context references inside threads.
  • Memory leaks caused by unclosed resources : Failure to log out resources in time leads to memory leaks, such as BroadcastReceiver, File, Cursor, Stream, Bitmap, etc. Solution: Close or log off in time when the Activity is destroyed. For example: ①BroadcastReceiver: call unregisterReceiver() to logout; ②Cursor, Stream, File: call close() to close; ③Bitmap: call recycle() to release memory (no need to manually after version 2.3).
  • Memory leaks caused by Adapter : not using cache but only relying on getView() to re-instantiate Item each time will create pressure on gc. Solution: Use the cached convertView when constructing the Adapter.
  • Memory leak caused by WebView . WebView is special, even if its destroy method is called, it will still cause a memory leak. Solution: In fact, the best way to avoid memory leaks caused by WebView is to let the Activity where WebView is located in another process. When this Activity ends, kill the current process where WebView is located. I remember that Ali Dingding’s WebView is another process that is started. This method should also be used to avoid memory leaks.
  • Leakage of collection classes : For example, the global map has static applications, but it is not deleted in the end. Solution: Recycle unnecessary collections during onDestry.

26. Performance optimization

layout optimization

  • Minimize the level of the layout file, the fewer levels in the layout, the workload of Android drawing will be less, and the performance of the program will naturally be higher
  • Selectively use ViewGroup with low performance. In the case of simple layout, use LinearLayout first, and then consider RelativeLayout and ConstraintLayout 
  • In the case of complex layouts, RelativeLayout and ConstraintLayout are preferred, and LinearLayout is not recommended for various nesting
  • Use on-demand loading layout ViewStub and Merge, do not take up space hierarchy.

ViewStub

  • ViewStub is a View that has no size and does not occupy a layout. The specified layout will not be loaded into the parent layout until the inflate() method is called or the visibility becomes VISIBLE
  • ViewStub will be removed after loading the specified layout and will no longer take up space, so the inflate() method can only be called once

Use of Merge

  • Merge is neither a View nor a ViewGroup, it's just a marker.
  • merge must be at the root node of the layout.
  • When the layout where the merge is located is added to the container, the merge node is merged without occupying the layout, and all views under the merge are transferred to the container.

drawing optimization

  • Do not create new local objects in onDraw, because the onDraw method may be called frequently, which will generate a large number of temporary objects in an instant, which not only takes up too much memory, but also causes the system to gc more frequently, reducing the execution efficiency of the program.
  • Do not do time-consuming tasks in the onDraw method, and cannot perform thousands of loop operations. Although each loop is very lightweight, a large number of loops still occupy the CPU time slice, which will cause the View drawing process to be unsmooth.

Network Optimization

  • Minimize network requests, and merge as much as possible
  • Avoid DNS resolution. Domain name query may take hundreds of milliseconds, and there may be a risk of DNS hijacking. You can use the method of adding dynamic IP updates according to business needs, or switch to the domain name access method when the IP method access fails.
  • A large amount of data is loaded in a paging manner
  • Network data transmission adopts GZIP compression
  • Join the cache of network data to avoid frequent network requests
  • When uploading pictures, compress pictures when necessary

Android memory optimization

  • Relevant optimizations to reduce memory leaks, as mentioned above, reasonable creation and use of objects, timely closing of resources, and cautious use of references
  • Avoid memory overflow optimization, large image compression processing, timely recovery of Bitmap, location selection of downloaded files, and reasonable use of thread overhead
  • The network and images are loaded using the cache, and the layout loading such as adapter list adaptation also uses the cache to avoid the instantaneous overhead of memory
  •  Tools for detecting and analyzing memory leaks: (1) MemoryMonitor: Changes in memory usage over time. (2) MAT: Input the HRPOF file, output the analysis results, view different types of objects and their sizes, memory occupied by objects and their reference relationship. (3) LeakCanary: A library for real-time monitoring of memory leaks (LeakCanary principle)

Caton optimization

  • Do not perform network access/IO operations on large files in the main thread
  • When drawing the UI, try to reduce the drawing UI level; reduce unnecessary view nesting, you can use the Hierarchy Viewer tool to detect it, which will be described in detail later;
  • When the layout uses FrameLayout, we can change it to merge, which can avoid overlapping calculations between our own frame layout and the system's ContentFrameLayout frame layout (measure and layout)
  • To improve the display speed, use ViewStub: it will only be occupied when loading. It is hidden when it is not loaded, and only takes up space.
  • In the case of the same view level, try to use LinerLayout instead of RelativeLayout; because RelativeLayout will measure twice when measuring, and LinerLayout will measure once, you can see their source code;
  • Delete useless properties in the control;
  • Layout reuse. For example, listView layout reuse
  • Try to avoid overdrawing (overdraw), for example: the background is often easy to cause overdrawing. Since our layout has set a background, the MaterialDesign theme used at the same time will default to a background. At this time, the background added by the theme should be removed;
  • Optional background in XML
  • Custom View optimization. Use canvas.clipRect() to help the system identify those visible areas, only within this area will be drawn. Also avoid overdrawing.
  • Startup optimization, monitoring the startup speed, discovering the problems that affect the startup speed, optimizing the startup logic, and improving the startup speed of the application. For example, splash screen pages, reasonable optimization of layout, optimization of loading logic, and data preparation.
  • Reasonable refresh mechanism, minimize the number of refreshes, try to avoid high CPU threads running in the background, and reduce the refresh area.

Power consumption optimization

  • Reasonable use of wake_lock lock, wake_lock lock is mainly relative to the sleep of the system (here is to save power, it is done), which means that my program adds this lock to the CPU and the system will not sleep. The purpose of doing this is to fully cooperate with the operation of our program. In some cases, if you don’t do this, there will be some problems, such as WeChat and other instant messaging heartbeat packets will stop network access shortly after the screen is turned off. Therefore, there are a lot of wake_lock locks used in WeChat.
  • Use jobScheduler2 to centrally process some network requests, and some that do not need to be processed in a timely manner can be processed while charging, such as image processing, APP download and update, etc.;
  • Calculation optimization, avoiding floating-point operations, etc.
  • When data is transmitted on the network, try to compress the data before transmission. It is recommended to use FlatBuffer serialization technology, which is many times more efficient than json. If you don’t know FlatBuffer, it is recommended to find information to learn.

Bitmap image optimization

  • The main purpose is to compress the loaded image to avoid OOM due to the large size of the loaded image.
  • Operate on the image itself. Try not to use setImageBitmap, setImageResource, BitmapFactory.decodeResource to set a large image, because these methods are finally completed through the createBitmap of the java layer after decoding, which consumes more memory.
  • The zoom ratio of the image. The SDK recommends that its value be an exponential value of 2. A larger value will cause the image to be unclear.
  • For unused pictures, remember to call the recycle() method of the picture

start optimization

  • Optimization through startup loading logic: Distributed loading, asynchronous loading, and deferred loading strategies can be used to improve application startup speed.
  • Data preparation: Data initialization analysis, loading data can consider strategies such as thread initialization.
  • Asynchronous loading: add asynchronous thread to Application, or add asynchronous thread to MainActivity
  • Lazy loading function: load after the first screen is drawn
  • Load layout dynamically: main layout file optimization
  • Main layout file depth optimization
  • Deep optimization of function code

Data structure optimization

  • Use spareArray that comes with Android instead of HashMap;
  • For example, HashMap and ArrayMap, use ArrayMap first;
  • Prefer primitive types over wrappers
  • Reduce usage of memory-intensive enums
  • Using a three-level cache mechanism: LRUCache
  • Image compression: inSampleSize, RGB_565 replace RGB_8888

27. Apk installation package slimming and optimization

  • Reduce unnecessary resource files in the application, such as pictures, and compress the pictures as much as possible without affecting the effect of the APP, which has a certain effect
  • When using the SO library, keep the v7 version of the SO library first, and delete other versions of the SO library. If you use a lot of SO libraries, for example, a version of the SO library has a total of 10M, then only keep the v7 version, and delete the armeabi and v8 versions of the SO library, a total of 20M can be reduced.
  • Res resource optimization, (1) Only use one set of pictures, use high-resolution pictures. (2) UI design Install the TinyPNG plug-in in ps to compress the pictures losslessly. (3) svg pictures: the description of some pictures sacrifices the computing power of the CPU to save space. Principles used: simple icons. (4) The image uses the WebP (https://developers.google.com/speed/webp/) format (Facebook, Tencent, Taobao are using it.) Disadvantage: The loading is much slower than PNG. But the configuration is relatively high. Tool: http://isparta.github.io/ (5) Use tintcolor (android - Changedrawable color programmatically) to achieve button inversion effect.
  • Code optimization, (1) Realize the logic simplification of functional modules (2) Lint tool checks useless files and lists useless resources in "UnusedResources: Unused resources" and deletes them. (3) Remove useless dependent libraries.
  • lib resource optimization, (1) dynamically downloaded resources. (2) The plug-in of some modules is added dynamically. (3) Clipping and compression of so files.
  • Assets resource optimization, (1) It is better to use lossy compression format for audio files, such as opus, mp3 and other formats, but it is best not to use lossless compression music format (2) For ttf font file compression, you can use FontCreator tool to extract only the text you need. For example, when doing date display, only digital fonts are needed, but using the original font library may require a size of 10MB. If you just extract the fonts you need, the generated font file is only 10KB.
  • Code obfuscation, using the proGuard code obfuscator tool, which includes compression, optimization, obfuscation, and more.
  • Plug-in, you can put functional modules on the server and load them when needed.
  • 7z extreme compression, please refer to Wechat’s Anjie package compression for details, realize the realization principle, and analyze it when you have time;

28. Data structure and algorithm Algorithm

Common Data Structures

common algorithm

Common Data Structures in Java

array:

  • An array is a data structure in which elements of the same type can be stored. In Java, we can use arrays to store basic data types like int, float, double, etc., as well as object types. One of the main advantages of arrays is that the elements in the array can be accessed quickly because each element has an index value.
  • The main disadvantage of using arrays is the fixed length. Once an array is created, its size cannot be changed. If we need to insert or delete elements in an array, we must first create a new array, copy all the elements into it, and then insert or delete the desired elements. The time complexity of this process is O(n)

linked list:

  • A linked list is a data structure that can be used to store data elements of the same type. Unlike an array, elements in a linked list do not need to be packed closely together. Each element is called a node and contains a data field that stores the element and a pointer to the next node.
  • There are many different types of linked lists, including singly linked lists, doubly linked lists, and circular linked lists. A major advantage of linked lists is that elements can be added and removed dynamically, since they don't need to be packed closely together. The time complexity of this process is O(1).
  • The main disadvantage of linked lists is that for some operations, such as accessing or searching for an element at a specific index, the access time is longer because it must take O(n) time to traverse the elements in the linked list

stack:

  • A stack is a data structure that can be used to store and manipulate data. A stack can have elements inserted and removed on top of it. The stack follows the "first in, first out" principle, so this data structure can be represented as a "last in, first out" (LIFO) data structure. Therefore, before removing an element from the top of the stack, the top element must be removed first.
  • A stack in Java can be implemented using the built-in class java.util.Stack. It provides many different methods, such as push (push the element onto the top of the stack), pop (delete the top element of the stack) and peek (return the top element of the stack)

queue:

  • A queue is a data structure that can be used to store and manipulate data. A queue can have elements inserted at its end and elements removed from its front. Queues follow the "first in, first out" principle and can therefore be represented as a "first in, first out" (FIFO) data structure.
  • Queues in Java can be implemented using the built-in class java.util.Queue. It provides many different methods, such as offer (add an element to the queue), poll (remove an element from the beginning of the queue) and peek (return an element at the beginning of the queue)

Hash table:

  • A hash table is a data structure that can store key-value pairs. A hash table uses a hash function to map a key value to an index in an array, which makes accessing and searching elements of the hash table very fast. The time complexity of hash table is O(1).
  • Hash tables in Java can be implemented using the built-in class java.util.HashMap or java.util.Hashtable. They are implemented slightly differently, and Hashtable is a thread-safe version of

Tree:

  • A tree is a data structure that can store hierarchically related data. A tree is a collection of nodes and edges where each node contains a value and zero or more pointers to its children. The root node of the tree is unique, while other nodes can be divided into upper and lower levels.
  • Trees in Java can be implemented using the built-in classes java.util.TreeMap and java.util.TreeSet. They use balanced binary trees to minimize the time complexity of searching or inserting and deleting elements. Balance the binary tree to ensure that the height of the tree will not exceed O(log n)

Open source frameworks (LivaData, Glide, OKHttp, Retrofit, Rxjava)

Guess you like

Origin blog.csdn.net/qq_29848853/article/details/130408717