The most complete summary of performance optimization points:

Zero and start optimization

1. Project background

A project in the company 19 is an app with a particularly large number of third-party libraries, which will launch 10 advertising SDKs and several game SDKs. Initially initialized directly in the application

2. Detection start time

adb shell am start -W package name/interface name

3. Print start time

The onCreate, onResume and other methods are time-consuming, especially the methods of initializing many SDKs (you can use the aop method, or the system time subtraction, both are fine; the aop package has apply plugin:'android-aspectjx' implement'org.aspectj:aspectjrt :1.8.+')
Filter the sdk that must be loaded at startup, and the others are placed in sub-threads or delayed loading

4. Optimization concept:

Divide more than a dozen SDKs to be instantiated into three parts: first load, delayed load, asynchronous load, lazy load
Load first: because the homepage has an open-screen advertisement, the sdk of the open-screen advertisement must be loaded first

Dividing various libraries into four situations is to improve the startup speed as much as possible;

5. Transparent page optimization at startup:

Set a transparent body or set the background page earlier; both are more conventional methods. I chose to set the background page to give users the feeling that I opened the app the first time, otherwise there will be a feeling of lag

6. MultiDex optimization

This problem is especially obvious in our third-party SDK projects; small apk is generally a dex; after opening multi-dex packaging, a lot of dex files will be generated; this is the mainstream method I use; other dexs are loaded asynchronously ; The most disgusting process is manual subcontracting, because it is necessary to ensure that the main dex is relatively small; it can be loaded quickly, and then other dexs are loaded in the sub-threads

7. Prevent the SDK from being initialized multiple times when there are multiple processes

Some of the music playback in the project is exaggerated, so it is necessary to prevent some SDKs from being initialized multiple times. This is relatively simple, and the code is not posted.

8. The final result:

Start-up time saved by more than half

1. Memory optimization

1. Project background

This is an e-commerce app project of the bank for 15 years. Because the overall design of the front and back ends of the project at that time was not particularly perfect; the entire image processing was done on the client side; including watermarking, compression, etc., and whether the image was uploaded or The downloads are all high-definition original images, so the performance of the app is a great test; the design of the front and back ends of the app at that time was not particularly reasonable, so the grass caused this problem, but because of this, I exercised the ability and knowledge of memory optimization

2. The concept of performance optimization

There is a reference relationship between two strongly referenced objects, and one of the objects has a long life cycle. When optimizing a project in 15 years, many people will manually call System.gc(), which is a taboo in performance optimization; simply put The object we create is a recyclable environment, so that GC can handle garbage collection when needed. The garbage collection operation itself is also performance-consuming; it is like in a community where a special garbage collection vehicle comes in, you only need Put the rubbish in the trash can and leave the others alone. Don’t call the rubbish truck frequently to collect the rubbish. Once you come to collect the rubbish, you have to stop the world yourself. Everyone is delayed.

3. Understand the reference relationship between objects and the occupation of object size

Pointer compression is turned on by default. In addition to the basic data types, other types occupy four bytes, that is, four bytes are increased by writing one more member variable object; and whether this member variable is specifically referenced to that The object is okay, as long as it is alive, it will take up more memory

4. Understand the points that often cause memory leaks in Android

There are also third-party controls. The common memory leaks placed at the back are:
(1) Time-consuming tasks: network request, attribute animation, Timer
The solution is to release the strong reference relationship in time, make the pointer empty, and stop time-consuming tasks in time; or set the pointer relationship with a weak reference
(2)、handler
Handler is generally because there is a delayed task. There is a Handler type target variable in the message. This is a member variable that refers to the handler. Therefore, if the delayed task does not end, the object where the handler is located cannot be recycled. The solution is to rewrite the handler or clear the delayed task in time
(3) Anonymous/non-static inner class
This is that the inner class object will hold the reference of the outer class, so if the non-static inner class object/anonymous object has a long life cycle, it will affect the recycling of the outer class object.
(4), singleton, applicationContext, ThreadLocal, internal class broadcast, etc.
In fact, it is caused by the difference between the strong reference relationship and the life cycle; the solution is to use weak references and release their relationship in time, because the general singleton, appContext, ThreadLocal will not be killed, and the life cycle is relatively long, so it can only be timely Disassociate the relationship and leave the variable reference empty.
(5), WebView memory leak
This problem has existed for a long time, and I have not noticed whether it has been fixed now. The main reason is that the webView core webkit has a registration relationship with the application, so it must be de-registered. The solution is to get the parent layout of the webView before the activity is closed, and then remove the WebView. , And then stop some methods of webView, clear history and clear views. Finally execute WebView.destroy();
(6) The resource is not closed in time
This is the IO stream, File file stream, and Sqlite, which should only be closed in time when it is used up.
(7), to de-register
For example: eventBus, broadcast, and ContentProvider, etc., all need to be de-registered in onDestory; the evm in the mvp mode I wrote also needs to be de-registered;

