Switching between activities without losing custom data - android

Currently using an Intent with startActivity() to switch between 2 activities which share an abstract superclass. However, whenever startActivity() is called the custom object inherited from the abstract superclass gets reset. Is there anyway to maintain this object between startActivity() calls? Serializing the object with OnSavedInstanceState does not work because this object contains a LinkedList.

Every time a class is created regardless if it extends a superclass (in this case an Activity), the superclass is recreated. You would extend the Activity to share common methods/functions and imports....
You want to stay away from Serializable, so you want your object class to implement Parcelable:
public class CustomObject implements Parcelable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
}
public CustomObject() {
}
protected CustomObject(Parcel in) {
this.name = in.readString();
}
public static final Parcelable.Creator<CustomObject> CREATOR = new Parcelable.Creator<CustomObject>() {
#Override
public CustomObject createFromParcel(Parcel source) {
return new CustomObject(source);
}
#Override
public CustomObject[] newArray(int size) {
return new CustomObject[size];
}
};
}
In the first activity you want to pass the List to the second Activity using an Intent:
public class StartActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(StartActivity.this, ReceiveDataActivity.class);
i.putParcelableArrayListExtra("KEY", getCustomObjectList());
startActivity(i);
}
});
}
private ArrayList<CustomObject> getCustomObjectList() {
ArrayList<CustomObject> itemList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
CustomObject customObject = new CustomObject();
customObject.setName("Name " + i);
itemList.add(customObject);
}
return itemList;
}
}
Then to get the list you would use getIntent():
public class ReceiveDataActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receive_data);
List<CustomObject> itemList = getIntent().getParcelableArrayListExtra("KEY");
Toast.makeText(this, "List size = " + itemList.size(), Toast.LENGTH_SHORT).show();
}
}

Related

Display data from ArrayList in android from one activity to another activity

I would like to show car specification information when button click. Illustration enclosed. The data from array list. So far my code :
#Override
public void onBindViewHolder(#NonNull final CardViewHolder holder, int position) {
Car car = listCar.get(position);
Glide.with(holder.itemView.getContext())
.load(car.getFoto())
.apply(new RequestOptions().override(350, 550))
.into(holder.imgFoto);
holder.tvCarName.setText(car.getName());
holder.tvCarSpecs.setText(car.getSpecs());
holder.btnSpec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent detailCar= new Intent(v.getContext(), DetailActivity.class);
v.getContext().startActivity(detailPage);
}
});
}
DetailActivity code
public class DetailActivity extends AppCompatActivity {
private ArrayList<Car> listCar;
public DetailActivity(ArrayList<Car> list) {
this.listCar = list;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Intent intent = getIntent();
listElang = (ArrayList<Elang>) intent.getSerializableExtra("DATA");
}
}
First you have to make Car class as parcelable then you can pass car object to another activity
Intent detailCar= new Intent(v.getContext(), DetailActivity.class);
detailCar.putExtra("item",car)
v.getContext().startActivity(detailCar);
in DetailActivity just get the object
onCreate(Bundle savedInstanceState){
if(getIntent()!=null && getIntent.getParcelableExtra("item")!=null){
Car car=(Car)getIntent().getParcelable("item")
}
}
for beginner tutorial check this link
To show car specification information when button click, you can use intent to pass data from one activity to another activity .
First of all create a Serializable model class
Like this:
public class DemoModel implements Serializable{
String name;
String number;
public DemoModel(String name, String number){
this.name=name;
this.number=number;
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public String getNumber(){
return number;
}
public void setNumber(String number){
this.number=number;
}
}
OnItemClick
ArrayListdatalist;
Intent intent=new Intent(this,FirstActivity.class);
intent.putExtra("car_detail",datalist.get(i));
startActivity(intent);
SecondActivity
DemoModel cardetail= (DemoModel) getIntent().getSerializableExtra("car_detail");
Log.e("check_response", ""+cardetail.getName()));

How to make nested ArrayLists parcelable

