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).
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 generally dislike the usage of singletons or static class, since I can refactor them to something different most of the time.
However, I am currently designing my access point to a HTTP API on an Android app, and I was thinking that I have the following environment:
I need to send HTTP requests in the majority of my code modules (Activities).
The code for sending a request does not depend on the request being sent
There will always only be one specific user on the app per session (unlike the server-side that has to handle different users etc)
Therefore, I was thinking that this could be a situation where it is justifiable to use a Singleton, or even a static class, to place HTTP requests - In the rest of my code, I would then simply have to use something like:
MyHttpAccess.attemptLogin(name, pass, callback)
in order to complete the request. I'm even leaning towards using a static class, as I do not have any variable data that I can think of needing to store.
Does this seem like good or bad design, and what should I potentially change?
Http Request in kotlin using single class
https://medium.com/#umesh8346/android-kotlin-api-integration-different-method-b5b84eb4f386
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.
Currently I have an app which has code in its main activity that reads data from an xbee. My problem is that I want to relay this data to 4 different threads in 4 different classes throughout my project. I looked into bundling it, but that seems like a one time data transfer, not a stream of it.
One idea I had was to write the data to a string called messages and then have a getMessages() function, but I ran into a problem calling a static method from a non-static class or vise versa.
Have you considered using SharedPreferences or extending Application? SharedPreferences will let you store basic types (String, int, boolean, etc) in persistent storage. Application can be extending to store variables / methods that can be accessed anywhere in your program. For example, MyApplication app = (MyApplication)getApplicationContext();
Are you looking to modify this stream of data in each of your threads, or simply read a value and modify data separately? You may want to setup some boolean flags to ensure you aren't accessing / modifying data that isn't safe to perform those operations on. Hope that helps! Let me know if I can provide a code example for clarity.
one way of doing it to simply make your main activity write into android.database.sqlite and others will simply read from it
since not sure how your code layout is I just refer you the documetation page :
http://developer.android.com/reference/android/database/sqlite/package-summary.html
You can create one handler for each of your threads and then post messages on all the handlers. Below is the link which creates an Handler and post messages from the handler reference:-
using a Looper in a Service is the same as using a separate thread?
You can implement observer pattern to solve this.Make the four classes as observers and the activity as subject.
Expose a api like onDataChanged(byte[] data) which will be called whenever your activity has some new data.
To learn more about observe pattern refer-https://en.wikipedia.org/wiki/Observer_pattern
You can also have a look at classic producer consumer problem if you want synchronization https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem
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.