5. Memory overflow problem

In Android, this is generally caused by bitmaps or videos that easily cause memory overflow. There are two types of memory overflow, one is direct overflow, and the other is memory overflow accumulated by memory leaks, which are all caused by the heap space being full. oom; bitmap is the compressed picture, the size of the bitmap is determined by the area of the pixel and the color position of each pixel; this is compressed according to the actual size of the bitmap to be displayed; generally, the compression ratio is calculated, and then the bitmap image is extracted;

6. The problem of memory jitter

This is to optimize the program. Now this problem is relatively rare, and it was optimized in 15 years. There are some relatively large objects that are frequently created and destroyed, which will cause memory jitter. In fact, they will start frequently. GC operation; extend the life cycle of this object or optimize the size of this object

7. Experience optimization

This is generally a problem of the overall architecture. When loading some pictures, even if the phone memory is large enough, the internet speed also limits the download speed of the pictures, especially in some list picture functions, the experience will be very poor, if the picture size is small , That gives people a different feeling; they are all more formal now, and this problem is almost gone

8. View memory view;

Learn to use the Android profiler, first manually gc, and then find whether the object exists according to the class name, you can find whether the Android object has a memory leak; in addition to memory, cpu, network, and energy consumption can all be checked

Does the search object exist?

9. Understand the process of object generation and distribution;

It can be allocated in heap memory and stack memory; the heap memory also includes the young generation and the old generation, and it must be judged according to the size of the object;

10. Code execution sequence in the process of object creation

Static variables, static code blocks, code blocks; the execution order of these situations in the construction method, parent class and subclass. Understanding these will help understand the code execution process and memory allocation

11. Optimization of SP files

In fact, it is the question of synchronization or asynchronous. If you want good performance, you must choose asynchronous, and then merge multiple commit();
commit (synchronous) apply (asynchronous)
Alternative: mmkv is produced by Tencent and has been used on WeChat since 15 years, showing that its performance has been tested

12. Detailed optimization process

(1) Choose the best image loading library: The grid compares the advantages and disadvantages and performance problems of various image libraries, chooses the most stable one, and finally determines the use of frsco (after the selection process, the analysis of third-party image libraries is explained)
(2), clear the manual GC operation in the project
(3) Remove the relationship between the network request operation in the activity and the anonymous callback object of the main acitvity; adopt a unified callback method, so that the time-consuming operation of the network request will not affect the normal acitivty object recovery
(4) In view of the memory jitter problem in the project, try to extend the life cycle of the object and compress the volume of the object, the purpose is to reduce the number of times that system.gc comes out to work
(5) Bitmap optimization, set bitmap.Config to ARGB_4444 or 565; then, calculate the compression ratio according to the actual display size of the control, and create a bitmap with appropriate pixels; finally, release the resources in time to execute the recycle() method and make it empty; because There is a bit watermarking operation in the project, so you need to deal with it by yourself
(6). Optimization of writing method, changing the writing method of loading fragment from add to replace. There are fewer member variables in the activity. Some have only a click event and no other operations, so there is no need to create a member variable in the activity. Writing a member variable saves 4 bytes of space. Write the onClick method directly in the xml file, and the efficiency is much higher than the first findViewById and then setOnclickListener; the second is to minimize the nesting of the layout, use include and megre, and viewStub more.
(7) Test the execution efficiency of some parent controls. The performance of RelativeLayout, LinearLayout and Fragmentlayout with the worst efficiency is almost the same. At that time, ConstraintLayout has not yet become popular, so it has not been processed. Some simple layouts prefer Linear/FrameLayout;
(8) Use android studio to check the memory leaks one by one activity; the checking process is to first open the activity page, then close it, and then manually call several gc operations; finally check whether the activity object still exists, and if it still exists, it means there is Memory leaks, and then check them one by one, most of them are caused by anonymous objects
(9) Check that there are objects that are related to singletons and ApplicationContext. These are potential points of memory leaks, so focus on checking
(10) Check the delayed task of the handler. At that time, it will not be weakly referenced, so just manually clear the delayed task of the handler when the activity is closed.
(11) Replace the ListView in the project with RecyclerView. The performance of RecyclerView is much better than ListView, which is also tested;
(12) The app creates a thread pool to uniformly manage some timed tasks, including carousels, SMS verification codes, etc.
(13) Controls such as RecyclerView and ListView should stop the loading of pictures when sliding

