I always wanted to write an article summarizing Android development experience, but I guess I was not up to a certain level at that time, so I couldn’t keep up with my ideas and didn’t have enough money to write. Recently, the train of thought is more clear, so start again to operate the keyboard code word. First declare ha, I am not a dachang program ape. Before graduation last year, I have been engaged in my favorite coding business in the current entrepreneurial team. The following summary is based on my current technical level and cognition to write, if you have different views welcome to leave comments to communicate with each other.

1. Understand abstractions and encapsulate change

The vast majority of development on the Android platform is in Java, and dealing with Java, an object-oriented language, involves the concepts of abstraction and encapsulation. Some of the developers I’ve talked to have stuck with these concepts by writing an abstract class, interface, or method (or abstract method). As to why, I’m not sure whether they can’t express it or whether they don’t understand it. I’m not going to talk too much, but I’m going to give you an example of what I think abstraction is.

// Use an Intent to pass data between activities. DestActivity Intent Intent = new Intent(this, destactivity.class); intent.putExtra("param", "clock"); SrcActivity.startActivity(intent); String param = getIntent. GetStringExtra ("param"); //DestActivity gets the data passed from SrcActivity. DestActivity Intent Intent = new Intent(this, destactivity.class); intent.putExtra(DestActivity.EXTRA_PARAM, "clock"); SrcActivity.startActivity(intent); Public final static String EXTRA_PARAM = "param"; String param = getIntent.getStringExtra(EXTRA_PARAM);Copy the code

The problem is that if SrcActivity or DestActivity mistype “param” as “para” or “paran”, the passed data will not be received successfully. The EXTRA_PARAM variable is “param”, “para”, or “paran”. This is a kind of abstract encapsulation of possible changes, which brings the benefit of reducing the probability of hand shaking error, and at the same time convenient for us to modify.

Based on abstraction and encapsulation, many of the Java apis themselves are designed this way, such as many sorting methods in Collections:




These methods are all sorting based on the abstract List interface of the List, and the sorting method itself does not care what data structure implements the List (ArrayList or LinkedList). Because there may be tens of thousands of concrete implementations of lists, if each class of List has to write a set of sorting methods, I would probably cry blind.

Summary: To abstract the parts prone to change is a kind of encapsulation of change.

2. Pick your “wheels”

The development of a project, we can not start from 0, if it is true, it will also cry blind. Therefore, it is important to be good at borrowing already made “wheels”, such as:

Network access framework: OKHTTP, Retrofit, Android-Async-HTTP, Volley Image loading framework: Android-universal-image-Loader, Glide, Fresco, Picasso Caching framework: DiskLruCache, Robospice Json parsing framework: Gson, Fastjson, Jackson EventBus: EventBus, Otto ORM framework: GreenDAO, Litepal and a variety of other open source custom controls, animation, etc. In addition to the open source framework mentioned above, it also includes some SDK data statistics that are not open source: Umeng statistics, Baidu statistics… Tencent Bugly, Bugtags… Cloud storage: seven cows… Even if the communication: ring letter, rong Yun, Ali Baichuan… Push: Xiaomi push, Tencent push, Baidu push… Security reinforcement: 360 reinforcement treasure, love encryption…

In general, I choose whether to introduce open source frameworks based on the following factors:

  • With the help of search engines, if there is a large wave of information on the Internet, it shows that there are many people using the problem to find a solution; Of course, if there are generally bad reviews, you can Pass them
  • Look at the framework’s authors or teams, such as JakeWharton, the Facebook team, etc. The framework produced by Dashen and large companies is of relatively high quality, which can ensure subsequent maintenance and bug repair and is not easy to rot.
  • Focus on open source project commit density, issue submission, reply, closing number, watch number, start number, fork number, etc. Projects that rarely submit code, issue, reply or fix are best passed;

For the choice of not open source SDK, the following points are mainly considered:

  • Use search engines to identify word of mouth;
  • The front page of many third-party SDKS will tell you how many apps are already connected to the SDK. If you see a lot of well-known apps on the SDK, consider giving it a try. For example, umENG official website:




  • Check out the SDK usage documentation, their developer community, and contact customer service. With a good SDK, the usage documentation will guide you in detail. If something goes wrong, go to the developer community and ask questions, and their developers will answer them. If you have no choice but to contact customer service, if the attitude of customer service makes you unhappy, then you can consider changing to another SDK.

Summary: Choose the right “wheel”, get twice the result with half the effort

3. Abstraction relies on third-party frameworks

Why rely abstractly on third-party frameworks? This goes hand in hand with point 1, which is to reduce our dependence on a particular framework so that we can quickly switch to a different framework. This may sound abstract to you, but let me give you an example of loading an image.

