How to send an object of a model in Intent - java

I have a model and it implements the Parcelable interface, on my MainActivity I've like this
ArrayList<Model> modelList = new ArrayList<>();
for(int i = 1; i <= 5; i++)
modelList.add(new Model( "name "+ i , "number "+ i));
And I have a ListView of this modelList items.
What I'm trying to do is that when the user clicks on an item of the list I use Intent and put its extra like modelList.get(position)
I just want to put a specific object of the model, and not the whole model like intent.putParcelableArrayList("KEY", modelList)

You might just need to do this
Intent().putExtra("name", yourModel)
putExtra has many overloads one of them is putExtra(name : String, value : Parcelable)

You can pass it in following way.
intent.putExtra("KEY",modelList.get(position));
and get it in following way in another activity
Model model=getIntent().getParcelableExtra("KEY");

Related

How to putextra arraylist<object> with if statement and show it in other activity

Activiy 1
List<Goods> goodsList = new ArrayList<>();
goodsList = getAllData();
Goods goods = new goods();
intent.putExtra("listbarang", (Serializable) goodsList);
function getAllData() is my function to show all data in my database, and I show it with RecyclerView by the way.
Activity 2
goodsList = (List<Goods>) getIntent().getSerializableExtra("listbarang");
and there's how I get the ArrayList
all I want is put extra the ArrayList with the specific condition with if statement. For example, I want to show only the goodies who have stock more than 0.
I have succeeded to store the ArrayList. But I want to get specific data for that condition, maybe using looping or something else.
I don't quite understand with your question, I think you probably need to pass the criteria with the list. Something like this:
intent.putExtra("listbarang", goodsList);
// Criteria for at least one item in the list
intent.putExtra("criteria", 1);
Then process the extra:
int criteria;
Intent intent = getIntent();
goodsList = (List<Goods>) intent.getSerializableExtra("listbarang");
criteria = intent.getIntExtra("criteria", 0);
// do something based on criteria
for(Goods good: goodsList) {
if(good.getStock >= criteria) {
// process the good.
}
}
you can implements your Goods class from Parcelable, and use Bundle.putParcelableArrayList to store your list data.
Solution for passing arrayList between activities, fragment and storing them in sharedPreferences.
Passing arrayList of Object type from One Activity to another activity.
This solution will also used for passing from one fragment to another fragment
or fragment to activity or activity to fragment.
And this also helps to store arrayList of object type in sharedPreferences.
First added this dependency in build.gradle(app) file
compile 'com.google.code.gson:gson:2.4'
for e.g.:
//first Activity
ArrayList<Goods> list=new ArrayList<>();
Gson gson=new Gson();
String goodList=gson.toJson(list);
Intent intent=new Intent(this,SecondActivity.class);
intent.putString("goods",goodList);
startActivity();
//Second Activity
Gson gson=new Gson();
String goodList=getIntent().getString("goods");
Type type=new TypeToken<ArrayList<Goods>>(){}.getType();
List<Goods> list = new gson.fromJson(goodList,type);
I hope this solution will help you.
Thanks

Extracting string array from object array

So I have arraylist modelData that populates a recyclerview using sqlite database in some activity.!
Now in my MainActivity I want an string arraylist of names from the modelData !
that's what did so far..
// inside the onCreate of MainActivity
//code ..
db = new DBHandler(this, null, null, 1);
modelData = new ArrayList<AzkarModel>();
modelData = db.getDataFromDB();
for (AzkarModel o : modelData) {
ArrayList<String> names = new ArrayList<>();
names.add(o.getName());
}
for (int i = 0; i< modelData.size();i++){
names.add(modelData.get(i).getName());
Log.i("The List Log", names);
}
Two problems
1) [FIXED] The names arraylist is showing the same element twice at first and end
I/ The List Log: [Mike, John, Sam, Nora, Mike]
2) The arraylist names doesn't get updated..! when I add/edit/delete from the recycler and go back to the MainActivity I don't see the new changes unless I close the app then open it again..! I can't use notifyDataSetChanged since there's no adapter here.!
Once you have an array list object, populate it inside a loop
ArrayList<String> modelNames = new ArrayList<>();
for (AzkarModel model : modelData) {
modelNames.add(model.getName());
}
Now you have an array list with model names inside. Concerning the second question, please use an recyclerview adapter here you can find a nice tutorial.

Android - Open Activity and wait for Result before continue in calling class

