How to make an arraylist of arraylists parcelable in android - java

My problem is that I have an arraylist of arraylists with custom objects that needs to be passed from one activity to another.
Clearly, let's say I have something like:
ArrayList<ArrayList<Statement>> data;
in one activity and I want to pass it to another. So, first what I have done is to make Statement implement the Parcelable class.
Then in the first activity (sender) I call the putExtra() method by passing it the data.
In the second activity (receiver) I call the getSerializableExtra() method to get data.
That works. But I have read that Parcelable would be better for efficiency etc. and so I tried to call putParcelableArrayListExtra() in the sender activity and the getParcelableArrayListExtra() method on the receiver activity.
But when I do that, I get red underlines indicating sth. like
ArrayList< android.os.Parcelable > is required
in the first activity which is the sender I have the line:
Intent intent = new Intent(SenderActivity.this, ReceiverActivity.class);
intent.putParcelableArrayListExtra(SenderActivity.EXTRA_LISTOFSTATEMENTLISTS, dataListOfStatementLists);
In the receiver activity I have sth. like:
myList = ( ArrayList<ArrayList<Statement>>) getIntent().getParcelableArrayListExtra(EXTRA_LISTOFSTATEMENTLISTS);
What I need to fix ? I know the basics about how to send Parcelable objects from one activity to another. But that was all things like
ArrayList<ParcelableObject> data
I have never done it for nested data like this
ArrayList<ArrayList<ParcelableObject>>
I hope someone can help.
Thanks in advance

This is just another way to do it. I suppose you know how to get the values in other activity.
ArrayList<ArrayList<Statement>> data;
Bundle bundle = new Bundle();
bundle.putInt("size", data.size());
for (int i = 0; i < data.size(); i++) {
bundle.putParcelableArrayList("item"+i, data.get(i));
}

