This is a pretty open ended question, but let me take a shot at describing how I see the intra/inter application communication working best.
One of the key aspects of Android messaging is the concept of all application components being loosely bound. Because all applications run in a separate process, and one 'app' may actually consist of several applications (responsible for providing different Activities or Services), the messaging techniques are all based around the idea of marshaling messages across process boundaries.
Intents
The preferred technique for messaging, always try to use an Intent whenever possible. It is the most 'native' way to transfer messages within Android.
Advantages
Using Intents for messaging maintains the loose binding of application components, letting you transfer messages seamlessly between several applications. Intents are used heavily within the core system to start Activities and Services, and to broadcast and receive system events.
Using extras Bundles you can include key/value pairs of primitives as payload data within Intents to easily pass information from one application component to another - even if those components are running in different processes.
Disadvantages
Because Intents are designed to go between processes, the extras payload only supports primitive types. If you need to send an object using an Intent you'll need to deconstruct it into primitives at one end and reconstruct it at the other.
Application Class
If you only want to communicate within a single application running in a single process this is a handy solution.
Advantages
By extending the Application
class (and implementing it as a Singleton) you get an object that will exist whenever any of your application components exist, providing a centralized place to store and transfer complex object data between application components.
Disadvantages
This technique limits your messaging to components within a single application.
Service Binding, IPC, and AIDL
Binding to a service lets you access its methods and exchange objects with it. AIDL is a way of defining how to serialize an object into OS primitives so that it can be marshalled across process boundaries if the Service you're binding to is running in a separate application.
Advantages
When you bind to a Service you have access to it as though it was an object within the calling class. That means you can execute methods on the Service and exchange rich objects with it.
Note that if you're binding to a Service in a different application process you'll need to create the AIDL definitions that tell Android how to seralize / deserialize any objects you want to pass between applications.
Disadvantages
Creating the AIDL classes for IPC is a bit of extra work, and binding creates additional dependencies between Services and Activities which can make it harder for the kernel to clean up resources when other applications are being starved.
Marshelling messages across process boundaries is expensive though. So if you're not executing methods on a Service, using binding and IPC is probably overkill - see if you can achieve the same thing using Intents.
Sockets
If you're resorting to sockets to communicate within or between applications running on a single device, it's either because there's no other way or you've missed a trick somewhere. If your messages are leaving the device then sockets are a good, fast, alternative. If you're staying on the device chances are Intents or IPC is going to be a better option.