I read about Interprocess Communication (IPC) and creating send data from one component to another component.
What I knew is that IPC defines the communication channel between the different components.
The channel will have programming interfaces for the components to send data through. Ways to create an interface are such as AIDL, Binder, and Messenger.
After creating the interface, data to be sent over it must be Parcel.
So the summary steps are as follows:
1. Create a programming interface.
2. Bind the interface to an application component.
3. Components sending data to that component must convert data into Parcel.
But suddenly found what is called Intent that can send data from one component to another without this overhead.
I need explanation about how Intent can send data without having an interface to be created?
Is intent internally have an interface?
What is the relation between intent and IPC, bound service, and interface?
Wow you have a lot of confusion here. Let's see if I can clear things up.
1)IPC does not send data from one component to another (it can, but its an inefficient way to do that). IPC sends data from one process to another. An Android app is generally one process, although it doesn't have to be (services are sometimes placed into another process by the developer). The reason this is an important difference is that processes cannot share memory, so special methods like IPC are needed to send any data between them.
2)Data sent between components do not have to be a Parcel. That's one way, and its the way Android uses when sending startup parameters around. But it's not necessary.
3)Using a Binder to talk to a service is only possible if the two are in the same process. Its a method to totally avoid using IPC.
4)AIDL is a wrapper around an IPC method. AIDL uses IPC, it just tries to make it look like normal function calls to the client.
5)An Intent object is an abstraction for all the data needed to start a service or activity in Android. It will include parameters, which may or may not be in Parcels. It may or may not use IPC to send those parameters (if the target Activitiy or Service is in another APK it will. If it isn't it may not).
I think the problem here is you don't really understand what a process is, what an Android component is, and how processes actually communicate. I suggest doing some studying up on that.
Related
I've been trying to use Java Observer and Observable in a multi-user XPages application, but I'm running into identity conflicts. I'll explain.
Say A and B have the same view on their screens, a list of documents with Readers fields. We want to keep those screens synchronised as much as possible. If A changes something, B might be receiving updates, depending on his rights and roles. We achieved to do this using WebSockets, but I want to see if there's a better way, i.e. without send a message to the client telling it to re-fetch the screen.
Using the Observer mechanism, B can observe changes and push the changed screen to the user. The tricky part here is that if I call notifyObservers as user A, and I walk through all the observables, A will be executing the Observer.update() method, and not B.
I also thought of using a Timer-like solution, but I'd probably end up with the same conflicts.
Question: is there any way I can properly switch sessions in XPages? Or should I wait for Publish/Subscribe in the XPages server?
I can see 3 possible actions:
Use the SudoUtils from XPages-Scaffolding to run code on behalf
Use DominoJNA to access the data with a different user id (not for the faint of heart)
Just notify the client using the websocket - preferably via webworker. It then would make a fetch (the artist formerly known as Ajax) to see if changes are needed in the client UI. While this has the disadvantage of incurring a network interlude (websocket + fetch) it has the advantage that you don't need to mess with impersonisation which always carries the risk of something going wrong.
For the first two I would want to pack them into an OSGi bundle to be independent from the particularities of Java loaded from an NSF
Old answer
Your observer needs to be in an application context, so you can update any Observer. The observer then would use a websocket to the client to tell it: update this ONE record.
The tricky part, needs planning: have individual websocket addresses, so you notify only the ones that need notification
I'm trying to make a design based on the Uncle Bob's Clean Architecture in Android.
The problem:
I'd like to solve is how to make the changes generated in one repository to be reflected in other parts of the app, like other repositories or Views.
The example
I've designed a VERY simplified example for this example. Please notice that boundary interfaces has been removed to keep the diagrams small.
Imagine an app that shows a list of videos (with title, thumnail and like count), clicking a video you can see the detail (there you can like/dislike the video).
Additionally the app has an statistics system that counts the number of videos the user liked or disliked.
The main classes for this app could be:
For the Videos part/module:
For the Stats part/module:
The target
Now imagine you check your stats, then navigate the list of videos, open the detail of one, and click the like button.
After the like is sent to the server, there are several elements of the apps that should be aware of the change:
Of course the detail view, should be updated with the changes (this can be made through callbacks so no problem)
The list of videos should update the "likes" count for the given video
The StatsRepository may want to update/invalidate the caches after voting a new video
If the list of stats is visible (imagine a split screen) it should also show the updated stats (or at least receive the event for re-query the data)
The Question
What are the common patterns to solve this kind of communication?
Please make your answer as complete as you can, specifying where the events are generated, how they get propagated though the app, etc.
Note: Bounties will be given to complete answers
Publish / Subscribe
Typically, for n:m communication (n senders may send a message to m receivers, while all senders and receivers do not know each other) you'll use a publish/subscribe pattern.
There are lots of libraries implementing such a communication style, for Java there is for example an EventBus implementation in the Guava library.
For in-app communication these libraries are typically called EventBus or EventManager and send/receive events.
Domain Events
Suppose you now created an event VideoRatedEvent, which signals that a user has either liked or disliked a video.
These type of events are referred to as Domain Events. The event class is a simple POJO and might look like this:
class VideoRatedEvent {
/** The video that was rated */
public Video video;
/** The user that triggered this event */
public User user;
/** True if the user liked the video, false if the user disliked the video */
public boolean liked;
}
Dispatch events
Now each time your users like or dislike a video, you'll need to dispatch a VideoRatedEvent.
With Guava, you'll simply pass an instantiated event object to object to EventBus.post(myVideoRatedEvent).
Ideally the events are generated in your domain objects and are dispatched within the persisting transaction (see this blog post for details).
That means that as your domain model state is persisted, the events are dispatched.
Event Listeners
In your application, all components affected by an event can now listen to the domain events.
In your particular example, the VideoDetailView or StatsRepository might be event listeners for the VideoRatedEvent.
Of course, you will need to register those to the Guava EventBus with EventBus.register(Object).
This is my personal 5cents and maybe not closely enough related to your example of "The Clean Architecure".
I usually try to force a kind of MVC upon androids activities and fragments and use publish/subscribe for communication. As components I have model classes that handle business logic and the data state. They data changing methods are only to be called by the controller classes which usually is the activity class and also handles session state. I use fragments to manage different view parts of the application and views under those fragments (obviously). All fragments subscribe to one or more topics. I use my own simple DataDistributionService which handles different topics, takes messages from registered publishers and relays them to all subscribers. (partly influenced by the OMGs DDS but MUCH MUCH more primitive) A simple application would only have a single topic e.g. "Main".
Every part of view interaction (touches etc) is handled by its fragment first. The fragment can potentially change a few things without sending notifications. E.g. switching the subrange of rendered data elements if the rest of the app does not need to know/react. Otherwise the fragment publishes a ViewRequest(...) containing the necessary parameters to the DDS.
The DDS broadcasts that message and at some point reaches a controller. This can simply be the main activity or a specific controller instance. There should be only ONE controller so that the request is only handled once. The controller basically has a long list of request handling code. When a request arrives the controller calls to the business logic in the model. The controller also handles other view related things like arranging the view (tabs) or starting dialogs for user input (overwrite file?) and other things that the model is not supposed to know about but influences (Throw new NoOverWritePermissionException())
Once the model changes are done the controller decides if an update notification has to be send. (usually it does). That way the model classes do not need to listen or send messages and only take care of busines logic and consistent state. The update notification ist broadcasted and received by the fragments which then run "updateFromModel()".
Effects:
Commands are global. Any ViewRequest or other kind of request can be send from anywhere the DDS can be accessed. Fragments do not have to provide a listener class and no higher instance has to implement listeners for their instanced fragments. If a new fragment does not require new Requests it can be added without any change to controller classes.
Model classes do not need to know about the communication at all. It can be hard enough to keep consistent state and handle all the data management. No message handling or session state handling is necessary. However the model might not be proteced against malicous calls from the view. But that is a general problem and cannot really be prevented if the model has to give out references at some point. If your app is fine with a model that only passes copies/flat data its possible. But at some point the ArrayAdapter simply needs access to the bitmaps he is supposed to draw in the gridview. If you cannot afford copies, you always have the risk of "view makes a changing call to the model". Different battlefield...
Update calls might be too simple. If the update of a fragment is expensive (OpenGL fragment reloading textures...) you want to have more detailed update information. The controler COULD send a more detailed notification however it actually should not have to/be able to know what parts of the model exactly changed. Sending update notes from the model is ugly. Not only would the model have to implement messaging but it also gets very chaotic with mixed notifications. The controler can divide update notifications and others a bit by using topics. E.g. a specific topic for changes to your video resources. That way fragments can decide which topics they subscribe to. Other than that you want to have a model that can be queried for changed values. Timestamp etc. I have an app where the user draws shapes on canvas. They get rendered to bitmaps and are used as textures in an OpenGL view. I certainly don't want to reload textures everytime "updateFromModel()" is called in the GLViewFragment.
Dependency Rule:
Probably not respected all the time. If the controller handles a tab switch it can simply call "seletTab()" on a TabHost and therefore have a dependency to outer circles. You can turn it into a message but then it is still a logical dependency. If the controller part has to organize some elements of the view (show the image-editor-fragment-tab automatically after loading an image via the image-gallery-fragmen-tab) you cannot avoid dependencies completely. Maybe you can get it done by modelling viewstate and have your view parts organize themselves from viewstate.currentUseCase or smth like that. But if you need global control over the view of your app you will get problems with this dependency rule I'd say. What if you try to save some data and your model asks for overwrite permission? You need to create some kind of UI for that. Dependency again. You can send a message to the view and hope that a DialogFragment picks it up. If it exists in the extremely modular world described at your link.
Entities:
are the model classes in my approach. That is pretty close to the link you provided.
Use Cases:
I do not have those explicitly modelled for now. Atm I am working on editors for videogame assets. Drawing shapes in one fragment, applying shading values in another fragment, saving/loading in a galleryfragment, exporting to a texture atlas in another one ... stuff like that. I would add Use Cases as some kind of Request subset. Basically a Use Case as a set of rules which request in which order are allowed/required/expected/forbidden etc. I would build them like transactions so that a Use Case can keep progressing, can be finished, can be cancelled and maybe even rolled back. E.g. a Use Case would define the order of saving a fresh drawn image. Including posting a Dialog to ask for overwrite permission and roll back if permission is not give or time out is reached. But Use Cases are defined in many different ways. Some apps have a single Use Case for an hour of active user interaction, some apps have 50 Use Cases just to get money from an atm. ;)
Interface Adapters:
Here it gets a bit complicated. To me this seems to be extremely high level for android apps. It states "The Ring of Interface Adapters contains the whole MVC architecture of a GUI". I cannot really wrap my head around that. Maybe you are building far more complicated apps than I do.
Frameworks and Drivers:
Not sure what to think of this one. "The web is a detail, the database is a detail..." and the graphic contains "UI" in this Ring as well. Too much for my little head
Lets check the other "asserts"
Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.
Hm yeah well, if you run your own architecture that is what you get.
Testable. The business rules can be tested without the UI, Database, Web Server, or any other external element.
As in my approach model classes neither know about controllers or views nor about the message passing. One can test state consistency with just those classes alone.
Independent of UI. The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.
Again a bit overkill for android is it not? Independence yes. In my approach you can add or remove fragments as long as they do not require explicit handling somewhere higher up. But replacing a Web UI with a console UI and have the system run like before is a wet dream of architecture freaks. Some UI elements are integral part of the provided service. Of course i can easily swap the canvas drawing fragment for a console drawing fragment, or the classic photo fragment for a 'take picture with console' fragment but that does not mean the application still works. Technically its fine in my approach. If you implement an ascii console video player you can render the videos there and no other part of the app will necessarily care. However it COULD be that the set of requests that the controller supports does not align well with the new console UI or that a Use Case is not designed for the order in which a video needs to be accessed via a console interface. The view is not always the unimportant presenting slave that many architecture gurus like to see it as.
Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.
Yeah, so? How is that directly related to your architecture? Use the right adapters and abstraction and you can have that in a hello world app.
Independent of any external agency. In fact your business rules simply don’t know anything at all about the outside world.
Same here. If you want modularized independent code then write it. Hard to say anything specific about that.
Recently we switched our push notification system over to Parse.com, but I'm having ridiculous trouble integrating our client on several ends.
These are the two requirements, yet it seems impossible to implement them together:
There are several different types of notifications (different sounds based on type, or icons, etc.) that need to be used depending on the state of the client and the notification received. Therefor I need the option of a custom NotificationBuilder.
I need to track the consumption of the notification.
Their documentation states that if you want to handle everything yourself, all you have to do is add one line when the internal Parse OPEN event is broadcasted:
ParseAnalytics.trackAppOpened(getIntent());
Ha! If only that worked.
By preventing the internal Parse helper from receiving the RECEIVE event (by overriding the onPushReceive() method of the ParsePushBroadcastReceiver), it appears to remove any link between the data pushed to the device and the Parse service running on it (which makes sense why that would be, since it never reached the starting point in the first place). And no, calling the super version is not an option, as it would cause Parse to display its version of a notification since there will be an alert/title key that I have no control over.
I figured, what the hell, might as well try to put the tracking method call in the Activity that is called by the popup (whose Intent does contain all the data originally passed to it). Still, no effect, reaffirming my belief that intercepting the event is preventing the local Parse system from knowing there's a notification to consume, therefor preventing its consumption from being tracked.
So, the question is, does anyone know how to get Parse to use a custom NotificationBuilder so that the events it requires can actually be triggered correctly, allowing me to actually track notification consumption?
Or any kind of solution that enables me to use a custom notification, while still triggering the appropriate events to be tracked?
Possibly some way to save the push_hash and manually send the API call to whatever endpoint handles consumption?
Quite literally pulled some hair out over this one today and would appreciate any help I can get...
Thanks, everyone!
In my app, i have lots of GET,POST, PUT requests. Right now, i have a singleton class that holds my downloaded data and has many inner classes that extend AsyncTask.
In my singleton class, i have also a few interfaces like this:
/**
* Handlers for notifying listeners when data is downloaded
*
*/
public interface OnQuestionsLoadedListener {
public void onDataLoadComplete();
public void onDataLoadingError();
}
Is there something wrong with this pattern (many inner classes that extend AsyncTask)?
Could it be done more efficiently with maybe just 1 inner class for every HTTP call (1 for GET, 1 for POST, ...)? If so, how to decide what to do after e.g. GET request?
As a whole, you should get away from AsyncTasks while preforming network requests.
Your AsyncTasks are linked to your Activity. That means, if your Activity stops, your AsyncTask stops.
This isn't the biggest problem when fetching data to show in that Activity, since you won't care that the fetching has stopped. But when you want to send some saved data to the server, and your user pressed 'back' or something like that before everything is sent, the data could be lost and not send.
What you want to have instead, is a Service which will keep running regardless of what happens to your Activities.
I'd advise you to take a look into RoboSpice. Even if you decide not to use it, reading what it does and why it does will give you a good insight on the pretty long list of reasons not to use AsyncTasks for network requests and why better to use Services.
If you use this, the rest of your question about efficiently network requesting is obsolete too, since they'll handle it for you the best way possible.
Nothing wrong with many async classes.
What ido is have a network layer,a service class. Send an intent to the service class with a resultreceiver object as part of intent. then in the service make http request in async task and send back the the result through result receiver object.
A good design is to abstract the ui (activity or fragment) from network access.
In a recently developed app I followed a similar scheme but in addition implemented a WebRequest class doing the actual GET, POST, PUT etc.
What I now have is a "Connector" class which has a whole lot of AsyncTask subclasses within.
In my implementation, however, I made them accept a Callback object to which each of those subclasses passes the Http result.
I think this is a valid if perhaps not ideal way.
What I imagine could be an improvement would be if I had just one subclass of Asynctask to which I would pass the request body (which is now built within those different tasks), the request url and method as well as the callback (which is, in my opinion a rather nice way to get the results).
I have a Network Client class that is receiving a large binary block and parsing it into a usable Java object. The Network Client is on a separate thread from the app's View. What is the best way to make this object available to the View? I've come up with the following solutions, but I feel like none of them are the correct one:
Create the object in the Network Client and let the View access it directly
I would send a small message in a Handler telling the View that the data has been updated
Con: requires that I synchronize the object between the threads to ensure that the Network Client doesn't replace the object while the View is accessing it
Serialize (Parcel?) the object in the Network Client and send it through a Handler to the View
Pro: there are no questions of ownership of the data
Con: would probably be a huge performance drain on the app
Create a reference to the object and pass that to the View
I come from a C++ background, and I'm not sure if this is even possible in Java. I C++, I could just send the View a pointer to the object and let it take care of it. That seems like something Java wouldn't let me do. Is this feasible?
Are any of these solutions advisable, or should I approach the problem in a completely different way?
If you don't want to keep downloading when the activity is in the background, then use non-blocking IO, not threads.
If you do want to keep downloading when the activity is in the background, you probably want to use a service. You can make the object Parcelable or so; I think the underlying service implementation passes pointers around if your activity and service are within the same process (I think they are by default, but ICBW).
If the object is really big and you don't feel comfortable returning it with a get method, maybe you could put its contents into an SQLite database and optionally expose it as a ContentProvider. You could also send an Intent and either cause the View to then go and grab the payload or attach it to the Intent.
Look at the application class subclassing this class and referencing this within your manifest will enable you to store the reference to the service/download controller at a central position that will be available in every activity of your app. This enables you to keep the data in memory and reduce the need of recreating the big object if you need it in more places then just one activity.
For the download you can use a local service that communicates with your activity through a binder object. Keep in mind that a service is not a thread. If you want have the download running in the background you need to create a thread in the oncreate method of your service.
Also keep in mind that it is good practice to have an annotation show the user that a service is doing something and let him access the service and cancel it or view it status.