Try this to send Data
Intent intent = new Intent(SenderActivity.this, ReceiverActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("object", List);
in.putExtra("list", bundle);
startActivity(in);
For Recieving Data
Intent i=getIntent();
Bundle bundle= i.getBundleExtra("list");
ArrayList<Statement> list = bundle.getParcelable("object");

Every time you want to pass data from one activity to another one via Intent you have to make sure that the classes where you create the objects that you want to send are implementing Serializable, otherwise it won't work. Your problem could be something related to this so I recommend you to implement Serializable on your classes.

Related

using a constructor in an Activity class and trying to get information out from that constructor to display on the associated screen

My activity class contains a constructor that computes some data:
public IPrintPanelActivity(String title, Object data, byte logoChar,
String keyName, boolean printNCopies, boolean showPrintButton) {
/*
* Configure the panel
*/
super();
panelTitle = title;
this.logoChar = logoChar;
if (data != null) {
setTextArea((String) data);
}
//put the display print panel here
SignOnActivity.startMyActivity(context,(String) data,"CORRECT?");
finish();
}
Then I need this data Object (which is actually a string) to display it in a TextView of the associated layout file. The problem is that I don't know how to get data "out of the constructor" to write something like
myTextView.setText(data);
I found an answer to a question that was asked more than 2 years ago and it seems to be what I need. The problem is that I get a NullPointerException for the context variable.
Here's the definition of the static function startMyActivity:
public static void startMyActivity(Context context, String paramA, String paramB) {
// Build extras with passed in parameters
Bundle extras = new Bundle();
extras.putString("PARAM_A", paramA);
extras.putString("PARAM_B", paramB);
// Create and start intent for this activity
Intent intent = new Intent(context,IPrintPanelActivity.class);
intent.putExtras(extras);
context.startActivity(intent);
}
Do I give you enough information? Please let me know and please help me fix the NullPointerException.
Do not create constructors for your Activity classes. The Android OS is responsible for instantiating Activities and will only try to do so with the default constructor. Keep in mind that an Activity may be destroyed and recreated by the system at various times, usually during configuration changes, such as when the device is rotated between portrait and landscape orientations.
Any "arguments" you pass to an Activity should be done using a Bundle in the Intent that starts the Activity. In one of the lifecycle callback methods (e.g. onCreate()) you can call getIntent() and check its extras for data, then do as you wish.
The link you posted where the user Chase create d static method for starting an activity still follows these guidelines. All his method does is compose the Intent and its extras using the arguments of the static method, then calls startActivity using this Intent. He did not create a constructor for the Activity, nor did he ever call new to instantiate an Activity. He just simplified the process of creating the Intent and its extras to start the Activity with the proper data.
You don't have constructors explicitly for Activties. You don't instantiate a Activity class. You only declare the Activity in manifest file.
Please read the answer by Raghav Sood
And i quote Raghav
By treating an Activity as a normal Java class, you end up with a null
context. As most methods in an Activity are called on its Context, you
will get a null pointer exception, which is why your app crashes.
Can i Create the object of a activity in other class?

Use variables between two activities with different processes

I created my Base activity in separated process by adding to it's <activity> fragment in manifest:
android:process=":login_exception_process"
In Base activity I initiate my connection objects, and start next Activitty. But from another Activity when I try to get this instances of connection objects they are NULL.
Objects initiated by Base activity are saved in separated classes in static variables. How can I access this variable?
Passing values to another Activity
You have to start your next activity sending an extra in an Intent.
Intent intent = new Intent(this, NextActivity.class);
intent.putextra("keyName","value");
startActivity(intent);
And your next Activity, you can retrieve this value by doing this:
String data = getIntent().getExtras().getString("keyName");
Here is the documentation for that.
Getting a result from an Activity
Starting another activity doesn't have to be one-way. You can also start another activity and receive a result back. For example, if you want to start the NextActivity and return a value back from NextActivity to BaseActivity, you can use startActivityForResult().
Here is the documentation for that.
Update
Sending objects via intent can be done with two options:
Pseudo-codes
Serializable
intent.putExtra("MyClass", your_object);
// to retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");
Parcelable
Intent mIntent = new Intent(this, NextActivity.class);
Bundle mBundle = new Bundle();
mBundle.putParcelable(PAR_KEY, your_object);
mIntent.putExtras(mBundle);
startActivity(mIntent);
Despite Serializable seems to be the easiest option, follow this tutorial it will teach you both ways.
Hope this helps you.
You should use Extras
How do I get extra data from intent on Android?
Basically, when creating your intent you have to put extras:
intent.putExtra("name", "My name is John");
then when you want to get it back when you start the next activity:
this.getIntent().getExtras().getString("name");
You can do this with any type if you convert the Object to a byte array.

Use the same object between activities

I have tried a lot of different ways to use the same object in different classes. I want to do this because I want the data to be stored in this object.
But no matter what I do, it hust wont be stored when I press the "back" button on the phone and then go back.
I am sending a bundle with the object to the second activity like this:
Intent intent = new Intent(this, TrainingDays.class);
Bundle bundle = new Bundle();
bundle.putSerializable("programObject", program);
intent.putExtras(bundle);
startActivity(intent);
And I am receiving the object like this:
Bundle bundle = this.getIntent().getExtras();
program = (Program) bundle.getSerializable("programObject");
I can use the object just fine, but I every time I switch back to another activity, the object is clean from data. Am I doing something wrong here or could it be something else that causes this? Any help will be greatly appreciated.
That's the correct way to manage objects. If you do not need to write the object on a File I would suggest to switch to Parcelable. About your problem, if you want to pass back the object, you can use the pair startActivityForResult and onActivityResult
Override the onBackPressed() method of Activity and use #blackbelt 's combination of startActivityForResult() and onActivityResult()
You can see an example on the developer page http://developer.android.com/reference/android/app/Activity.html#StartingActivities
onBackPressed() controls going back to the previous activity you could create a new Intent in the onBackPressed(), then a create a Bundle and Put the Bundle in the setResult() method as such setResult(RESULT_OK, mBundle); and Bundle Object will get passed back the previous activity.
in Short
#Override
public void onBackPressed(){
Intent data = new Intent();
Bundle newBundle = new Bundle();
newBundle.putParcelable("MyObject", mObject);// must extend Parcelable on Object class
data.putBundleExtra("ObjectBundle", newBundle);
setResult(RESULT_OK, data);
finish();
}

How to save an intent from one class to another class

I am new to Android so apologies if I am asking something silly. I am trying to develop an alarm clock application - basically, it's my final project and I am trying to develop an alarm like there is in API level 2.3.3.
I have designed the list view that takes input through a dialog box like time. I have also coded it to set an alarm.
Now I want to save that alarm as an intent in the other class, and I don't have any idea how to save different alarms in the other activity. I have also checked for the desk-clock alarm code but I didn't get that too.
Please help me someone, I am stuck here for the code for more than a week. Please someone help me, I shall be thankful to you.
If you want to send an Intent from one Activity to another, and then retrieve information from inside the Intent, the best way is use the Bundle object inside the intent:
Let's supose you send the intent from Activity1 to Activity2...
In Activity 1:
Intent intent = new Intent(Activity1.class,Activity2.class);
//I use the String class name as a key value, but you can use whatever key
intent.putExtra(String.class.getCanonicalName(), myString);
startActivity(intent);
//Or this other method if you want to retrieve a result from Activity2
//startActivityForResult(intent,Activity2);
In Activity 2:
Intent intent = this.getIntent();
Bundle bundle = intent.getExtras();
String myString = bundle.getString(String.class.getCanonicalName());

Trying to pass an int between two classes on Android platform

I'm trying to pass an int between two classes using a bundle. I have looked online and it seems like it should be easy to do, its just not working for me :( any help is much appreciated! I am trying to pass the int life from one page to another in a simple game.
here is the code for the first page where I am passing it from
int life = 5;
....
if(input.equalsIgnoreCase(teststr))
{
Intent i = new Intent("com.name.PAGETWO");
i.putExtra("com.name.PAGETWO.life", life);
startActivity(i);
mpButtonClick.stop();
}
And on the second page, trying to receive the int
Intent i = new Intent("com.name.PAGETWO");
Bundle extras = i.getExtras();
int temp2 = extras.getInt("life");
int life = temp2;
when i try to run it, it tries to go on to the second page and then just says the application has unexpectedly stopped, but when i comment out the code it continues running as normal, so i know i am definitely putting in the code here wrong somewhere. thanks in advance!
Why would a brand new intent object contain the int you've passed? In the receiver activity, use getIntent() to retrieve the intent that the activity was started with. That intent would contain your extras.
You're creating a brand new Intent on the second page, which of course doesn't have the bundle. Instead, you need to retrieve the calling Intent using getIntent().
Here's how your second page's code could look:
int life = getIntent().getExtras().getInt("life");
EDIT: Looking at your code again, make sure the key name of the extra is consistent on both ends. To be sure, I usually use a final variable for this. So in your second activity (let's say it's ActivityTwo), declare this at the top (outside of onCreate()):
final static public String EXTRA_LIFE = "life";
Then in the calling activity:
Intent i = new Intent(this, ActivityTwo.class);
i.putExtra(ActivityTwo.EXTRA_LIFE, life);
startActivity(i);
(You may have also been constructing your Intent incorrectly; compare my example).
And in the second activity, inside of onCreate():
int life = getIntent().getIntExtra(EXTRA_LIFE, 0);
(You can replace 0 with what you want the default value to be if the extra doesn't exist.)
That way you don't have to worry about typos and can rely on Eclipse's suggestions to make sure you're consistent.

Categories