I am quite new to Android and facing a problem.
I have a class A from where i would like to call another activity. I have found some post saying that there is no way to pause the calling Activity and wait for the result.
public class A extends AppCompatActivity {
[...]
private List<String> list = new ArrayList<String>();
private void doSomething() {
list.add("a");
list.add("b");
for(String tmp:list) {
Intent intent = new Intent(this, OtherActivity.class);
intent.putStringExtra("TAG", tmp);
startActivityForResult(intent, 1);
}
}
This is not a complete example but basically the problem I am facing.
I have a loop and try to open another activity. The loop does not stop when i start the "OtherActivity".
The first thing i see is the OtherActivity for the last element of the list (here String "b"). When i finish this Activity i see the OtherActivity with String "a" in wrong order.
I considered a callback for this, but i am not sure how to implement it because the callback handler wouldn't be within the loop.
Again I am not sure if a callback would be a good idea because many people say i should not Pause the "calling" activity for the sub activity.
You are doing it totally wrong, if you want to send data to other activity and do some work then get the result , i would prefer that send the whole data as a list , do the work and then get the data from that activity , you shouldn't be doing it in a loop. Either pass it is as intent or save it in database then retrieve from database.
If you want to pass the whole list of string to the other activity I suggest you do this
You can pass an ArrayList the same way, if the E type is
Serializable.
You would call the putExtra (String name, Serializable value) of
Intent to store, and getSerializableExtra (String name) for retrieval.
Example:
ArrayList<String> myList = new ArrayList<String>();
intent.putExtra("mylist", myList);
In the other Activity:
ArrayList<String> myList = (ArrayList<String>) getIntent().getSerializableExtra("mylist");
Please note that serialization can cause performance issues: it takes time, and a lot of objects will be allocated (and thus, have to be garbage collected)
Source: Passing a List from one Activity to another
Or as Abdul suggested, save the data to a database and retrieve it from there in the other activity

Class Cast Exception when passing array of Serializables from one activity to another

I have an array containing serializable objects and am trying to use Intent's putExtra() and Bundle's getSerializable(). However, I am getting a class cast exception and don't understand why.
Below is the code. UserInfo is my own class which implements Serializable, and I have been able to pass individual UserInfo objects between activities. I've only ran into this problem when attempting to use an array.
Code sending the serializable:
Intent intent = new Intent( JOIN_GROUP ); //JOIN_GROUP is a constant string
String user_ids[] = packet.userIDs();
int length = user_ids.length;
UserInfo users[] = new UserInfo[length];
for ( int i = 0; i < length; ++i )
users[i] = getUserByID( user_ids[i] );
intent.putExtra( USERS_IN_GROUP, users );
Code retrieving the serializable:
Bundle extra = intent.getExtras();
String action = intent.getAction();
if ( action.equals(IMService.JOIN_GROUP) )
{
//CLASS CAST EXCEPTION
UserInfo users[] = (UserInfo[]) extra.getSerializable( IMService.USERS_IN_GROUP );
}
Here is the error:
Question
I'm aware I could probably just use a different data structure, but I would like to understand why the array does not work since arrays are serializable?
EDIT: SnyersK was able to get a simpler but similar scenario to work.
So I tried the same thing, and I still get the same exception. It turned my array of Tests into an Object when retrieving the array, which results in the casting exception.
My Test object:
package types;
import java.io.Serializable;
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
private String hello = "hello";
}
Code to pass the array of Test objects:
Test myArray[] = new Test[] { new Test(), new Test() };
Intent i = new Intent( this, Login.class );
i.putExtra( "key", myArray );
Code to retrieve the array of Test objects:
Bundle extras = getIntent().getExtras();
Test array[] = (Test[]) extras.getSerializable( "key" ); //Class Cast Exception
Apparently this is a bug on older versions of Android. (Version 5.0.1 is the only version tested on which it works like expected, perhaps it works from 5.0 and up)
The bug
Let's say we have an Array of an object called User which implements Serializable.
User[] users;
When we try to pass this array to another activity through an intent like this
intent.putExtra("myKey", users);
our users will get converted to Object[].
If we try to get our array from the intent in the second activity like so
User[] users = getIntent().getSerializableExtra("myKey");
We will get a ClassCastException.
From the docs, we can conclude that this shouldn't be a problem since Array is a serializable class, and putExtra(String key, Serializable value) has been added since api 1.
If you want to pass an Array through an intent on Android versions prior to Android 5.0.1 (maybe some older versions work aswell, but up to Android 4.3 it is NOT working)
You'll have to work around it. You could do this by converting your Array to an ArrayList.
EDIT
another workaround is copying your extra to a new array, thus, not having to cast it. I'm not sure about the positive/negative consequences of the method though. It would look like this:
Object[] array = (Object[]) getIntent().getSerializableExtra("key");
User[] parsedArray = Arrays.copyOf(array, array.length, User[].class);
I found this method here: How to convert object array to string array in Java.
Replace
intent.putExtra( USERS_IN_GROUP, users );
with
intent.putExtra( USERS_IN_GROUP, new ArrayList<UserInfo>(Arrays.asList(users)));
try like this:
Intent intent = new Intent( JOIN_GROUP ); //JOIN_GROUP is a constant string
String user_ids[] = packet.userIDs();
int length = user_ids.length;
UserInfo users[] = new UserInfo[length];
for ( int i = 0; i < length; ++i )
users[i] = getUserByID( user_ids[i] );
Bundle bnd=new Bundle();
bnd.putSerializable(USERS_IN_GROUP, users);
while sending you are attaching to intent and while retrvng you are reading from the bundle (which is intent extras).
Is the UserInfo inner class or a separate java class file?
If it is an inner class, then the parent class also should be Serializable.
If not, make UserInfo class implement Parcelable and use
intent.putParcelableArrayListExtra(USERS_IN_GROUP, new ArrayList<UserInfo>(Arrays.asList(users)));
in doc HERE there's no putExtra(String name, Serializable[] value) method (note [ ] brackets). there is only putExtra(String name, Serializable value) - single serializable object.
you should try with Parcelable - intent can carry extra one object and array