Suppose you are currently introducing a framework for loading images for your project, Android-universal-image-loader. The easiest way to do this is to add the corresponding dependencies and write the following code snippets wherever images are loaded.

ImageLoader imageLoader = ImageLoader.getInstance(); // Get singleton instance
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view 
//  which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView);
// Load image, decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() {
    @Override
    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
        // Do whatever you want with Bitmap
    }
});Copy the code

This is the simplest, but also the most problematic. If I wrote this in dozens or hundreds of places, and ONE day I heard that Facebook had Fresco and wanted to replace the Android-universal-image-Loader, you would find that you had to change dozens or hundreds of places of code, and it would be a lot of work. It is also prone to error. The reason for this is that there is a strong coupling between the project and the frame that loads the image, and the project itself should not actually know which frame I am using to load the image.

The correct way is to make an abstract encapsulation of the framework to cope with future changes. I will directly give an example of encapsulation in my open source project AndroidAlbum.




The general code is as follows:

// declare the ImageLoaderWrapper interface Public Interface ImageLoaderWrapper {/** * display image ** @param imageView Display image imageView * @param imageFile Public void displayImage(ImageView ImageView, File imageFile, DisplayOption); @param imageUrl URL of the image resource * @param option Display parameter Settings */ public void displayImage(ImageView imageView, String imageUrl, DisplayOption option); Public static class DisplayOption {/** * loadingResId; /** * load failed resource id */ public int loadErrorResId; }} / / 2, UniversalAndroidImageLoader encapsulated into interface inheritance ImageLoaderWrapper UniversalAndroidImageLoader, / / code here a little longer, ImageLoaderFactory public class ImageLoaderFactory { private static ImageLoaderWrapper sInstance; Private ImageLoaderFactory() {} @return */ public static ImageLoaderWrapper getLoader() {if (sInstance == null) { synchronized (ImageLoaderFactory.class) { if (sInstance == null) { sInstance = new UniversalAndroidImageLoader(); //<link>https://github.com/nostra13/Android-Universal-Image-Loader</link> } } } return sInstance; }} / / 4, where all need to load images for the following calls ImageLoaderWrapper loaderWrapper = ImageLoaderFactory. GetLoader (); ImageLoaderWrapper.DisplayOption displayOption = new ImageLoaderWrapper.DisplayOption(); displayOption.loadingResId = R.mipmap.img_default; displayOption.loadErrorResId = R.mipmap.img_error; loaderWrapper.displayImage(imagview, url, displayOption);Copy the code

This way, the cost of switching frameworks is small, which is the benefit of not relying directly on the framework. Of course, the above is just my relatively simple encapsulation, you can also do more detailed processing.

Summary: Reserve changes that are not strongly coupled to third-party frameworks

4. From MVC to MVP

To be honest, I’ve always been developing in the MVC model before I came into contact with MVP architecture. As the project gets bigger and bigger, the code in the Activity or Fragment gets bigger and bigger. When you read it, you feel like vomiting, and when you modify it, you feel like shit. Leaving aside the various other architectures, just compare MVC and MVP.




  • View: XML file for the layout
  • Controller: Activity, Fragment, Dialog, etc
  • Model: Relevant business operations that process data (e.g. operations on databases, operations on networks, etc.) should be in the Model layer

As you can see, if the View layer only contains XML files, there is not much we can do with the View layer in our Android project. The most we can do is reuse the layout with include. Activities, on the other hand, are a bit of a weirdo. Although they belong to the Controller layer, they actually do the View layer’s work (View initialization and related operations are in the Activity). This structure, which is both View and Controller, violates the principle of single responsibility and leads to the bloat problem mentioned above for activities.




  • View: Activity, Fragment, Dialog, Adapter, etc. This layer does not contain any business logic
  • Presenter: An intermediary. A View and Model are not connected
  • Model: Relevant business operations that process data (e.g. operations on databases, operations on networks, etc.) should be in the Model layer

MVPS have a clearer hierarchy than MVCS, with no one person doing two jobs (some unit test kids will find it easier to write unit test cases). Here you can see that the View and Model are not aware of each other’s existence, so it is better to deal with changes. Most of the time, the View layer changes, while the Model layer changes relatively little. After following the MVP structure, the code changes are less painful. There is also something to note here, because most of the interaction is concentrated in the Presenter layer, so the granularity of Presenter needs to be well understood. An Activity can hold multiple Views and presenters. This avoids the problem of large views and presenters.

I recommend two good MVP architecture projects to everyone. If you still don’t understand the children’s shoes, you can experience its design ideas by yourself:

Github.com/pedrovgs/Ef… Github.com/antoniolg/a…

Summary: Go practice understanding MVP

5. Archive code

