I am new in android app development and while studying about the basic android components I got confused between intents and content provider as both are being used to send data from one application/component to another application/component . In case of intents we can send data using bundle or extras so why do we use content providers. Can someone please explain me this with a example . Also can we access database in android only using content provider and is this the sole reason why we use content providers ?
both are being used to send data from one application/component to another application/component
Not really.
There are four components in Android:
Activity
Service
BroadcastReceiver
ContentProvider
An Intent is none of those. An Intent is involved when we start an activity, start or bind to a service, or send a broadcast. However, comparing an Intent to a ContentProvider is akin to comparing a shovel with a boot, arguing that both can be used to carry dirt. While true, usually a boot is involved in carrying dirt, but the actual means of carrying dirt is handled by something else, such as a wheelbarrow.
In case of intents we can send data using bundle or extras so why do we use content providers.
We often use different tools for different circumstances. For example, you will find it rather difficult to carry water in a fishing net.
Each of the four components has a different role, particularly in relationship to inter-process communication (IPC):
An Activity drives the bulk of our user interface, including starting up activities from other apps (or having one of our activities be started by other apps)
A Service exists for longer-running operations that are logically decoupled from the user interface, including working with services that are implemented by other apps (or having other apps work with services that you publish)
A BroadcastReceiver is a publish/subscribe messaging system, to allow you to send messages to arbitrary subscribers, or to subscribe to messages from arbitrary senders, across process boundaries
A ContentProvider is for bulk data transfer, whether in the form of a database-style structure (rows and columns) or in the form of a stream, particularly for working with other apps
Also can we access database in android only using content provider
No. After all, if that were true, it would be impossible to access a database. A ContentProvider does not appear by magic. It has to be written by a programmer. If a ContentProvider could only access a database by means of a ContentProvider, we would have a problem.
is this the sole reason why we use content providers ?
No. In addition to offering a database-style API, a ContentProvider can also publish a stream. This is important for getting arbitrary data between apps, such as an email client making a PDF attachment available to a PDF viewer.
Intents are a messaging architecture for sending /receiving transactional commands and data. Content providers are an abstract interface to stored data for create,update, delete and sync operations.
Related
I am working on sharing road traffic information between Android applications, and wondering what is a good transport mechanism.
There are two classes of applications: Publishers post traffic messages they have obtained from various sources (say, an Internet service or a TMC receiver device) and converted to a standard format. Subscribers listen for messages and work with them (e.g. displaying them in a list or guiding drivers around congestions). The system is intended to be decentral: there will be multiple publishers, multiple subscribers and users can mix and match them as they like.
Messages are identified by a unique ID, which remains stable over their entire life cycle. They have an expiration time, after which they are considered invalid. Until then, they can be updated at any time. An update can also cancel the message (replacing it with a tombstone until it expires), or extend its expiration time.
Subscribers get new messages as they arrive. (Filtering may happen in a later phase.) They also need a way to retrieve all currently cached messages from all publishers.
A message is around 1 kByte in size. A publisher can easily hold several hundred active messages at any given time.
In terms of security, the messages are generally public information. The only sensitive information is geodata, as it may allow for conclusions on the location of the device or where its user intends to travel. The precision of such data is low, anywhere from city to country level. Therefore I don’t see a need to hide this information from any app, as long as it has location permission.
Now I am wondering what a good transport mechanism would be:
Option 1: Broadcast intents
Initially I have been working with broadcast intents: whenever a publisher has any new messages, it sends an implicit broadcast with the messages in the extras. Subscribers can register a broadcast receiver at run time to receive messages. They also have the option to send a poll broadcast (an explicit broadcast, with the corresponding broadcast receiver declared in the publisher’s Manifest). Publishers will then respond with a feed of all currently cached messages. To address security concerns, any app sending a broadcast with geodata requires that the receiver hold one of the location permissions.
There is an issue with large feeds, as the Android request broker supports a maximum of 1 MByte for all concurrent transactions (so the maximum amount of data in a feed can be even less if things are busy). I am currently working around that by breaking down feeds into chunks of 100 messages or less.
An advantage of this system is that all central infrastructure is provided by the OS. Having one publisher and one subscriber app installed is sufficient.
Option 2: Content Providers
Some people have pointed out that broadcast intents are not the best way to go, and have suggested I implement a content provider, a territory into which I have not ventured so far. Looking at the documentation, it is not clear if there is a way to have multiple backends (each backend being a separate app) implement functionally identical content providers and advertise them as such. Since content providers support both read and write operations, I could set up one central component as the content provider, and have both publishers and subscribers connect to it. However, that would require providing a central component in order to work, which I would rather avoid.
Questions:
Is there a way to implement the above multi-publisher, multi-subscriber model with content providers, and without having to supply a central component not already provided by the OS?
Specifically, can a single content provider have multiple backends? Alternatively, can multiple, functionally identical content providers advertise themselves as a group?
How would I implement the above using content providers?
What are advantages and drawbacks of broadcast intents or content providers that I may have missed?
Is there a way to implement the above multi-publisher, multi-subscriber model with content providers
Keep the broadcasts. Replace the payload.
Publishers would implement a ContentProvider that serve up the current roster of messages. You can think of a ContentProvider as being a quirky sort of REST-style Web service, where Uri values get mapped to responses by the provider.
Publishers would then send broadcasts as they are today, but perhaps with only two extras:
One that identifies the protocol version that the broadcast is using, since you have lots of independently-updated parties. Rceivers need to know how to interpret the broadcast, as you might change the rules over time.
One that contains a Uri pointing to the publisher's ContentProvider.
If there are other extras that you are using today that you know will remain small, and you want to still put those in the broadcast, that's cool. Just keep the indeterminate-sized ones out of the broadcast.
Receivers would then:
Look at the protocol version extra and branch to the code to handle that version (today, just one branch, but, hey, future-proofing)
Use that Uri and a ContentResolver to get the messages (and other stuff if needed) from the publisher
You might consider developing this communications infrastructure as an SDK. Even if you are the only one developing apps, you'll want to avoid duplicating all this logic across the apps. And, if third parties will develop apps, you're better off giving them an SDK to work from, rather than forcing them "roll their own".
anyone knows why the Android developers team have implemented the Content-Resolver as a middleman to get data from a Content-Provider. Why not asking data directly from the Content-Provider ?
It means that the Content-Resolver has a special job, what is it ?
Why not asking data directly from the Content-Provider ?
A content: Uri may refer to a ContentProvider in another app. You cannot work with that ContentProvider directly; inter-process communication (IPC) is required. Hence, the API was designed around that IPC model.
ContentResolvers are designed to create an interface for applications to securely access and/or modify data in other applications which run in separate processes. It creates a common contract for content consumer registrations, requests, updates, binding, etc. to be passed between a particular ContentProvider and the content consumer that runs in another process.
Creating a proper and durable interface for transferring data across processes in Android is complex. If you had to create your own IPC client then it would be time consuming and you would likely overlook important aspects of the implementation. A "direct" connection to the ContentProvider is what a ContentResolver provides, but with a lot of the complexity already addressed. It is a convenience to already have that created and well-defined on both sides.
This is a little like a postal delivery system. If you use the postal service, you put an address on a piece of mail and the postal service (ContentResolver) finds the appropriate place to deliver the message (ContentProvider), and then returns any messages to you in response to your message. Your postal service will also handle new address registrations, tell you if the address is invalid, if the package is too big, if the recipient at the destination address is not accepting messages right now, waits if the message queue is full, handles situations where the vehicle carrying the message breaks down, etc. And in the case of ContentResolvers there are a few other things.
You could handle all of that yourself but when you think about real-life message delivery, it's not simple and much easier to use something built by someone else. Likewise for interprocess communication (IPC) in Android. It's not a perfect analogy but hopefully that helps clarify the need for a ContentResolver.
I would like to re-design my application into components, so it is more modular and easier to re-use in the future, but I've never really designed applications, so I don't really know how I should do this.
Here is a brief description of the application:
The purpose of the Application is to allow the User to create "Events" that are going to be stored locally on the Device and sent over the network.
The User can interact with the application through 2 Activities: A "NewEventActivity" that allows him to create the new Events and a "LogbookActivity" that allows him to browse previously created Events.
The local storage should be handled by a SQLite Database
The Event should be sent in a specific Binary format.
Other applications should be able to Use the Sending component to Format and send other type of messages in the same format.
This drawing represents how I was thinking of organizing the components. Boxes represent components, and arrows represent interactions without those components.
Here are my questions:
Does this model look OK? Can you see something that could be improved?
Should my SQLiteHelper be a ContentProvider or a ContentResolver?
Should I create one BroadcastReceiver class per type of Signal, or should I create one big BroadcastReceiver that handles all the kind of Signals my application can handle?
Thank you!
A few suggestions to simplify the design:
If EventWriter and EventReader only interact with the activity due to direct user interaction, they don't need to be BroadcastReceivers. In fact, they could just be methods in the activities.
Depending on how you choose when to send Events, you could also refactor MessageFormatter and Sender into an IntentService which will periodically poll the content provider and choose which pieces of data to send. You can schedule the IntentService via alarms.
Should my SQLiteHelper be a
ContentProvider or a ContentResolver?
It should implement ContentProvider (since it provides access to data).
Should I create one BroadcastReceiver
class per type of Signal, or should I
create one big BroadcastReceiver that
handles all the kind of Signals my
application can handle?
I lean towards one receiver per signal type, but that's really just a preference.
I am developing an app and get confused about the idea of Service and Content Provider in Android. In practice, what will be the difference between them?
Content Provider
is a facade and it defines a way to share data among applications. You many attach a local database to your app or create Content Provider mapped to a universal database so that all the application on the same device can share it.
Service
is long running processes that need to be decoupled from main activity. It has local and remote service. local service is like the local database, and remote service is like Content Provider sharing the database info.
What My App is doing?
downloads info. from multiple internet resource in the background (I suppose this will be Service) and store the info. into database, and multiple applications will need to retrieve the data, format them and output them to user (I guess it will be a Content Provider).
What will be the fine line between Service and Content Provider? Newbie in Android, and any suggestion is welcome.
Lily
Your understanding of the difference between a Service and ContentProvider is pretty spot on. The key thing is that a ContentProvider simply acts as a conduit for retrieving data, while a Service is meant to do something in the background without user interaction.
I've been working with Android for well over a year now, but I still have trouble determining when different types of messaging/communication between processes/threads should be used. I'm mainly talking about broadcasting Intents, using AIDL for services, using Handlers to send messages and socket communication.
Many of these tools can be used to accomplish similar tasks, but which is better suited to particular situations?
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.
It all depends on the use case and kind of your application. If the application is running all the time better to go with AIDL approach as it is most secure way to communicate. If application need not run all the time, then you can go with either broadcast intent or pending intent approach to communicate between applications.
My 2 cents
I have not used local sockets.
Seems like overkill since you have to
generate and parse the data.
Intents are for either things that
other apps might want to do (launch
me in a compose window or to pick
something out)
AIDL/Parcels/Handlers for having a
GUI talk to a headless process that
is running constantly. Depending on
the app a lot of the actual data
transfer might happen using a content
provider but I tend to have some data
that needs to be transferred outside
of that channel.
This is a good article I found helpful in trying to find a substitute for Cocoa's NSUserDefaults class:
http://developer.android.com/guide/appendix/faq/framework.html