I'm trying to send a SerializableExtra from an application to another one.
I use
resultIntent.putExtra("thing", fc);
and in the receive application :
Thing theThing = (Thing) data.getSerializableExtra("thing");
But since the applications doesn't have the same names I got the following error:
Java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object (name = com.test.senderapp.Thing)
And I can't modify the sender application , I need to find a way to make it works only controlling the application that receive the intent.
Thank you
Use Content Providers to achieve this.
https://developer.android.com/guide/topics/providers/content-providers.
We were discussing this issue into something pretty similar; we wanted that a keyboard could share data with another app and use it with a combination of other features.
The goal is that you define which data to expose and other apps can use that similar to what the Contact's app does; which you can access a CursorLoader to fetch all of the user's contacts.
On the other hand, as a second solution, you can make your second app receive a String and send the object as a JSON; but I'd rather prefer the first one if you're going to keep adding more objects or summing up other applications.
Related
If I have a class that contains a static variable, say x:
class MyClass {
static boolean x = false;
// Other methods
}
Now let us say that, hypothetically, I set x = true; from my first activity. Is there any point through the rest of my app's life cycle (including various activities and threads) where this value will simple be 'reset' back to false due to how the 'Google JVM' or the android environment works? I have heard that static variables have a 'lifetime', that dies when the program dies. Do Activities count as separate 'programs'? What about services? Or even Widgets?
I am asking this because it is often difficult to share complex data structures that rely on other complex processing (like syncing data from an online database) in android due to how 'separated' activities are, and static variables are often a very quick and dirty solution to the problem. Other things I have tried include serialisation, but that doesn't really seem like a practical solution either (constantly serialising and decoding objects when the user navigates from one activity to the next seems like it would be very resource intensive).
If I am an evil person for doing this, please tell me what I am doing wrong, or even better, give me some links or examples of better ways to solve this problem.
Yes. There are times where that will reset. Primarily if the user leaves the app and starts fiddling around with other apps or if the user lets the phone go to sleep for a long period of time. The Android process could kill the actual app. Then the "state" of the app will be restored when the user comes back, however static variables will be at their defaults because the actual process was rebuilt.
Generally passing small objects between Activities and Services is done by overriding the Parcelable interface. This will allow you to save and restore objects using setOnInstanceState methods of both Activities, Views, and some adapters. They will likewise, have a restore method in which you can rebuild the object. Parcelable is preferable over Serializable.
Larger data may require a shared file or database depending on the data that you want to have synced. There is a 1 MB size limit for parcelables being passed between Activities. One common tactic is to save the information to a file and send a URI to the location of where the information can be retrieved.
Answering your question - yes, there is a situation when you set x = true and value will be 'reset' back to false. Well, not exactly reset but consider this scenario: you have an activity and a service. Service is using separate process (you can define that in AndroidManifest when you declare your service). Then those two processes (main app and service) won't share memory and setting x to true in your activity won't affect the value of MyClass.x in your service. In all other cases changing value in one place will be visible everywhere else. Hope it helps!
No, a static variable will not be changed unless you change it or the app ends, it is safe (but generally unclean) to use it. Closing the activity the variable lives in won't hurt it.
You suggest you just need to keep track of a value as you move around activities. In that case you can add the value in your Intents as what is called an 'extra'. If you need to also pass back the value after, android also has the startActivityForResult feature
Intent extras example:
x below could be any type of value including any object which implements Parcelable
Intent intent = new Intent(...);
intent.putExtra("myKey", x);
startActivity(intent);
in receiving class:
x = getIntent().getBooleanExtra("myKey");
Edit:
Given your additional comment - "lists of objects that contain yet more lists of objects" you may get a Parcel too large exception when trying to use extras, but this is an indication you have a bigger architectural problem and that there may be a better approach
Use Gson.
Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.
You have two options. Convert to string , then put data in an intent then pass to activity. Or Convert to string with gson, save to a preference, then in the other activity, check if the preference is alive and read from it.
If you wish to be bold, you can persist to database preferably using Realm for Android or ObjectBox is a new mobile object database optimized for performance. With ObjectBox, we are bringing technology from NoSQL server databases to mobile.
I have one activity in which I need to do a GET command to receive json data and have that inserted into my POJO. The GSON library does this for me. However, I need to do another GET command and have that json data inserted into a different POJO. In addition to that, I need to also do a POST command to send data to the server as well as update data on the server.
If I use a asynctask, I would need to create at least 2 different ones because I am handling to different POJOS. And then I would have to write some logic in there to do a POST instead of a GET... can you recommend to me some architecture which would best suit to do all of these things ? I dont want to have to create 4-5 different asynctasks classes., I think there might be a better approach than this.
I dont know how one asynctask can do the job, because I have 2 different return parameters for my asncytask: List, List . As mentioned above, I have 2 different GETS.
You can get all the data in a single AsyncTask, making 3 requests one after another thus creating 3 objects and returning all of them, say, as a list, from doInBackground().
I need to share data between two android apps that are on the same phone without using the internet. The data I want to share includes a several key value pairs of different data types. The options I am aware of are:
Using intents - Send and Receive. But the typical examples
for intents do not involve these use cases. Intents seems more
suited for sharing data of a particular mime type or launch apps (or
let users choose from) to handle the data being shared.
Sharing the SharedPreferences. However the MODE_WORLD_READABLE
or MODE_WORLD_WRITEABLE flags required for this have been deprecated
post API 17.
Broadcast Receivers - But I'm not exactly listening to events.
I want to use a request/response cycle.
Content Providers. This is great except for the fact that I
need to store the data in a database in the app sharing the data. If I have key, value pairs
where the value can be of different data types, this makes the data
table a bit cumbersome. Is there a better way to do this with
content providers?
Which is the best technique to adopt?
I created a small library that makes it simple to share SharedPreferences from one app to another in a READ ONLY fashion using ContentProvider.
Described it here - https://github.com/ratpik/android-sharedpreferences-api/blob/master/README.md
You can set up Broadcast Reciever on one end to listen for particular intent type. And broadcast intents from first application with data held in extras. You can send whole objects via intent using parcerable approach.
More about parcerable approach can be found here
I have to implement custom search in my application for android 2.3.I have some EditText in which user type one letter and then I send response to the server, retrieve all the results matches this one letter and then I need to display them in a list. When user types second button I also need to send new response and refresh data and so on.
The question how can I do this in Android 2.3? What should i use?
This seems to be too open ended with too many questions to give a really helpful answer.
What you use in your app will heavily depend on how the server's API is expecting you to communicate. I, for one, am all for hiding the specifics of what a server does from the application and put all the "smarts" behind the API. So a query like:
http:/blah.com/getresults?search=a
would result in whatever matches 'a'. If it is searching a MySql Db, processing a Google search, or accessing files on the system doesn't matter.
Your code needs to worry about the interface to the API to make queries and processing the results, whether they're free formatted text, JSON objects, or whatever.
Maybe rewording your question or provide information on what you know would help.
I have something of an abstract question regarding managing live feeds/polling on web sites.
I am creating a web app (built on Java/Spring/Hibernate) and on the user's home page I want a live feed of the latest activity from all the members of there team, and I am trying to work out the best way to handle this query on the server side.
The brute force way would be to load the current users list of team mates, and then iterate through each of his team mates, loading their latest conversations/file uploads/etc, and then merging all this activity in to a single list sorted by timestamp and returning that (lets say for sake of example that we just return the top 10 latest activity for the feed).
However, that seems very un-performant, especially as this operation would need to be done regularly (depending on the polling interval).
I have also considered making all the potential activities (conversations/status updates/uploads) as extending an Activity class and then just having a direct SQL/JPQL query in a DAO that selects all the latest activity from a set of users to be returned, but concerned that might bypass the caching and continued access to the DB would also reduce performance.
Has anyone handled this type of problem before? any one know what a good approach is?
Thanks!
This is an old one now, but here is what i did for this:
All tasks that should appear on a live wall extend Activity (this was already the case)
Created a new Notification object, the Notification had a link to the underlying Activity and a link to a user (who was being notified).
Created a pre-persist hook for Activity that created a Notification object for the Activity being persisted - it did this for every user that was interested (all users following the user that was persisting the Activity)
For the moment, Notifications are persisted/retrieved to the DB - possibly not scalable to very high volumes, but the approach I think supports moving to a Queue based system (such as LinkedIn's Kafka queue library which is designed exactly for this purpose). As it is per-user, it also provides the option to have a read/unread notification flag for significant notifications.