To pass an arrayList of objects to a fragment, I have to make the list objects parcelable.
public mObjectClass implements Parcelable {
// Some code
}
The problem is that one of the attributes in my list objects is another object-based arrayList.
public mObjectClass implements Parcelable {
// Some code
private ArrayList<someOtherObject> anotherArrayList;
}
How can I make mObjectClass parcelable?
someOtherObject has to implement Parcelable (not extend has in your question) too. Then you can call parcel.writeTypedList(anotherArrayList); to write it and parcel.readTypedList(yourList, someOtherObject.CREATOR) to read it back. You can read more here
This solution is heavily influenced by some Stackoverflow posts, including
this.
Essentially make both Classes parcelable and make use of someOtherClasses Parcelable.Creator.
mObjectClass:
public class mObjectClass implements Parcelable {
private ArrayList<someOtherObject> anotherArrayList;
//add getter + setter...
public mObjectClass() {
anotherArrayList = new ArrayList<someOtherObject>();
}
public mObjectClass(Parcel in) {
anotherArrayList = new ArrayList<someOtherObject>();
in.readTypedList(anotherArrayList, someOtherObject.CREATOR);
}
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel outParcel, int flags) {
outParcel.writeTypedList(anotherArrayList);
}
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
#Override
public mObjectClass createFromParcel(Parcel in) {
return new mObjectClass(in);
}
#Override
public mObjectClass[] newArray(int size) {
return new mObjectClass[size];
}
};
}
someOtherObject:
public class someOtherObject implements Parcelable {
String someString;
//add getter + setter...
public void writeToParcel(Parcel out, int flags) {
out.writeString(someString);
}
public static final Parcelable.Creator<someOtherObject> CREATOR = new Parcelable.Creator<someOtherObject>() {
public someOtherObject createFromParcel(Parcel in) {
return new someOtherObject(in);
}
public someOtherObject[] newArray(int size) {
return new someOtherObject[size];
}
};
public int describeContents() {
return 0;
}
public someOtherObject(Parcel in) {
someString = in.readString();
}
public someOtherObject() {
}
public someOtherObject(String someString) {
this.someString = someString;
}
}
Tada, you are now able to add mObjectClass as extra to your intents after initialising it and using a setter to set the Arraylist with other someOtherObjects.

Android: passing object between activities and make it parcelable