Organize common utility classes or business process code into your own codebase (if you don’t already have your own codebase). Such as encryption and decryption, taking photos, cutting pictures, access to the system of all pictures of the path, custom control or animation and some of his other commonly used tools, etc.. Archiving is a great way to improve your development efficiency and can be used as you come across new projects. If you want to better maintain your own codebase, you can open source your private codebase with detailed documentation without compromising company secrets. This will attract more developers to use the code and get bug feedback so they can start fixing and improving the stability of the repository code.

Summary: Archive code properly and, if possible, maintain it open source

6. Performance optimization

When it comes to performance optimization, the general focus is on the same areas: memory, CPU, power consumption, lag, rendering, process survival, etc. There are already many answers on the web for the performance optimization ideas and analysis methods in these areas, which will not be described here. I would just like to say the following:

  • Don’t do performance optimization too early, the app should be usable first and then usable. Spending a lot of time optimizing when the requirements are not complete is putting the cart before the horse;
  • Optimization is based on actual data and tested by test tools (e.g. Netease’s Emmagee, Tencent’s GT and APT, IFLYTEK’s iTest, Google’s Battery Historian). After all, the boss asks you how much electricity consumption is reduced than before, and you can’t answer that it is reduced, right??
  • Any means not to reduce performance loss to do live, are playing rogue.

Summary: Reasonable optimization, data quantization

7. Practice new technology

Rxjava, React Native, Kotlin… When it starts, there are a lot of developers around who will jump on the bandwagon. The spirit of learning new technology is very encouraging, but it is not appropriate to introduce new technology into a business project without a period of observation. For teams in large companies, there are teams or programs that study these emerging technologies to determine whether or not to introduce them into their product line development. But does being a small company mean you don’t have the opportunity to experiment with new technologies? Is not! I have the following suggestions:

  • Use a search engine. Look at the technology pit more or less, word of mouth is good but pit more, it shows that the current technology is not mature, you can wait patiently for updates;
  • Consider the cost of learning. If the learning cost is too high and it is not easy to recruit developers who understand this aspect, it is recommended not to introduce this technology;
  • Highly copy a project and open source it. If you want to introduce React Native for commercial development, it’s best to implement an application and then open source it. Developers who are interested in RN will run your code and give you feedback on bugs, which will help you learn about the pitfalls of new technologies, find solutions, and decide whether or not to introduce them.
  • Lower barriers to entry. Try to document the process of practicing new technologies in detail, which will help lower the threshold for other colleagues in the project team to enter new technologies. If possible, I will also learn to open source documents, get more feedback from developers on this document, and correct some errors in the document.
  • Combine with actual business. All new technology needs to be introduced in accordance with the current business needs. I have heard of some programmers who want to introduce new technology because they think it is cool. I haven’t done it at all. Sometimes good speechless, feeling in will use some technology just like in show skills;

Summary: empty talk spoils a country, but solid work prospers it

8.UML

I am also on the way to learn and experience the benefits of UML, a tool for taming code and understanding project structure. Regardless of the size of the project, with it, you can better clarify some context structure. Working with old, bulky project code, or interested in reading some open-source project code, is a must for developers at home.

Summary: To do a good job, you must sharpen your tools

9. Build your own “Wheel”

As mentioned in previous 2, the project cannot start from zero, and many third-party frameworks need to be introduced. This does not contradict 2, but suggests that developers who want to improve their technical skills can code a framework in their spare time. If you have insights into web access and image loading, put those ideas into concrete code. You may find that you think a lot more and get a lot more out of it when you do it. (Especially recommended for those who have seen a lot of open source code and have not yet done it themselves)

Summary: Don’t stop at API calls

10. Expand the tech sphere

When you have time and can afford it, you might as well attend some technical seminars that interest you. Many of them will have a big bull on stage, listen to other people’s solutions, broaden their own way of thinking about problems, and participate in some valuable online activities. I have a lot of developer friends that I met when I was at the event, and sometimes when I had a technical problem, I would talk to each other about how to solve it. Pretty great!

Summary: Broaden technical horizon

11. Write a blog summary

This may not be much to say, you read the title to understand. Its biggest benefits are:

  • Systematically document your own solutions;
  • To facilitate their own review in the future;
  • There will also be reader comments and feedbacks to promote technical exchanges;
  • Improve your written communication skills;

Summary: summarize carefully and improve continuously

12. Find a date

Don’t spend too much time in front of your computer. Find someone to boost your happiness. It is said that high happiness of the program ape, coding efficiency is high, the probability of bugs is small…

Bottom line: Be an object-oriented programmer

I have thought of these. If I want to write something else, I will write a new article. Flocky wrote so much, the most key or their own to implement, do not hear too much truth, but still bad this life !!!!