Abstraction with Java in Android
It is always a good idea to make modular, reusable components. When an app is built from the ground up with this in mind, it becomes more and more scalable, more and more self-extensible. The same components in an app get re-used as newer features are added, saving time and effort. And it becomes easier to make changes later on or identify sources of errors. Refactoring should never be afterwards, but from the beginning.
Having said that, it is not a great idea to have more and more abstractions in mobile apps just for the sake of "abstraction". The reason, of course, is that smart phones are not as powerful as servers or even desktop computers. There is a performance penalty associated with literally every class and virtual method in an Android app. There needs to be a greater balance between "abstraction" and efficiency, and the performance trade-offs become more visible on the medium and low-end devices.
From the official docs:
1. Be careful with code abstractions
2. Avoid dependency injection frameworks
3. Avoid Creating Unnecessary Objects
4. Prefer Static Over Virtual
5. Avoid Internal Getters/Setters
EDIT:
After having recently tried out Dagger, I have to admit that point 2 may be a bit outdated by now. What can I say ... I came to the Dagger party quite late.
You need abstraction whenever you have a class that you do not want to implement all of its methods. Those classes inheriting it will be forced to implement all those methods otherwise you would need to declare the subclasses as abstract as well.
In addition to that you should be aware of interface, methods of interface must not have body and the good thing is that your class can implement as much as interface as you want. Whereas, you can only inherit one abstract class. Interfaces are like contracts. Whichever class implement them need to provide body for all of their methods.
Whether you need abstract or interface or both is really depend on your design and what you want to implement. Although it is a good practice to force those classes that have common methods to implement the same interface ( if you do not know anything about body of each of the methods) or abstract ( if you know what the body of some, all or none of the methods)
Another example would be when you have abstraction or interface if you add something to them all the subclasses or classes that are implementing them need to follow those modifications, it means the could would be more easier to get modified.
Have a look at this, this and this and open/close principle as well.