Sharing an ArrayList Between Acitivities

I am having problems storing a List in an Application class across activities.
In my Splash screen, I am loading data into a List from a MySQL database.
The List is in a class called Rateit that extends Application. I do this in it as a class variable:
public static List<String> masterCats;
In the Splash Screen Activity/Class, I do this:
in onCreate:
Rateit.masterCats = new ArrayList<String>();
Inside my AsyncTask loop where loading data I do this:
Rateit.masterCats.add(cat);
cat being the list item that comes from the database. I have Log.d the data (cat) as well as the ListPosition to check if it is being added to the List and it is.
However, I need to grab that same info in the next Activity and put it into an adapter. It comes back with 0 length.
I simply do this: adapter = new MasterCatAdapter(getActivity(), Rateit.masterCats, tf);
How come the list doesn't maintain data across activies? Is this because its static? something else?
(Note: I will add getter and setter methods here soon!)
As #A--C mentioned in his comment, avoid the model you have now with the static variable. Instead, I would do something like this:
private void yourMethodWhereYouGetYourData(){
//get your data
ArrayList<String> masterCats = new ArrayList<String>();
masterCats.add(cat);
//Assuming you're doing this synchronously, once you've gotten your data just do:
Intent i = new Intent(this, YourActivity.class);
i.putStringArrayListExtra("MasterCats", masterCats);
startActivity(i);
}
Then, in your new Activity's onCreate() or wherever, just access the list by doing:
getIntent().getStringArrayListExtra("MasterCats");
#KickingLettuce also mentioned in the comments about keeping this accessible if the user navigates away from the Activity. So, in whichever Activity you want to save the ArrayList, just convert it to a comma-separated String and save it in SharedPreferences like so:
private void saveCats(){
//get your ArrayList from wherever (either as a global variable or pass it into the
//method.
StringBuilder sb = new StringBuilder();
for(int i = 0; i < masterCats.size(); i++){
if(i == masterCats.size() - 1)
sb.append(masterCats.get(i));
else
sb.append(masterCats.get(i)+",");
}
SharedPreferences.Editor prefsEditor =
PreferenceManager.getDefaultSharedPreferences(this).edit();
prefsEditor.putString("MasterCats", sb.toString()).commit();
//Note: in API 11 and beyond you can store a Set of Strings in SharedPreferences, so
//if you are only targeting API 11+ you could do:
Set<String> masterCatsSet = new LinkedHashSet<String>(); //<--using LinkedHashSet to preserve order
masterCatsSet.addAll(masterCats);
prefsEditor.putStringSet("MasterCats",masterCatsSet).commit();
}
Then access this SharedPreference in your onCreate or something if you wish to persist the list across the Activity lifecycle.
saving the List in a Application extended class is good idea you can achieve it by following
Declare List as follows in your App class like
public static List<String> masterCats;
and declare setter and getter methods for above variable
public List getMasterCatsList()
{
return masteCats;
}
public Void setMasterCatsList(List list)
{
masteCats=list;
}
get the application object as follows in your Loader class as follows
Application application = (YOurClassName That Extends Application class) getApplication();
and set the list as follows
application.setMasterCatsList(List list);
now you can access this list from any activity as follows
Application application = (YOurClassName That Extends Application class) getApplication();
List l = application.getMasterCatsList();
hope it will be helpful to you

Resources