How to use 'bundle' instead of 'intent.putExtra()' in Fragment in Android - java

In Activity I have used the following code for passing the value to other Activity classes:
intent.putExtra("book_arr", book_arr); // [putExtra(String *name*,Serializable *Value*)]
How to use like this code in Android Fragments?
I have tried the following code, but it is not supporting serialized value:
Bundle args =new Bundle();
args.putInt("book_arr", book_arr);
Thanks,

args.putSerializable("book_arr", book_arr);
If your book_arr (which should be bookArr) is a large array of heavy objects, consider making them Parcelable. You'll need to write additional code, but it's about x10 faster. (if it's not a big object you probably shouldn't bother). This page can be helpful
http://www.developerphil.com/parcelable-vs-serializable/

Related

Android: static variables and moving complex data

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.

How can I pass data between two fragments belonging to same container activity?

I've an arraylist in one fragment that I need to pass to another fragment. Both of these fragments belong to the same container activity.
This is what I came up with but apparently there's something wrong with it.
This is how I'm sending the data from Fragment1:
Bundle b=new Bundle();
b.putStringArrayList("Brands",allBrands);
Fragment fragment = new Fragment();
fragment.setArguments(b);
This is how I'm trying to receive the data at Fragment2:
brands = getArguments().getStringArrayList("Brands");
I understand this is not how it is done. Please help me out.
I checked the question on implementing fragmentlistener.This isn't about that.
There are few different ways of communicating between fragments.
1) creating a interface
2) shared preferences
3) sqlite database
using 1) you create a common method where the information can be read by both fragments.
using 2) is great to save the information forever until overwritten or deleting the app.
using 3) same as the second one but it depends on the app if you really need a database or not.

Send data between activities

I'm new in Java & Android Studio. I need to send data between activities. But
I have 3 activities. A -> B -> C
I want to send a data from A to C directly without write anything in B.
Hope you understood. Have a nice day and thanks.
It depends on what type of data you want to pass.
The first way is to use static global variable. You are able to pass any type you want, but this way is fragile as the object that you are passing is saved in memory (not disk). It can lead to memory leaks.
The second way is to use SharedPreferences. With this, your data will be saved on disk.

Android Intents and Lists

I plan on reading several files when my app/game is created and using the information from them for the entirety of the app. I also have to write to the file at one point.
I have two files. One is a 2-column text file that I'll turn into a dictionary for fast searching. The other is a text file that has 11 columns. I'll make a dictionary out of two of the columns, and the other data I need kept as is so I can write to the columns to count the amount of times something happens in different circumstances for datamining.
Currently, I've turned the second file into a list of a list of strings, or List>. I can't figure out how to pass that around in intents. ".putStringArrayListExtra" only works for a list of strings.
Am I going about this the wrong way entirely? This is my first real Android app.
In order to store a data structure into an Intent, it has to be either serializable or parcelable. If your data structure is neither of them, you might create a class that would implement Serializable and manage it. A good example might be found here.
Once done, you then might use Intent.putSerializable(...) to store your data structure. See this:
Using putSerializable in Android
Additionally to this, if you could convert your structure into a JSON structure, you'd already have it done since it would be treated as a String. If not, the above solution should be easy to do.

Maintaining Android Activity's data: onPause, onSaveInstanceState, onRetainNonConfigurationInstance

I have an application Activity that in onCreate loads an XML file from a service using an AsyncTask. The XML is parsed into an ArrayList. When I switch to a different activity and then back to the main activity, I want to be able to recognize that that XML file was already loaded and use the populated ArrayList.
What is the best way to persist that ArrayList?
onSaveInstanceState only seems to support primitives and I've been unable to set up a case where onRetainNonConfigurationInstance actually gets called. So in onCreate, the XML data is loaded from the server ever time I switch to that Activity. I have made the models that are in the ArrayList implement Parcelable, so could use that in some way?
What is the best way to persist that ArrayList?
I don't see where your problem has anything to do with multiple activities. What happens if the user presses HOME (gasp!), for example? Your app will eventually be closed. Do you want to reload the data from the server? If the answer is "yes", then you don't need to "persist" anything, and onSaveInstanceState() may suffice (see below). If the answer is "no", then you need to rethink your approach to your data model, so you arrange to keep the data in a database, synchronizing with your Web service periodically, and probably dumping the ArrayList and replacing it with a Cursor.
onSaveInstanceState only seems to support primitives
If the answer to my HOME question is "yes", then you can just hold onto the data in a data member of your activity, and, if it is modestly sized, also stash it in the Bundle in onSaveInstanceState(). A Bundle can hold an ArrayList of Parcelable. However, if the data set is large (say, 100KB or more), you probably don't want to go this route and should consider the "no" path I described above.
I've been unable to set up a case where onRetainNonConfigurationInstance actually gets called.
Rotate the screen. There are other scenarios, but orientation changes are the easiest ones to trigger it.
However, it has nothing to do with your problem.
"onSaveInstanceState only seems to support primitives"
onSaveInstanceState supports objects, as long as they are declared serializable.
// ON_SAVE_INSTANCE_STATE
// save instance data (5) on soft kill such as user changing phone orientation
protected void onSaveInstanceState(Bundle outState){
password= editTextPassword.getText().toString();
try {
ConfuseTextStateBuilder b= ConfuseTextState.getBuilder();
b.setIsShowCharCount(isShowCharCount);
b.setTimeExpire(timeExpire);
b.setTimeoutType(timeoutType);
b.setIsValidKey(isValidKey);
b.setPassword(password);
state= b.build(); // may throw
}
catch(InvalidParameterException e){
Log.d(TAG,"FailedToSaveState",e); // will be stripped out of runtime
}
outState.putSerializable("jalcomputing.confusetext.ConfuseTextState", state); // save non view state
super.onSaveInstanceState(outState); // save view state
//Log.d(TAG,"onSaveInstance");
}

Categories

Resources