Preface A qualified code should not only realize the function, but also follow good specifications. Following good code specifications is beneficial to: - Improve program stability, reduce code risks, and reduce failure rates;
- Enhance scalability and greatly improve maintenance efficiency;
- Unify standards and improve the efficiency of multi-person collaboration;
- It is convenient for newcomers to get started quickly and ensure the project progress when there are changes in project team members.
Here are some things that need to be paid attention to during Android development, including multiple parts, and divided into two categories according to the strength of the constraints: - Mandatory: Failure to comply will result in serious code confusion, complicated later maintenance, and even serious bugs;
- Recommended: Failure to follow this may result in unclear code descriptions and difficulty in understanding, which may lead to the problem that the more features there are, the more difficult it is to maintain.
Below is the specification text System Design Mandatory: - Two identical logic blocks are not allowed to appear. They must be extracted as public methods and their differences controlled by parameters to avoid omissions caused by multiple modifications during modification.
- It is not allowed to have two identical complex layouts in the same logical group, and they must be extracted as separate include/merge;
- Subclass specific methods are not allowed to appear in the parent class. If necessary, the parent class can define abstract methods and let the subclass implement them;
- Direct communication between multiple Fragments within an Activity is not allowed and must be transferred through the Activity.
recommend: - It is recommended to use MVP or MVVM architecture;
- Kotlin language is recommended;
- Use module classification instead of file classification to quickly find module-related content. For example, put files belonging to the same login module such as LoginActivity/LoginPreenter/LoginHttpRequest/LoginBean/LoginAdapter into one folder instead of putting all activities into one folder and all adapters into one folder.
Naming Mandatory: - Chinese naming is not allowed;
- Java/kotlin files use upper camel case, for example: LoginActivity.kt, NewsAdapter.kt, NewsBean.java;
- Resource files such as layout/drawable/anim/style use lowercase + underscore, for example: login_activity.xml, login_logo.png;
- Class definitions use upper camel case, for example: class LoginPresenter {}, class NewsBean {};
- Objects use lower camelCase, for example: LoginPresenter loginPresenter, NewsBean newsBean;
- Static constants use all uppercase letters and underscores, for example: public static final boolean IS_RELESAE = true;
- The control ID in the layout used by Kotlin must use lower camel case, for example: android:id="@+id/tvLogin".
recommend: - Use the module + type method when naming files/resources to quickly find related content, such as login page: LoginActivity.kt, login_activity.xml, login_logo.png, network error, #f3f3f3
- It is recommended that the ID name in the layout used by Java use lower camel case and start with the control type abbreviation, for example: android:id="@+id/tvLogin", Appendix Common Control Abbreviations:
Visibility Mandatory: - All newly defined classes/methods are written as private by default, and are marked as public, protected, or package-private only when they are referenced by other classes;
recommend: - If a method defined in a parent class defined in Java causes problems if it is overridden by a subclass, add the final keyword;
Comments related Classes/complex methods or methods whose intent cannot be seen from the method name must be annotated. When annotating a class/method, this type of annotation must be used: - /**
- * Created by XXX on 2019/6/19.
- * Describe this type of effect, explain the main idea if the logic is complex
- */
- public class LoginPresenter {
- /**
- * Used to make network requests
- * @params xxx XXX
- */
- public void doLoginRequest(...){}
- }
Variable annotations are not allowed to use the same annotation format as classes/methods; Incorrect parameter descriptions of @params and @return are not allowed in method comments and must be updated in real time; recommend: - A logic suggestion uses the /* */ method;
- It is recommended to add annotations such as @Nullable, @NotNull, @UiThread, etc. to methods/parameters;
Coding style - This git directory also contains the AndroidCodeStyleSetting.jar configuration file, which is used to format the code in a unified style after AndroidStudio imports it.
- If you don't have the habit of formatting your code at any time when writing code, you can check the Reformat code option in Before Commit on the right side of the AndroidStudio version control submission window.
Android basic components Mandatory: - Intent communication does not allow the transmission of data exceeding 1M. You can use external Presenter transfer or EventBus transmission;
- When Intent is implicitly started, you must check whether the target exists, otherwise the target cannot be found and a crash will occur: if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null);
- If there are time-consuming operations in Activity/Service/BroadcastReceiver, multi-threading must be used for processing;
- When sending broadcasts within an application, only LocalBroadcastManager.getInstance(this).sendBroadcast(intent) can be used. Context.sendBroadcast(intent) is not allowed to avoid interception by external applications.
- Data caching is not allowed in the Application. Global shared data can be stored using a presenter or read and written using SharedPreference.
- When dynamically registering BroadCastReceiver in Activity or Fragment, registerReceiver and unregisterReceiver must appear in pairs;
recommend: - In Activity#onPause/onStop, combine the judgment of isFinishing to execute resource release, and avoid putting it in Activity#onDestroy() which is executed later;
- Do not perform time-consuming operations in Activity#onPause, as this will cause the interface to jump and become stuck. Instead, you can perform them in Activity#onStop;
UI/Layout Mandatory: - ConstraintLayout is preferred for layout XML, which can ensure that 99% of layout requirements, including the requirement to show and hide some controls at the same time, can be met without nesting;
- It is not allowed to use ScrollView to wrap ListView/GridView/ExpandableListVIew and other list views. Complex polynomial lists can be processed using multiple ItemTypes;
recommend: - When displaying a dialog box or pop-up window in an Activity, try to use DialogFragment instead of Dialog/AlertDialog to manage the life cycle of the pop-up window with the Activity life cycle;
Process/thread/message push Mandatory: - When there are multiple processes, the initialization code in the Application should be processed separately according to the process to avoid initializing unnecessary services;
- When creating a new thread, it must be done through the thread pool, and new Thread() is not allowed;
- When using Handler in Activity/Fragment, you must use static inner class + WeakReferences or call handler.removeCallbacksAndMessages in onStop;
recommend: - To share data between multiple processes, use ContentProvider instead of SharedPreferences#MODE_MULTI_PROCESS;
Files/Databases Mandatory: - Use system API to get the file path, avoid manually spelling the string, for example: android.os.Environment#getExternalStorageDirectory(), Context#getFilesDir(), Error example: File file = new File("/mnt/sdcard/Download/Album", name);
- When using external storage, you must check the availability of external storage: Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
- The database Cursor must be closed after use to avoid memory leaks;
recommend: SharedPreference only stores simple data types, not complex data, such as json data/Bitmap encoding, etc.; When submitting data to SharedPreference, try to use Editor#apply() instead of Editor#commit(); Images/Animations Mandatory: - When loading large images, they must be processed in a child thread, otherwise the UI will be stuck;
- Close the animation being executed by the current activity in Activity.onPause()/onStop();
recommend: - It is recommended to convert Android images into WebP format to reduce the size of APK;
- Try not to use AnimationDrawable for animation, as it takes up a lot of memory;
- Use ARGB_565 instead of ARGB_888 to reduce memory usage;
- When the Animation execution ends, call View.clearAnimation() to release related resources;
Security Mandatory: - The online package must be obfuscated;
- The encryption and decryption keys/salts are not allowed to be hard-coded into the code to prevent decompilation;
- The certificate must be verified during Https processing, and it is not allowed to directly accept any certificate;
- When using Android's AES/DES/DESede encryption algorithm, do not use the default encryption mode ECB, but explicitly specify the use of CBC/CFB encryption mode;
- It is forbidden to print sensitive information into the log;
- When publishing the application, you must ensure that android:debuggable is false;
- The checkServerTrusted function in the X509TrustManager subclass must be used to verify the legitimacy of the server-side certificate.
- The android:allowbackup attribute must be set to false to prevent adb backup from exporting application data.
|