New to Android programming. Having trouble to pass the object between activities and make it parcelable. Could somebody tell me what the problem could be? I want to know whether the logic is sound.
public class MainActivity extends Activity {
private Bundle MyActivityParams;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MyActivity.class);
MyActivityParams = fillInData(MyActivityParams);
intent.putExtras(MyActivityParams);
startActivity(intent, savedInstanceState);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private Bundle fillInData(Bundle bundle){
bundle.putFloat("com.company.MyActivity.FL", 12);
bundle.putFloat("com.company.MyActivity.VH", 100);
bundle.putFloat("com.company.MyActivity.const", 1);
return bundle;
}
}
public class DisplayActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
displayData();
}
private void displayData(){
//ActivityData is from MyActivity
ActivityData data = new ActivityData(getIntent().getExtras());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_display, menu);
return true;
}
}
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
displayParams();
}
private void displayParams(){
ActivityData dataBundle = new ActivityData((getIntent()).getExtras());
transfer(dataBundle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_algorithm, menu);
return true;
}
public void transfer(ActivityData incomingdata){
startActivity(incomingdata.getIntent());
}
protected static class ActivityData{
private Bundle data;
private TextView text;
private Intent intent;
public ActivityData(Bundle bundle){
/*data = bundle;
intent = new Intent(null, DisplayActivity.class);
text = new TextView(null);*/
}
public void display(String key){
this.text.setText(data.getString(key));
//not allowed: startActivity(intent);
//not allowed either: setContentView(text);
}
public Intent getIntent() {
return intent;
}
public void setIntent(Intent intent) {
this.intent = intent;
}
public TextView getText() {
return text;
}
public void setText(TextView text) {
this.text = text;
}
public Bundle getData() {
return data;
}
public void setData(Bundle data) {
this.data = data;
}
}
}
Let's have a Person class
public class Person {
private String name;
private String email;
private int age;
public Person(int age, String name, String email) {
this.age = age;
this.name = name;
this.email = email;
}
}
A parcelable one would look like this
public class ParcelablePerson implements Parcelable {
private final Person person;
private ParcelablePerson(Parcel parcel) {
this.person = new Person(parcel.readInt(), parcel.readString(), parcel.readString());
}
public ParcelablePerson(Person person) {
this.person = person;
}
public Person getPerson() {
return person;
}
#Override
public int describeContents() {
return 0;
}
// This is the method where you disassembly your object to pieces
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(person.getAge());
parcel.writeString(person.getName());
parcel.writeString(person.getEmail());
}
public static final Creator<ParcelablePerson> CREATOR = new Creator<ParcelablePerson>() {
// And here you create a new instance from a parcel using the first constructor
#Override
public ParcelablePerson createFromParcel(Parcel parcel) {
return new ParcelablePerson(parcel);
}
#Override
public ParcelablePerson[] newArray(int size) {
return new ParcelablePerson[size];
}
};
}
The crucial thing in the process is to have the same order of the variables in private ParcelablePerson(Parcel parcel) constructor and public void writeToParcel(Parcel parcel, int flags) method... You can see it on the age property which is an int.
try this one.
ParcelTest.java
import java.util.HashMap;
import android.os.Parcel;
import android.os.Parcelable;
public class ParcelTest implements Parcelable {
private HashMap map;
public ParcelTest() {
map = new HashMap();
}
public ParcelTest(Parcel in) {
map = new HashMap();
readFromParcel(in);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ParcelTest createFromParcel(Parcel in) {
return new ParcelTest(in);
}
public ParcelTest[] newArray(int size) {
return new ParcelTest[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(map.size());
for (String s: map.keySet()) {
dest.writeString(s);
dest.writeString(map.get(s));
}
}
public void readFromParcel(Parcel in) {
int count = in.readInt();
for (int i = 0; i < count; i++) {
map.put(in.readString(), in.readString());
}
}
public String get(String key) {
return map.get(key);
}
public void put(String key, String value) {
map.put(key, value);
}
}
ExampleSupplierActivity.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class ExampleSupplierActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ParcelTest p = new ParcelTest();
p.put("green", "go");
p.put("yellow", "wait");
p.put("red", "stop");
Bundle b = new Bundle();
b.putParcelable("com.example.trafficlight", p);
Intent i = new Intent(this, ExampleConsumerActivity.class);
i.putExtras(b);
startActivity(i);
}
}
ExampleConsumerActivity.java
import android.app.Activity;
import android.os.Bundle;
public class ExampleConsumerActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
ParcelTest p = b.getParcelable("com.example.trafficlight");
String red = p.get("red");
// ...
}
}
try this out this code work for me. but i have implement serializable rather than parcelable.
Try to implement parcelable rather than serializable . and try it if its work. i havnt tried this but implementing parcelable.
To pass and object to another activity:
in activity A
make sure the class implements the serializable interface
create a new intent
create a new bundle
use the putSerializeable method to add the object to the bundle with a key
put the bundle in the intent by using the putExtras method
start the activity using the startActivity method
Specifically,
Intent intent = new Intent(ShoulderExerciseScreen.this, ExercisesScreen.class);
Bundle bundle = new Bundle();
bundle.putSerializable("exercise", new Exercise("BenchPress));
intent.putExtras(bundle);
startActivity(intent);
in activity B
declare and object of the type you want passed
use the getIntent method to get the intent
use the getSerializeableExtra to get the the value using the key
cast the returned value from getSerializeableExtra and the desired type
Specifically,
Exercise ex = (Exercise)getIntent().getSerializableExtra("exercise");
if(ex != null)
{
//do something
}

Passing ArrayLists in Android

I'm trying to pass array lists between activities in Android. The lists contains strings. I've read a lot about Parcelable. Would I need to create a Parcelable to pass a String array list? As of now I am using putStringArrayListExtra() and getSringArrayListExtra() to pass the lists through intents.
Here is some of my code.
Intent load = new Intent(getApplicationContext(), HelloTabWidget.class);
load.putStringArrayListExtra("albums", albums);
load.putStringArrayListExtra("songs", songs);
load.putStringArrayListExtra("artists", artists);
load.putStringArrayListExtra("fileName", fileName);
This is my onCreate method for the acticity which obtains the array list.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.songlist);
Bundle extras = getIntent().getExtras();
isArtists = extras.getBoolean("artists");
isAlbums = extras.getBoolean("albums");
isSongs = extras.getBoolean("songs");
Intent get = getIntent();
songs = get.getStringArrayListExtra("songs");
artists = get.getStringArrayListExtra("artists");
albums = get.getStringArrayListExtra("albums");
fileName = get.getStringArrayListExtra("fileName");
if(isArtists == true)
updateArtistsList();
else if(isAlbums == true)
updateAlbumsList();
else if(isSongs == true)
updateSongList();
}
The class which retrieves the list is supposed to create a listView from the data in the lists. Whenever I run the code i get nullPointerExceptions when trying to make the lists. I know that my listView code works, so I have narrowed down the problem to the intents which pass the array lists.
Thanks in advance.
EDIT:
Here are the first few lines from the logcat.
12-28 03:03:42.313: E/AndroidRuntime(873): FATAL EXCEPTION: main
12-28 03:03:42.313: E/AndroidRuntime(873): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.adam.mediaplayer/com.adam.mediaplayer.HelloTabWidget}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.adam.mediaplayer/com.adam.mediaplayer.MakeListActivity}: java.lang.NullPointerException
It depends on the type of arraylist
putIntegerArrayListExtra(String name, ArrayList<Integer> value)
putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value)
putStringArrayListExtra(String name, ArrayList<String> value)
putCharSequenceArrayListExtra(String name, ArrayList<CharSequence> value)
Then you can read from you next activity by replacing put with get with key string as argument,eg
myIntent.getStringArrayListExtra("arrayListName");
Here is how you can pass an ArrayList :
MyListClass.java - Custom class
public class MyListClass implements Parcelable{
private int test;
public MyListClass()
{}
public MyListClass(Parcel read){
test = read.readInt();
}
public int getTest() {
return test;
}
public void setTest(int test) {
this.test = test;
}
public static final Parcelable.Creator<MyListClass> CREATOR =
new Parcelable.Creator<MyListClass>() {
#Override
public MyListClass createFromParcel(Parcel source) {
return new MyListClass(source);
}
#Override
public MyListClass[] newArray(int size) {
return new MyListClass[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel arg0, int arg1) {
arg0.writeInt(test);
}
}
MyParcelable.java
public class MyParcelable implements Parcelable {
private List<MyListClass> arrList = new ArrayList<MyListClass>();
private int myInt = 0;
private String str = null;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public List<MyListClass> getArrList() {
return arrList;
}
public void setArrList(List<MyListClass> arrList) {
this.arrList = arrList;
}
public int getMyInt() {
return myInt;
}
public void setMyInt(int myInt) {
this.myInt = myInt;
}
MyParcelable() {
// initialization
arrList = new ArrayList<MyListClass>();
}
public MyParcelable(Parcel in) {
myInt = in.readInt();
str = in.readString();
in.readTypedList(arrList, MyListClass.CREATOR);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel outParcel, int flags) {
outParcel.writeInt(myInt);
outParcel.writeString(str);
outParcel.writeTypedList(arrList);
}
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
#Override
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
#Override
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
MainAcitivty.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
arrList.add(new MyListClass());
arrList.get(0).setTest(200);
MyParcelable object = new MyParcelable();
object.setMyInt(100);
object.setArrList(arrList);
Intent intent = new Intent(MainActivity.this,ReceiverParcel.class);
intent.putExtra("parcel", object);
startActivity(intent);
}
ReceiverParcel.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
MyParcelable object = b.getParcelable("parcel");
System.out.println(object.getArrList().get(0).getTest());
System.out.println(object.getMyInt());
}

Parcelable data returning null

I have the following three classes.
Cricketers
public class Cricketers implements Parcelable {
private String name;
private String address;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#Override
public int describeContents() {
return 0;
}
public Cricketers() {
}
#Override
public void writeToParcel(Parcel dest, int flag) {
dest.writeString(name);
dest.writeString(address);
dest.writeInt(age);
}
public Cricketers(Parcel in) {
this.name = in.readString();
this.address = in.readString();
this.age = in.readInt();
}
#SuppressWarnings("unchecked")
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Cricketers createFromParcel(Parcel in) {
return new Cricketers(in);
}
public Cricketers[] newArray(int size) {
return new Cricketers[size];
}
};
}
Activity1
public class Activity1 extends Activity {
private ArrayList<Cricketers> cricketers;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cricketers = new ArrayList<Cricketers>();
Cricketers object = new Cricketers();
object.setName("Sachin");
object.setAddress("Mumbai");
object.setAge(37);
cricketers.add(object);
Cricketers object1 = new Cricketers();
object1.setName("Sourav");
object1.setAddress("Kolkata");
object1.setAge(38);
cricketers.add(object1);
Cricketers object2 = new Cricketers();
object2.setName("Dravid");
object2.setAddress("Bengaluru");
object2.setAge(38);
cricketers.add(object2);
Intent intent = new Intent(this, Activity2.class);
intent.putExtra("cricketers", cricketers);
startActivity(intent);
cricketers = null;
}
Activity2
public class Activity2 extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
Cricketers cricketers = bundle.getParcelable("cricketers");
}
}
I am retrieving the data on Activity2 , but its returning cricketers = null .
Within the Activity1 class , the data "cricketers" is being properly added to the Intent.
Kindly provide your inputs.
Thanks in advance.
I have solved the issue ....
Changes need to done to the Activity2 class
public class Activity2 extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
ArrayList<Cricketers> data = new ArrayList<Cricketers>();
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
data = bundle.getParcelableArrayList("cricketers");
for (int count = 0; count < data.size(); count++) {
Cricketers cric = (Cricketers) data.get(count);
String name = cric.getName();
String address = cric.getAddress();
int age = cric.getAge();
}
}
}
I found some problem with AIDL cache ... if you change all your code abour the parcelable, or simple you refactor the name of the class. if you reinstall the app, or clear the app cache, the AIDL is still working and searching fot that refactored class.
I fix this task rebooting the device. It a crap to change code in the parcelable class but not see it works when reinstall the app, you MUST to reboot the device... or thats whar I do.
Thanks for the example dude ;) the activit2 was a bless!!

Categories

Resources