My name is Ryan Cooke and I work on the Core Experience team at Pinterest. Today I'm here to talk about various Android libraries: their pros, cons, and other stuff. The goal is to efficiently outline as many libraries as possible so that when you run into a problem, you know if it's already been solved? What's a better approach? And also to help you avoid those pitfalls.
Choosing the right library means you can have a better solution that is already built, rather than spending three months rebuilding it. Understanding these libraries is the first step. I hear a lot of people wanting to implement the first library, can't we do this with Async tasks or something native? Google felt that if there was already a solution on the market, they didn't want to build an identical competitor. They've expressed this idea many times in many places. But you should know that you have some other options. General Tips The most valuable thing about libraries is that they are reversible: you add a library to your application and you can remove it later (without any overhead). You can always take it out. Not everything can be like this, but if it can, make it a library, not tied to your application for life. A better approach is to wrap your library. If your own classes call library methods, then this has many benefits, allowing users to call your own API. For example, if the library returns an exception in some cases, you want to intercept it in the API. You only have to modify one file. Having a wrapper makes your library easier to use. If you're working on a library, some people on your team may already be using it, and they know how to call your library without using your wrapper. This style of checking will throw an exception at compile time or in the application when they use the import statement for the connection class, saying "don't use the connection class, use the wrapped API". You also point out not to do this on this specific file. If you don't do this, the wrapper is not very useful because people will eventually bypass it. Also, it's a good idea to unit test third-party libraries. You need these tests, and if you're using a library like Joda-Time, you can use unit tests to understand its weird edge cases. You can even unit test it to understand how it works. You might find that if you don't use the add day method and add one to today, you might end up with February 30th. In the Android world, we have to consider the method count limit (64,000). (I'm talking about the method count of third-party libraries, which will be reduced). There is a website [methodscount](http://methodscount.com) where you can upload your library, the Gradle import statement, and it will tell you how many methods the library has (which is a great thing, especially when you want to use the library). With ProGuard, many libraries will become much smaller. This method will only include the parts of the library that are referenced, but it is difficult to predict what you will use before using the library. Sometimes you can do, "I know I'm only using this method of the library" and see how small it is. Dex function counts will be in your gradle, and you can also do this on your own build system to track the total number of functions in your app. Apk-method-count is a great tool. You can drag your APK and see how many methods it has (63,905 methods, I like to live on the edge of 64,000). Before the MultiDex restrictions came into play, every method you added will still slow down the boot time on those older devices. Although your ship has sailed and is not restricted by MultiDexing, there is still a difference between 100,000 methods and 120,000 methods. Fewer methods is always good. Instagram is famous for extracting what they need from the library instead of using the full library. This is a good practice if you have the energy to do so. Apart from that, I also recommend focusing on popular mature libraries. Every month (especially if you subscribe to Reddit Android Developers), you will hear about the newest and coolest libraries. The more mature the library, the more popular it will be. Working with existing projects, the fewer compatibility issues there will be. Whenever you run into a problem, stackoverflow will have the answer. Also, be careful about special methods. This is something that is not compliant with the Java standard. If you are building a completely different layout, there will most likely be compatibility issues. This is when adopting a library becomes more hesitant. Social Login Facebook is the gold standard for social login (and if you don't like Facebook's implementation, it's only going to get worse). They provide test users and you can use these test accounts to test. No more fake accounts, you should use their test accounts - they work better. I've seen people make this mistake, you can't assume every Facebook user has an email. About 10 to 15% of Facebook users don't have an email. If you're expecting an email, this could be the mysterious reason why 10 to 15% of signups fail. They require the key hash (which is a random sequence of key-value hashes that some code prints out) so you don't have to deal with it, just ignore it. If you want to ask for some other crazy permissions, they've locked those down now. They need to see how you plan to use these permissions first, so if you have this crazy idea and the app isn't built yet, let them know in advance. When logging in and registering, please log the errors you get. This is how we found out that 10 to 15% of registrations failed due to no email. Sometimes logging errors can be the most effective way to find something you don't understand. There are a lot of other login options out there: Twitter, LinkedIn, Google. My mindset is that (especially Twitter, LinkedIn), while they're popular, they're often not worth trying. You'll see less than 2% signup rates unless it's a really good scenario. LinkedIn provides a very challenging API (that wasn't my original wording, but PR told me I should change it). Twitter, they don't provide a lot of information, but you can go to this link and say I need email and basic info and they'll grant people permissions. But overall, these are going to add complexity to your app unless your architecture is really good. Google is a bit more complicated. On Android, a lot of people have Google accounts. It's weird if they don't have a Google account. But you get a lot of functionality from Google Sign In - you get email notifications and other things. Also, the login UI is pretty ugly. It's also a bit slow, so you have to account for loading modal dialogs. networking If you use native libraries, there are two big names: Retrofit, Volley. There is also native HTML URL Connect (generally not recommended). You will often see comparisons between Retrofit and Volley, and you will see that Volley does more than Retrofit (such as image downloading and neat ). This is deceptive. Retrofit was built by Square, and they have a philosophy that their library does as little as possible. They try to have the library strictly solve a specific problem, and enforce good practices when solving that problem. Retrofit is probably their best example. This code (see slide) is an example of how I used Retrofit in an application where I had to create a very clean interface for my API calls. Get more development news like this Volley gives you enough rope to hang yourself. You can use Volley, but it's easy to use it wrong. Retrofit enforces best practices better, and I like that. You'll hear about OkHttp a lot: it's the real behind-the-scenes contributor to the massive network performance gains. It's already native in Android 4.4. Network debugging Think of network debugging, where you have network calls going on and you want to understand what's going on. Stetho Stetho is a great option. It's made by Facebook. It gives you a Chrome developer tools view of your network calls. It also gives you lots of other goodies: you can look into your database and see what's going on there; you can see your layout if you don't know what's going on on the screen. The caveat is that you have to start it every time you run it, otherwise it will shut itself down. While the timings are accurate, it will make your network calls take longer. HttpLoggingInterceptor I personally prefer another simple HttpLoggingInterceptor. You add the interceptor to your network request and it prints it on the log file. You can also see some JSON files. There are a bunch of similar things named logging interceptors. Using Square's standard HTTP logging makes it easier for you to browse, which is very convenient. picture As someone who works at Pinterest, images are important. If you are working on an image-based application, you may want to use a third-party library to handle image caching, image downloading, and image resizing. Picasso,Glide The two most popular image processing libraries are Picasso and Glide. They have very similar interfaces; for most standard users the interfaces are basically the same. Picasso is smaller. The latest version has shrunk from 2,879 lines to 849. However, Glide tends to offer every feature you could want: it can load GIFs, and it can also display video preview images. If you're loading images, Picasso is the better choice. It's more popular: it has more documentation, more support. Both libraries are good. If you have some weird use cases all the time, you can risk using Glide. If your use cases are pretty standard, Picasso is a good choice. hint I already mentioned that I work at Pinterest, and that images are important to my work. I have to throw out a bunch of tips about images. The simplest thing that people aren't doing because the libraries aren't doing it is prefetching in the list. Every time you scroll through the list, you'll see the images loading. If you prefetch the next one or two images, then as you scroll, there will be fewer dropped frames. This will give you a better experience, not having to wait for them to load. If you prefetch too many images, then there will be contention, which is not good either, but prefetching the next one or two images will definitely give you a better experience. Beyond that, none of these libraries will solve your image memory issues. The simplest thing to do is to disable images and then figure out how much memory they consume in your application. Don't use images and figure out the memory savings. Also, freeing images that are not being displayed and resizing images to the dimensions you are displaying can help save memory. Cloudinary is a cool hosting service that allows you to request images at specific resolutions. They try to make this work. However, when you resize the requested images, you have to make sure you don't bust the cache by requesting similar images (so there's a balance here). I'm a fan of bigHeap. One of our apps, with bigHeap, had memory crashes down to 1/4 of what they used to. Google discourages using it because it closes other apps in the background, so switching between apps isn't that great. But at some point, that's not your problem. Garbage collection also takes longer, and you can use it to mask memory issues (which you shouldn't do). In general, bigHeap is good. If you go to the Play Store, and search for largeHeap, you can download a cool app that will show you the apps on your phone that have bigHeap enabled. You'll notice that almost everyone is stuck right now and is using bigHeap. When you think about memory and images, there's a simple formula here. Some people ask, "It's a two-kilobyte JPEG, why is my actual memory usage so high?" The memory used is four times the pixel width times the pixel height. That's the size you'd expect. The standard format for them is ARGB_8888 - it stores the color space in four bytes. If you use RGB_565, you can reduce that to two times. But the colors will be very similar to each other, you'll see less color space, and it can't do alpha, but it will reduce the memory usage by half. You might consider doing this on lower-end devices or lower-version APIs. It's a good way to save on out-of-memory issues. Fresco Facebook released an amazing library that solves the out of memory problem for all versions before API 21. Before API 21, there was a bug in the Android system that allowed you to use other memory outside of the application memory. But it would bring some strange situations: your program would have no problems on old devices, but would perform worse on new devices. Because the way it loads is very different from other libraries, it can implement images like progressive JPEG, where images are loaded gradually in layers. However, they are more deeply coupled in your application. With Glide and Picasso, you can isolate it from your app very well. Without using imageViews, you have to use their type Drawees, and it will also produce more isolated code. If you are targeting lower end devices and you have more memory requirements on older devices, I would recommend using Fresco. Otherwise, I would stick to Picasso and Glide. Memory - Leaks LeakCanary LeakCanary is the go-to tool for memory leaks these days, and it can help you find where you have memory leaks. Leaks aren't all memory problems, but they're worth keeping an eye on. When you add LeakCanary to your application, it automatically starts watching your activities for memory leaks. One misuse I've seen firsthand is that they add LeakCanary to their app, fix one or two leaks, and then think there are no more memory leaks. It only monitors activities. If you use this code here (see slide), you can have it monitor fragments. That doesn't mean you won't have memory leaks elsewhere. Activities and fragments are great places to monitor, but if you don't set observers to the objects, you won't know about all the leaks. In simple terms, it works pretty cool. As a weak reference to whatever object you reference: attach it to something you no longer reference. You put it in the destroy block. Then it does garbage collection. If the object is still there, it's a memory leak, so it knows what object is still there. It gives you the relevant reference to that home fragment scene. I find this hard to understand (*some people think this is simple, some people think it's hard.) Here's an example of a view to illustrate this a little bit (see slide). You start at the bottom (that's what's leaking). I have the home fragment. It's referenced by the pin grid fragment - the pin grid fragment is the parent of this object. Then we have this weird $0 - which explains that this is a runnable object. Inside the object there is a handler that contains a runnable. This code (this is not mine), it's from the Android OS, is the code for the handler. The handler has a runnalbe that's running. I need to make sure the handler no longer holds on to the runnable. In this case, I can clear all the runnables and handlers in the destroy of the view, and that will fix this memory leak. WeakHandler You can also use this random tool called WeakHandler, which makes handler references weak references. If you trigger a garbage collection, they can be collected. The downside is that they can be garbage collected - if you don't want them to be garbage collected, unexpected things may happen. It's worth noting that most of the memory leaks I've encountered are invalid, it's usually a non-missed class that is running and holding onto an external class (this is the most common place). You also need a way to triage bugs for your memory leaks. There's nothing worse than having 70 memory leaks on your phone and you don't know what to do next. It's always a good idea as a team to figure out what to do when we find a memory leak. UI We all know where we've been stuck. Activities are the old standard. Fragments were created because you wanted to reuse them. But we ended up using fragments to make UI displays incredibly complex. Try another approach, view-based architecture, which is more popular. In view-based architecture, you have a frame layout, and instead of dealing with any native Android navigation stuff, you can replace anything inside the frame layout with the views you want. Hopefully, this will solve the complexity of fragments. Fragments have been simplified and updated, they are now more stable, but people still argue that there needs to be a view-based architecture. If we follow this argument, we should look at some libraries (bottom of the graphic, see slide). View-based architecture This architecture was introduced by Mortar and Flow. I believe they were the first libraries to popularize view-based architecture. Flow really follows view-based architecture, but they tend to go together, while Mortar is mainly MVP pattern. When you start implementing view-based architecture, be aware of this quirk. You can also find some weird things, which is that if your application is view-based, you will encounter some random problems, because this library is not view-based. It is activity-based, and if your application is view-based, you have to solve those problems by yourself. Like the standard view-based problems, such as on-activity behavior, permissions, etc. Even the back button and navigation, you have to solve them by yourself, as long as you are view-based. Mortar and Flow accomplish basic navigation functions, but they don't solve all common problems (such as saved states on screen). Conductor was born for these View-based views, and it created a solution: such as saving state, transitions, etc. But you still have compatibility issues. In general, they are very good, they are architecture agnostic, so you can adopt your own MV. Scoop is from Lyft. They use it in production. It's a production-tested solution for a view-based architecture. They don't save state, so Lyft can't save state. Of the main common issues you're going to have with a view-based architecture, this is the biggest one. The toggles are easy to use, but they're also limited, which is a bit disappointing with a view-based architecture where you tend to be able to do pretty good toggles. Overall, if you don't need to save state, Scoop is the most secure product available. Conductor is also very good. I would recommend both libraries. Model View Presentation (MVP) There are several good MVP libraries. The basic idea of MVP is to separate the logic code, so that the view part, the Core Android stuff, will be together, and then the presenter is also separate, and we can unit test the presenter. In theory, we can change the view without completely rewriting the business logic. There are many ways to do MVP. The first library I would recommend is Mosby. Even if you don't use Mosby, they have great tutorials and articles about Android (like what MVP should look like and how it works). The main thing it can do is provide view states to your presenter. Nucleus is similar. Mortar, as part of Mortar and Flow, is an early version of them, and the more they upgrade, the more problems they have. I see companies often build MVP themselves: on create, you will start your presenter; on destroy, you will stop your presenter. There will be a presenter for each activity or anything that your view holds. All of these tradeoffs, while it sounds simple, when you actually implement a use case, there are a lot of edge cases to consider. You have your adapters, your view items. Making sure everyone understands the same thing and finding the places where you can apply MVP is the hardest part. But the end result of this is that you get more unit testable code. You get more stable code. Testing - Performance NimbleDroid I have a bunch of stuff about testing, but I don't want to keep you guys listening to three hours of testing stuff, so let's skip over unit testing with JUnit 4. You have a Gradle build system, you have Espresso. That's standard. Performance testing is a non-standard tool. There are two main approaches to doing performance testing. Google tends to advocate using something like Systrace to look at frame loss, and they have a codebase that gives you code that almost works out of the box (but not very efficiently). This allows you to do automated performance testing to see if frame loss changes. NimbleDroid has a free trial option where you can upload your APK and it will automatically test cold start, and you can also add some key flows in your app. They provide a time series graph and detailed information about what happened in a function. It's free to try (e.g. upload your APK and get the cold start time to see if there are obvious problems). If you want to use it for regression testing, then it's expensive, but it will help you realize, someone made a change and our startup time is slower, or our key flow is slower. If performance is a high priority goal, then it's effective to use it. JSON When people think about performance they tend to think about JSON. There are a lot of JSON libraries out there. My first warning is this: people like to look at JSON libraries purely through the lens of performance. That's a mistake. I took my largest request (150 kilobytes, 30,000 lines, huge JSON file). I parsed it with GSON and Jackson. They were about 20 milliseconds apart, which isn't crazy for that huge file. My first suggestion is: focus more on something that is easy to use, a library with good documentation. You want support. You don't want to spend weeks with developers trying to figure out why something is wrong because stackoverflow doesn't have the answer. Unless you have super high performance requirements, GSON and Jackson are the most used and popular ones, especially on Android, GSON is more popular. Moshi is the library that Square uses. It is very similar to GSON. I have tried to give some opinions on how to use GSON well. You can agree or disagree with these opinions, but you will not be wrong. If you care about JSON parsing performance and want it to be faster, LoganSquare is a great choice. They do the work that other libraries need to do at runtime at compile time. Compared to other libraries, this will save you about 1/4 of the time, or 4 times the performance. If you really care about JSON performance, you shouldn't use JSON. Instead, you can use Flatbuffer. JSON is human readable, Flatbuffer is not, but because of that, it throws away other unnecessary baggage. But Flatbuffer takes almost no time to parse compared to JSON. Facebook made this switch. They found a 10% to 15% increase in startup time, and some improvement in startup time. They also observed more efficient memory usage. But it is harder to use than JSON, so use with caution. Database - SQL For databases, we know that the most common one is SQLite - the standard Android library. SQLBrite is a common simple library on SQLite; it gives you a reactive interface to the database. You can listen to your users. If there are any changes to your users, you will be notified and you can update the user interface immediately. It is a very small library. It is cleanly compatible with SQL. SQLDelight is also from Square. They wrote a lot of libraries. It tries to avoid being a full blown ORM, because ORMs leak too much into your code and tend to force you to do too much, but it still tries to make working with the database easier. It makes the API type-safe and the SQL statements well organized (it tries to make it easier without being too heavy). If you're willing to go for a full ORM, there are a lot of great libraries out there: GreenDAO, OrmLite, DBFlow are some of the more popular ones (there are many other options). They all say they're the best in terms of performance. Each library has some charts that show they're 100x faster than the alternatives. My advice is to prioritize ease of use first, then consider if they're better in terms of performance. Database - NoSQL Realm is the NoSQL approach. It's super fast. Unlike other comparable databases, Realm supports a lot of documentation. This can ultimately save you a ton of development time, regardless of database type. Another NoSQL approach recommended by Google is LevelDB. Key-value pairs, but it can be said that "you can figure out how to do it, but you have to figure out every step yourself." Realm db can help you avoid this. One thing to be particularly careful about with Realm Database is its size (I think our app doubled in size when we initially added it). The reason for this is that it's a native library. They include a full copy of the Realm Database in your app for each chip architecture. To avoid this, you can throw this code into Gradle (see the code in the slides) and generate a separate APK for each architecture. The size will go down as many times as you break it up into versions. This will also give you a lot of memory savings. This is the right thing to do for any C++ code that runs natively, so you'll see the same gains with Crashlytics and some other popular libraries. There's another cool app in the Google Play Store called Native Lib. - It's in the Play Store and it shows you some native libraries so you can see if you're downloading a library for your APK that's not meant for your phone. Doing this will reduce memory usage. If you're just looking for a way to save data on the phone, you might want to store data on the phone. If you're building a one-off app, don't keep data. If you're using Realm to build an app on a phone with very little storage (why would your app need to take up a lot of storage in this case)? But overall, it's a very good database solution. Database - Mobile Platform Another aspect is mobile platforms: a mobile developer’s dream, we no longer need these server guides. We can also build apps ourselves. Parse used to be the best example (maybe rest in peace). The most popular ones in mobile right now are Firebase and Realm. They're both NoSQL models, they have some query challenges, but they're very, very fast to build. They're great for doing synchronized updates. Chat is the most common solution, you send a chat message and suddenly all the phones get the update. Instead of having to build a database, you don't have to have a server, you can use one of these solutions. It makes the build process very fast, get the app done and out to market in no time. And the performance is very good. Realm is offline-first, which is what differentiates it from Firebase. They both work offline, but Firebase does it as an afterthought, while Realm is designed in advance, and Realm supports offline in many ways. Many applications require little to no online behavior. If you are thinking about running an app tracking program, we want to synchronize our running state, and we want all the features to work completely offline, and then work fine online. Realm will stand out. Analytics I like analytics. The Lean Startup saying is, if you can measure it, you can optimize it. If you don't have numbers for something, everything is random and you can only guess how to make it better. I like to have detailed analytics to understand, did this change make things better? Are people using this feature? How can I improve it? Analytics is a great choice for wrapping third-party libraries. If you wrap Analytics well, you should be able to completely replace your analytics service without changing any functional code. You should be able to easily add a new Analytics service so that they work at the same time. It is a good practice to wrap Analytics code. If you're adding analytics, the easiest way to do this is to record your screens, record the screens people go through, and put that in an abstract activity. You'll get a lot of value very quickly. A common mistake I see people make with analytics is adding too much analytics. They'll add a thousand events everywhere, and then no one knows what the analytics mean. They don't test enough, so you're only getting 2/3 of the actual registrations. Be very careful when adding analytics. Try to use simple naming and standards. Don't use analytics to delay easy decisions. If there's an easy decision, then make it. If your analytics tell you "people don't like freeing memory", assume your analytics are wrong. It's easy to draw a wrong conclusion. If you have a big conclusion, the first thing to do is to make sure there's nothing crazy going on with your analytics code. Firebase Firebase used to be a real-time database, and then Google (to confuse us) started a whole bunch of tools called Firebase. Firebase Analytics is the foundation of all Firebase tools. Google realized that iOS and Android developers were solving the same problems. They were using third-party services and paying to solve all of these problems. They thought, we can make it easier to build apps, and the easier it is to build apps, the more money you make. They made a competitor to these tools. To force them to be better, Google tried to make analytics tools the foundation of all tools. The vision of this is that if you get crash reports and see your analytics data, you can sort them by the ROI of the crashes. Your notification system also participates in this, and you can send notifications to the customers who are experiencing the most expensive crashes and tell them about some free discount. We know you are about to buy because you are a high-value crash. It's a cool vision. Not implemented yet, to be honest. Some of it works, some is still a work in progress, and it's not a high priority for Google. But a lot of the tools are good (not as good as competitors'). Analytics is free though. But the events are unlimited. Not a lot of reasons not to use it. Another popular one is Google Analytics. It makes it easy to get a lot of basic information about your users. It's the only one I've seen that offers a cool behavior flow chart where you can see people switching between your events. It's still a bit dated, and its style of recording events is older than all the other analytics tools. It's also free, and Firebase is meant to replace it. A/B Testing I personally think A/B testing is overhyped. It's usually used to slow down learning so you know better, which doesn't apply to simple naming conventions, but of course you can put it in the hands of users and find that out of a sample of 100 users, 55% prefer this choice. That's what you usually see in A/B testing. It’s easy to get buggy. Basically, the number of app versions you have in an A/B test is the number of A/B tests you have in your app plus 2. If you have 3 A/B tests in your app, you have 8 different versions of your app working together. You may not be testing a wide variety of different versions of your app. Sometimes you may find that important decisions are often made difficult because of these issues. My solution is a user analytics service. Mixpanel has a really good A/B testing tool that works with your analytics tool. There are many tools for A/B testing. I would say the most well-known are Optimizely and Apptomize. Optimizely is better for web (their pricing is a bit mysterious). They help you provide different versions and tell you that this one is statistically significantly better than the other. Firebase Remote Config can technically be used to do A/B testing. It's not designed for A/B testing. It's designed to send key-value pairs from a server without requiring developer updates, but it allows us to do A/B testing. You can send two different versions of a key-value pair, and then you can use code to decide what to do. After that, you can pass it to your own analytics interface and figure out how to parse it. In a sense, if you use Firebase Remote Config, you're reinventing the wheel. You can also A/B test your store listings. This is worth trying, especially if you are testing in different countries. It is relatively easy and you can make some gains there. Crash Reporting Like analysis, there are a thousand solutions. I am only going to cover a few. The first thing people see is, especially for Android newbies, is the Play Store. Whenever you encounter a crash, you have the option to send a report. Everyone will ignore it directly, and about 1% of the crashes appear in the Play Store. Sometimes, if you have a very large number of users and some very mysterious crashes, it may be worth checking out because people will comment on what is going on. That is, you have 1% of the crashes; "99% say the app is sucking, crashing." But every once in a while, there are comments like "I rotated the screen on my phone and it crashed" (you seem to be, ah, a developer, I'm grateful) Crashlytics trends are the most popular. This is part of Twitter's Fabric Suite or now Google Fabric Suite. It's free and provides you with a very good, advanced, organized view of crashes. You still need to sort and prioritize yourself. It has some problems and is difficult to search and query. I see people using Bugsnag in combination so that query and search will be a little better. Bugsnag is pretty good, but it's not free. Instabug and Telescope. Telescope is a library. You put it in a bug as a third-party service. The advantage of these libraries is not to monitor crash, but to let you shake your phone to report the problem when the problem occurs. In this way, when designers on your team see the error, they don’t have to submit the bug in JIRA, or explain all the steps to others and then let others report the bug, but you still hope that these bugs that are not crash can be fixed. There is such a tool that all test users, alpha users, and people in your company can tell you that these problems need to be fixed. Push Notifications As a developer, the first reaction is to use GCM or now Firebase Cloud Messaging, which libraries are being reorganized. But these tools are not marketable. The easiest case is that if you already have a good analytics service, Firebase and Mixpanel (and many other libraries) can be used to send notifications. You can send messages based on your activity. It can be designed like this, a person who has never had a purchase, did three searches, and you can send them a notification and suggest they buy something. This is the easiest case. Sometimes you want something deeper. Urban Airship’s push notifications are particularly professional, which is their main direction. They found that “people will only see the first 60 characters of a notification” and we all receive notifications like this, you can only see the first few words. Like, “You won’t believe this…”, it’s truncated. Then you click on it, you are taken to a random screen, and you don’t even know what the push notifications are. Urban Airship is great, they help you think about things like this, give you more nuances and think about how to launch notification services better. Kahuna is very popular, and there are many people who use it, but I would strongly object to it. Their idea is great. By using AI to help you determine which push method is more suitable, whether to send an email, text message or push notification. The AI calculates the best push time and suggests whether to add flowers to the notification. This part has not been implemented yet. But they will make some text changes now. They try to make notifications popular and push the most appropriate notifications as much as possible. The idea is cool, and I hope it can be implemented quickly. But now, in reality, they have a lot of problems, and the user's notifications are sent to the wrong user. The users are merged together and treated as a group. So be careful when using it. Some people use it very well. But I was cheated. Easier There are many great tools to make your development easier. : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : Hugo is a library for Jake Wharton (* When I say Jake Wharton, halfway through Square, they mean the same thing*). It is a lightweight library where you can execute @Debug.Log on top of the method and print out the time it takes, as well as the parameters. It is especially suitable for field performance records. "Do I need to cache this variable? Is it called so much that it gets slower?" You can see, "No, this only took 10 milliseconds, I should have put it on a background thread, or it took less than a millisecond, we don't have to worry about this". It's easy to incorporate your code and get the relevant numbers quickly. Dart & Henson, you have intents; you don't need to use a key-value mapping, it gives you the value you should have. It does annotation mapping to show what the value of intents is. Another way I prefer is the static intents of the activity you are calling. This way you can pass in the parameters you want, which solves the mysterious key-value pair problem. It makes the code tighter, which prevents errors. If you like lambdas, you should use Retrolambda. Note that it produces four methods, not normal anonymous classes. I think using Retrolambda will make the code less readable, which is where you have to make an informed decision. More difficult (early) Let's talk about which libraries make development more difficult, or at the beginning, but in general, these are good tools. RxJava RxJava, for those who haven't heard of it, the idea of this library is that the code in the past starts at point A and ends at point B. But in the Android world, in the mobile development world, it's all different. *You start at point A. Then people click on something, so you have to do something else to respond. Then a notification comes in, and you have to do something again. Then the database request comes in. Reactive strives to enable your code to react to what's going on in your application, helping you organize them better, and it's easy to move. It's hard at first because it has a learning curve. If you're looking at the code, especially for people who haven't been exposed to RxJava, there are many things that are unclear. The easiest one is the network. But if you have a few standard examples that you use these cases and make sure it's the best practice, the situation will be different. When you start having these features, they're very powerful and you can use them anywhere in your application, but when you do that, whenever you hire a new developer, you'll have to teach them how each activity works, which requires careful. Also, it's easy to use it wrong. Even many meetings about RxJava misses some best practices. For example, if you don't unsubscribe to a network call, you'll get called back, which can crash because the screen no longer exists. Using it with caution, overall it's good. Kotlin When I say be careful about using non-built-in languages or say something unusual in new languages, all I want to say is the unusual places you can see. Kotlin generates tidy code. This is good. Making your code easier to read and also making less meaningless things, which is the core thing you need. It also hides the concept of pointers. The biggest drawback is that it will randomly break things, and if anything happens, you will doubt Kotlin. This may be Kotlin's fault, maybe not, but it will take a lot of time for developers to figure out whether it is Kotlin's fault. You need to update the build of Gradle, but this still doesn't work. This may be Kotlin's fault, or it may not be Kotlin's fault, but you have to recheck Kotlin. The same thing is that your Android Studio will crash randomly, or ProGuard will not work because it removes some of the Kotlin classes. These things happen often and are hard to reverse. There are many trade-offs in Kotlin. We use it in our code. There are indeed some problems, and at the same time, people who know Kotlin have faster code reviews. For those who don't know Kotlin, there is a learning curve. It's a trade-off. You have to decide for yourself. camera If you've ever used Camera in Android and you're using a native solution, it's not crazy, you'll find that there's a camera API and a camera two API, and the camera two API isn't better than a camera one API, if you support both new and old devices, you have to use the camera one API unless you're only planning to run properly on very new devices. My first suggestion is, if you have a camera scenario, build an intent. Let someone else's camera app solve your problem if that's not your core scenario. If this is not the case, there is a library called Material Camera, which I fork before. You can add your own look. It helps you create the camera. Solve the problem. But when you first set it up, when you show up in landscape, the picture will be reversed and you have to test it on every phone because they will install the camera in different ways. There are many boundary cases to consider. Material Camera is great, it has solved all these situations. It also supports video. This is video mode. You can change the UI on it and it works great. Again, if Camera is your very core use case, then you should rebuild it, which is just a compromise. Every camera app I use has a cropping feature, and this feature is horrible. I don't know why. You try to cut and suddenly your video gets cut out the middle part. There is a good library called "Android Crop". It provides a very simple new activity to finish the cropping. Global Thinking As Android developers, we need to take into account all developers around the world. If you are doing some development work for developers around the world, there are things you have to consider, such as network emulation: you want to be able to test on a low-quality network. It is harder to do this on Android than iOS. Emulator technology can provide a local emulator AVD, but usually my experience is that if you do any 3G operations on the emulator, no app works fine. Some of my applications sometimes work fine on 3G. The most successful tool I know is the Charles proxy. You can configure it through a certain proxy. It's easy to set up. You can tell the proxy how fast it should be. But there's still a challenge, you need to know how fast the network may be. For example, a 3G network in Brazil is almost a meaningless statement - 3G is different everywhere in Brazil, and very different everywhere. Sometimes you have to try to find some numbers and choose some numbers. There are some resources outside, but selecting parameters is one of the most difficult parts of picking network emulation. There is a tool called Augmented Traffic Control, which comes from Facebook. It allows you to connect to a server or set up a router, and you can set up a configuration file - how fast your internet should be when you connect to a router. If you have non-developers for you, they can still connect to this WiFi network and set the connection level they have. Product managers and testers should generally consider poor quality networks as well. ATC servers are great to use. I believe the new Android O hints that they will have something similar to AutoFitTextView , but now this is just a library, as long as the text is too large for the text box, the text will shrink. If you are translating German and it's a lot of letters are still a little bigger than English, it will shrink it into the box. This is not your first translation solution, but it's better to have them shrink to the size of the text box instead of filling the entire screen and covering everything. It will resize your text (change your text size to fit), which is a good and safe translation. YearClass is another library on Facebook. It will tell you what the latest phones to run your product are. If we say 2015 is the highest year, then you don't have to care about something special on the phones made in 2016. From an analytical perspective, this is the best - for example, this crash is that it happens on Android OS Marshmallow, all phones are low-power phones, and this happens sometimes. Knowing the probability of crash on phones in different years can help you gain a deeper understanding of this crash. The Connection class is a very good tool to understand the quality of user connections (* This is the encapsulated sample class I recommended at the beginning). It classifies networks. Not divided into 4G 3G, because they vary greatly, it is based on bandwidth, divided into excellent, good, moderate or poor, or unknown. It is classified by sampling download speed. Then it moves the average. The value of doing this is, for example, you are an image website that displays many images, and you may want to reduce image quality on a poor network, or do other things. Knowing bandwidth in advance can do many things. The biggest warning is that its sampling may be inappropriate. What you can do is to get them to start sampling and stop sampling. For example, when I open the application, start sampling, stop when I close the application. What they do is to see the amount of data you download and refresh it every second. If the user opens your application and does nothing, they will think your network is terrible slow. What we do is that you can start it in the middle of a network call or an image call, which works great. Besides that, this library knows your network bandwidth very accurately. About the content This content has been published here with the express permission of the author. |
<<: The three-way handshake and four-way wave process of TCP protocol
>>: You can also play like this: Check out Siri's 12 new features in iOS 11
Editor's note: During the special period of e...
[[123651]] As the passion of smart hardware entre...
If the goal is to acquire customers, then you nee...
Xiaohongshu has undergone a lot of changes during...
The latest traffic rankings of the 50 most popula...
For B-side products, holding events to acquire cu...
In early November, Lenovo just made minor adjustm...
Alcohol consumption levels currently considered s...
π is a very important number in mathematics. I be...
At present, the connection between Beidou and for...
In fact, websites that are not indexed are genera...
Poets can't help but feel sad when facing the...
1. Introduction Hello everyone, I am Anguo! Befor...
30 relationship management lessons, teach you not...
Last December, Google spun off its self-driving c...