13. Optimization results

The crash rate of the project has been extremely high and has dropped to a very low level, and the crash will not occur anymore

Second, the installation package slim

Background of the project

It is also the direct banking project of the bank in 16 years. The android package is too large, which is mainly caused by the addition of various so libraries such as face recognition and maps.

Optimization plan and process

1. There are too many so files, and there are multiple types according to the cpu architecture. This depends on the potential users of the app. If it is a mobile phone, generally only use v7, if it is a pad, use x64, x86, etc., in short, be specific choose

The project at that time used v7
2. Default internationalization: turn off the default internationalization

Because after the android is packaged into an apk, there will be a file called resources.arsc in the apk, which is generated by the files in the res/values folder, and the languages of many countries will be generated by default like this

We only need to set it to only support Chinese or English

3. Some pictures are converted into webp format. Of course, there will be real situations when compressing. This depends on how you choose. If the distortion is not obvious, then it can be compressed or compressed; some small icons can use Vector vector Picture, this volume is also much smaller than png, and there is no need for adaptation. Vector graphics can display the size according to actual needs. If you don’t want to use png, you need to distinguish various screen sizes.

Vector vector, now the logo of a new project android is the vector vector

4. Conventional methods: obfuscation (code obfuscation, resource file obfuscation), removal of useless files; the figure below is to remove useless files, I will not explain the confusion

5. Optimization results: The project volume has been reduced a lot, mainly due to the so file. The choice of the so file is the most objective for reducing the size of android. Other effects are not too great, but the effect of adding less to more is obvious ; The above optimization plan: the confusion of resource files and the optimization plan of Vector vector diagram were useless in the project at that time. I didn’t know these at that time, but I took this opportunity to summarize it and share it with you.

Three, network optimization

1. I don't think there is any good way to do this. First, process the data according to the current network situation. If the network is poor, change the network protocol suspiciously and directly use tcp, mqtt, etc.; if it is http, then open gzip compression; Use ip address to avoid parsing, etc.
2. Create a dictionary for data analysis and compression by yourself;
3. Data caching, connection pool reuse, and merge requests

Four, some simple alternatives to third-party libraries

EventBus

Although this is a very useful library, it has serious performance problems, which is unbearable for people with code cleanliness like me; although the library provided by him is very rich, it needs to traverse all the methods in a class, and then Identify what you need, especially in the activity. There are many methods and variables in your activity. Invisibly, it consumes a lot of performance; the solution can be written like this:

Register where you want to receive data, for example in acitivty:

Of course, there is also the problem of memory leaks, anonymous internal class objects; here is only a case, if you want to switch threads, you can also create a handler in it, you can do all the work of eventBus, but the performance will be much better than it.

Annotation binding control library:

Annotation to instantiate the View control also has this problem; it will traverse all member variables; and will generate additional classes, and include all your control member variables, which is equivalent to double the memory used by the acitivty station, and declare one more member variable It takes up four more bytes of space, and an additional object of 16 bytes will be created; if more pages are accumulated, it will not only consume memory but also consume performance. The principles like Xuils, bufferknife, etc. are the same.

Alternatives to RxJava:

Suspiciously write a simple one, as long as it can meet the business needs of the current app, but it is not satisfied, you can continue to improve it, such as the following example: Of course, if your business is particularly complex, all the functions of the third-party library are basically acceptable. If used, it is better to use theirs directly; this is a balance between development convenience and performance.


Instructions:

1. Conclusion: The business of most apps is not that complicated, and the functions provided by third-party libraries can be said to be exceptionally rich; for most projects, it is too rich and many functions are not used, so additional performance is caused Consumption; Of course, you should pay attention to memory leaks when you write by yourself. If you are not confident enough about memory leaks, you can use third-party libraries honestly.

Five, image loading library problems and performance comparison

1. Background of the problem:

This is also a problem encountered during the performance optimization of the bank’s e-commerce app project for 15 years. Because there are more content, so I just take it out; for example, Imageloader has the best performance, but there is a serious memory leakage problem; Fresco It will completely solve the memory problem, but it is not smooth to use imageLoader; picsso is similar to ImageLoader in my opinion; now the longest is glide, because glide has some automatic management of image loading mechanisms and context life cycle management; In 15 years, for list pictures, you have to manually stop the picture loading function during the sliding process; this gilde has helped us deal with it; there is also context life cycle management to avoid the generation of memory leaks

2. Picture library test results:

Fresco has the best stability; the Glide experience is the smoothest and there is no memory leak problem; there is automatic life cycle management, ImageLoader, Xutils, and piacsso have been basically eliminated; nowadays, many well-known manufacturers’ apps and image libraries used are Glide.

3. Test process

At that time, I wrote the function of an album, and used the above image loading library to load the album, and then repeatedly opened and closed the album page, recording the number of openings and fluency; the final conclusion of the test

4. Suggestions for use:

Personal advice: xUitls3, Imageloader, and picasso can be discarded; Imageloader has serious memory leaks, and xUtils and picasso are not updated. It is estimated that this is a problem of the mechanism; after all, network requests are a time-consuming operation and all need to Incoming context
Recommend Glide: Reasons
(1) Most mainstream apps use Glide to decompile these source codes; it shows its popularity
(2) Its own Context life cycle management can detect when the activity/frgment page is closed and Glide can stop the download of the picture at the first time, thus preventing the leakage of memory and the consumption of cpu resources;
(3) Glide supports gif pictures
(4) Support to stop loading pictures when sliding with the sliding list
(5). Finally, Fresco. This is a thing at the bottom of the box. If Glide can't meet it, take it out; Fresco's library written in c stores the image data in the ashmem area, so that it does not occupy the jvm Heap memory, so it is the ultimate big move; but it is not as smooth as the previous java experience when using it, so it is the last choice;
As for some other caching mechanisms and caching strategies, such as whether the cached image is compressed or the original image, the difference is not big, and the settings can be manually modified, so these mechanisms will not be used for reference.

Six, lock optimization synchronized and lock

Let’s just talk about it briefly. You need to understand the lock upgrade process, coarsening, elimination, etc. of synchronized; the abstract queue synchronizer in the lock, cas spin, user mode, kernel mode, and operating system mutexes; more content, You can learn by yourself, and I will simply say and conclude: Use the sync keyword if the amount of concurrency is small, and use Lock if the amount of concurrency is large.

The optimization direction of the lock:

1. Minimize the execution time of the locked part of the code, because there may be other threads waiting. The more threads waiting, the longer the last thread can execute to the locked content
2. Reduce the strength or scope of the lock: For example, the ConcurrentHashMap in the Map is a thread-safe collection. The lock only locks a single bucket. Even if two threads write data at the same time, as long as the hash value is calculated There will be no impact if the target is no longer in the same position;


3. Lock separation: lock the two operations that do not affect each other, such as linkedBlockQueue

We see that different locks are used for different operations;
Extended singleton writing recommendation
Singleton recommends static internal class singleton. Even if it is thread-safe, it is lazy loading and does not require shackles, so it will save a lot of performance in terms of performance;

Seven, the drawbacks and solutions of the MVP design pattern (emphasis)

Problems with Mvp:

Contact the mvp model from the very beginning, continue to think and improve the writing of mvp to achieve the best requirements, the code is small, decoupling; the business logic is clear, I have tried many times, this year I have to write an open source project, so simply follow Over the years, I have reorganized the wording of a mvp, which has been put on github, welcome to communicate

(1) The first is the design idea problem

View is divided according to business and View is divided according to interface; how to divide Persent; is there a one-to-one correspondence between present, model, and View; in fact, this involves activity; if View is divided according to interface, then View It is sufficient to directly define the return value of ResponseData type; there are several interfaces to define how many Views; another way is to divide according to the business, for example, the login business may include login, verification code, SMS login, and forget password. These operations , Write these businesses into a LoginContract, and then define other various businesses separately, I prefer the latter

(2) Excessive present and model problems

If there is only one interface and a simple function in a page, do I need to write an additional presentation, model, and view? This is very redundant; it is also not conducive to the speed of development; if there are too many such activities, that is, to write an actvity, you must write a view and a present, obviously such a large amount of code is too stupid

(3) The problem of memory leaks

We know that network requests are time-consuming operations. Once the user closes the activity when the network is not good, the activity cannot be recycled at this time, which causes memory leaks. Activity is generally a large user of memory, although weak references can be used to deal with, but weak references will also create additional objects, which will increase the memory footprint

(4) Solution

Create the Evm intermediate class so that there is no strong reference relationship between the present and the View and the model, so there will be no memory leakage problem; then the present and the module can be freely defined, and you can define a few if you want to define them. It can be associated through the EVM intermediate class, and the reflection method is adopted, which only obtains the interface, so it has no impact on performance. Unlike EventBus and ButterKnife, all methods or variables are traversed, and if the View has been recycled, one will be generated. Temporary object of this interface type, no need to judge whether it is empty

The code is:
/**

  • description:
  • author: tianhonglong
  • new date: 2021/7/9
  • version: v 1.0
    */

public class EVM {

private EVM() {
}

private Map<String, EasyView> views = new HashMap<>();
private Map<String, EasyPresent> presents = new HashMap<>();

private <T extends EasyView> T getView(Class<T> clazz) {
    EasyView easyView = views.get(clazz.getSimpleName());
    if (easyView == null) {
        try {
            return clazz.newInstance();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
    return (T) easyView;
}

private <T extends EasyPresent> T getPre(Class<T> clazz) {
    EasyPresent present = presents.get(clazz.getSimpleName());
    if (present == null) {
        try {
            T t = clazz.newInstance();
            presents.put(clazz.getSimpleName(), t);
            return t;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
    return (T) present;
}

private void managerView(EasyView easyView, boolean registerOrNot) {
    Class[] classes = easyView.getClass().getInterfaces();
    for (Class clazz : classes) {
        if (EasyView.class.isAssignableFrom(clazz)) {
            if (registerOrNot) {
                views.put(clazz.getSimpleName(), easyView);
            } else {
                views.remove(clazz.getSimpleName());
            }
        }
    }
}

public static void register(EasyView easyView) {
    EVM.ins().managerView(easyView, true);
}

public static void unregister(EasyView easyView) {
    EVM.ins().managerView(easyView, false);
}

public static <T extends EasyView> T getV(Class<T> clazz) {
    return EVM.ins().getView(clazz);
}

public static <T extends EasyPresent> T getP(Class<T> clazz) {
    return EVM.ins().getPre(clazz);
}

private static class InnerClass {
    private static EVM easyPresent = new EVM();
}

private static EVM ins() {
    return InnerClass.easyPresent;
}

}
Used in basectivity:

And only search for the connected interfaces, there will not be too many interfaces for a class, so it will not affect the performance
defines a base class interface
Write a LoginContract, define the View and present related to login in it

In LoginActivity,

Looking at the present code: very elegant

(5) Summary of this mvp design:
1. Completely release the association between View, Present, and model. Among them, model, View, and present can write as many as they want. Through the evm intermediate class association, they can all call each other;
2. Solve the memory leak problem of View, and can call each other without direct strong reference, so it will not affect the memory recovery;
3. Only need to pay attention to the development of the business and design the model for the interface

Nine, the optimization of View drawing

(1) Multiple nesting issues:

When optimizing other people’s code, the most common problem in layout files is too much nesting. Many subspaces can be achieved. Many people have to add a parent control, such as LinearLayout, RelativeLayout, etc., and then use merge to reduce nesting. Set, because the spatial rendering calculation is recursive, in the previous old models, as long as the 7-layer Layout is nested, there will be obvious lag, but if it is at the same level, even the 14th layer will not have any Problem, so when some interfaces use LinearLayout and will not bring more control levels than RelativeLayout, LinearLayout is preferred;

(2) Performance comparison of various controls:

The worst performance is RelativeLayout; if both LinearLayout and FrameLaout are satisfied, RelativeLayout is excluded first; if it is more complicated, use Google’s new ConstraintLayout; and RecyclerView has much better performance than ListView, such as loading fragments in addition to laziness In addition to loading, replace also add to save memory

(3) Use the placeholder ViewStub:

In some interface controls, the initial state needs to be View.GONE; but even if it is View.GONE, this control will still execute various instantiation methods to create objects that occupy memory, but in the end it is not rendered on the phone screen through wms. ViewStub is a lightweight View; after using ViewStub, the original control is equivalent to lazy loading. It will be loaded only when the user makes it display by hand. If the display is not required, it will never be loaded. ; Just there will be one more lightweight ViewStub

(4) Conclusion:

In the process of writing code, there are many inadvertent points that can save memory, as long as you save the use of memory and cpu everywhere; the accumulation is a good project; if you do not save on memory, accumulate The oom caused by memory leak is the most difficult to solve and optimize;

10. Some well-known memory management and monitoring software

(1) LeakCanary

It is to use WeakReference and ReferenceQueue these two types of mechanisms to check whether the memory is leaked; Suspicious helps you quickly locate the point of memory leak; But it can't help you solve the problem of memory leak, just help you find the problem

(2) koom

Kuaishou self-developed OOM solutions. The efficiency is said to be much better than that of leakCanary. I haven't used it before. I recommend it to everyone;

11. Data encryption optimization

Background of the project:

This is a project optimized for 20 years. Because I have more experience in the banking and financial app industry, there are problems with the data security in some non-bank apps; directly use asymmetric encryption and decryption of data; this Performance is a big problem;

Optimization:

To use a combination of symmetric encryption and asymmetric encryption, the communication data should be encrypted and decrypted with symmetric encryption, then the symmetric encryption key is encrypted and decrypted with asymmetric encryption, and then the encrypted key is spliced and hidden in the data , So that the performance will be greatly improved under the condition of the same security
Symmetric encryption

Asymmetric encryption

Hashing algorithm:

Commonly used encryption schemes:

MD5: For example, the password entered by the user is encrypted with MD5, and the MD5 data is stored directly in the background, and then the integrity of the data is verified
Sha-1: What's in the general signature key
Symmetric encryption: encrypt basic data, because the performance is much better than asymmetric encryption
Asymmetric encryption: Encrypt the keys of symmetric encryption and use them in combination, so that the security has reached the asymmetric level and the performance has been improved;

Summarize:

MD5 check integrity + symmetric encryption to encrypt all data + asymmetric encryption symmetric encryption key
The most commonly used is MD5+RSA+AES

Twelve, revise the programming thought! Object-oriented or process-oriented

(1) Object-oriented development and process-oriented development

This is an optimization project in the current company; although java is an object-oriented language, colleagues in many projects still use a process-oriented thinking model for development; for a simple example, such as the face recognition app that I used to do, There is such a scenario, after the face recognition gets the data, a user object is generated, which contains the user's starting and ending time and the user identity; first look at the process-oriented writing, an extremely simple case:

Look at the object-oriented writing:

The contrast between readability and conciseness is obvious; that is, when writing code, you must distinguish between business process and business details; the process here is whether the person is passable, and the business details are the process of judging whether the person is passable; this part of the code is not required Appear in the process

The above is just a simple example. The actual judgment of whether to pass in our project is much more complicated, including multiple groups and multiple periods, so the judgment process is very complicated and there is a lot of code.

Thirteen, architecture: some design thinking about the business logic of app code

1. Project background:

This is the business logic that optimizes the code. The most typical face recognition page activity has 7500+ lines of code, which contains various services including: data synchronization, UI display (recognition result display), face authentication The process (including face, temperature, mask, distance recognition, hardware interface callback, etc.), and processing of some business details, such as whether the face is the same person in the last two times, wifi status monitoring, etc.;

2. Optimization ideas:

According to business classification, it can be divided into UI part, verification process part, verification detail processing part, and object-oriented part; split into three activities, originally a FaceVerifyActivity, now split into FaceBusinessActivity, FaceUIActivity, where the inheritance relationship:
FaceVerifyActivity inherits FaceBusinessActivity inherits FaceUIActivity
The function of FaceUIActivity should only include the UI part, and has no logical relationship with face authentication. It only provides various dialogs or other UIs that may need to be displayed when the face result comes out.
FaceBusinessActivity contains methods for judging whether the last two times are the same person, methods for data synchronization, etc.
FaceVerifyActivity: It is purely a judgment of the business process, and then according to the result of each judgment, the methods of FaceUIActivity and FaceBusinessActivity are called, so that the entire business logic is much clearer

3. Details and examples

Due to the large amount of code in the original project, it is impossible to post all of it; so here is an example:
The first is UIActivity, which defines some UI dialog boxes that need to be displayed

The second is business activity, which defines door opening, data synchronization, whether the same person is the same, etc.

Finally, the main process activity: pure process judgment

1. In the case, each page has 30-40 lines of code. If it is not split and written in accordance with the object orientation, there will be 110 lines of code in one page. This is just a case. In a real project, the amount of code in the case is expanded by 70 Times, is the actual code in our project, an activity has more than 7000 lines of code, who doesn't have a headache? After splitting, it is divided into three parts, each of which is more than two thousand lines. Besides FaceVerifyActivity, there are no calls between the methods in the other classes. They are all separate business methods. It will be much simpler and easier to modify in the future; this is actually It belongs to the idea of modularization, classified by type, that is, the purpose is to make the code single, concise, easy to modify, and easy to expand;
14. Database and high concurrency optimization
1. Problem background
First of all, I am ashamed; this question is not my actual work experience; this is the question asked by the interviewer when I went to a certain company for an interview, asking about high-concurrency data storage and data optimization, the answer is not very good, and it is indeed not. In terms of experience, in the attitude of not having to learn, I have studied a lot of articles and codes, and I will share them here. Let’s talk about how the client can solve it here.
2. High concurrency optimization for 10,000 people
Question 1: The message has never been read, how to send this message? If it is real-time, the message that has been read must be sent to 10,000 people. If 10,000 colleagues read this message, it will happen that 10,000 colleagues send messages to 10,000 people, and the amount of concurrency can be imagined; this The solution is to reduce the frequency, whether it has been read, refresh it every 10 seconds, which greatly reduces the number of concurrent messages
Question 2: When one person receives multiple messages from different people, a buffer is established. , Merge multiple messages to one person, and A, B, C, D and A send messages to A at the same time, then a buffer mechanism is established to combine A, B, C and D into a message, so that at the technical level A only receives one set of messages, in short, the purpose is to reduce the number of concurrent;

3. Database optimization
The concurrency optimization of the database is similar to IM communication. There are transactions in the data, which is actually equivalent to establishing a buffer to merge multiple pieces of data, and then opening a special ready-made to perform database operations
(1), open the transaction
SQLite in Android opens transactions by default. Even if only one data is inserted and updated, it will help you open the transaction. Therefore, when the amount of concurrency is large, put multiple execution statements in one transaction, which improves performance. No need to open and close the transaction every time;
(2), create an index
Indexing is to create a directory of data in the database. When searching, you do not need to check it page by page. The index is generally a balanced tree structure; in short, it uses algorithms and data structures to improve efficiency, but it seems that the amount of data is particularly large. At the time, maintaining the index will also incur a lot of overhead;

(3) Asynchronous operation is time-consuming
For example, some data storage and synchronization do not need to know the return result, so that a thread pool is established to perform these tasks, so that it will not affect the main thread operation
15. Common ANR operations
The principle is also very simple. The system services ams and wms will detect the app response time, that is, whether the local applicationThread will send binder information to ams and wsm in a timely manner. If it is not sent for a certain period of time, the system will think you are stuck; It will prompt no response, because the information sent to the system service through applicationThread is executed through the main thread, so once the time-consuming operation is performed in the main thread, it will cause ANR
16. Android-specific libraries and some code base writing
1. The serialization of the object Android's unique Parcelable has better performance than Serializable
2. Android-specific collections: use SparseArray and ArrayMap instead of java collections when the amount of data is small
3. Multiple traversal methods of Map, which are the fastest
4. When writing the basic library, especially when dealing with data, use StringBuilder in the case of thread safety, and use StringBuffer in the case of incomplete threads
5. Determine whether to use a linked list collection or an array collection according to data storage and usage
6, try to use basic data types, such as int type member variables occupy a total of four bytes of heap space. If you use Integer, in addition to the four bytes of the member variable in the class, there will be 16 bytes of the Integer object;
7. Reduce the recalculation of variables in the loop
For example: for(int I = 0; i <list.size(); i++) is changed to for(int I = 0, len = list.size(); i = len; i++)
8. Avoid using two-bit arrays. The data is special. No matter whether you store the object or not, the memory has been consumed at the moment the array is created. Each pointer in the array occupies four bytes; the object header and the length of the array are not counted. The moment a two-dimensional empty array with a length of 10 is created, it occupies 10 10 4 = 400 bytes; not counting the length of the object header pointer array; the same as ArrayList, because they are all arrays
9. Json serialization performance comparison: use gson if the amount of data is small, and use Alibaba's fastjson if the amount of data is large

Author: Tian Honglong


性能优化实践者
11 声望220 粉丝