Android Parcelable object when returning loses its value

0

hoping they are well, I have a concern.

I have two activities 1) List of courses and their children are the activities - 2) Data and evaluation of the course activity

The process is as follows.

I select a course activity from a ExpandableListView which with the position of the group and its child I get the object Activity , previously filled. This happened to the activity (2) with an intent.

So far so good, my problem is when evaluating the activity. The change in the database is correct but when I do the set in the activity object, within the activity (2) the value is maintained, but when I go back the value is lost, since it does not update an image that I have in the list of activities of ExpandableListView

Activity Class

class Activity implements Parcelable{
private Integer id;
private String titlePref;
private String title;
private String teacher;
private String type = "";
private Integer evaluateContent = 0;
private Integer evaluateTeacher = 0;
private Integer canEvaluate = 0;
private Integer isAccomplished = 0;
private Integer isBlocked = 0;
private Integer hvVideo = 0;
private Video videoObj = null;
private String bannerUrl = "";
private String blockName = "";

//default constructor, for video or other who extends of Activity
public Activity(Integer id) { this.setId(id); }
public Activity(Integer id, String titlePref, String title, String teacher, Integer isAccomplished, Integer isBlocked, Integer hvVideo, String bannerUrl, String blockName)
{
    this.setId(id);
    this.setTitlePref(titlePref);
    this.setTitle(title);
    this.setTeacher(teacher);
    this.setIsAccomplished(isAccomplished);
    this.setIsBlocked(isBlocked);
    this.setHvVideo(hvVideo);
    this.setBannerUrl(bannerUrl);
    this.setBlockName(blockName);
}

private Activity(Parcel in)
{
    id              = in.readInt();
    titlePref       = in.readString();
    title           = in.readString();
    teacher         = in.readString();
    canEvaluate     = in.readInt();
    evaluateContent = in.readInt();
    evaluateTeacher = in.readInt();
    isAccomplished  = in.readInt();
    isBlocked       = in.readInt();
    hvVideo         = in.readInt();
    bannerUrl       = in.readString();
    blockName       = in.readString();
}

public static final Parcelable.Creator<Activity> CREATOR = new Parcelable.Creator<Activity>()
{
    @Override
    public Activity createFromParcel(Parcel in) {
        return new Activity(in);
    }

    @Override
    public Activity[] newArray(int size) {
        return new Activity[size];
    }
};

public int describeContents() {
    return 0;
}
public void writeToParcel(Parcel dest, int flags)
{
    dest.writeInt(id);
    dest.writeString(titlePref);
    dest.writeString(title);
    dest.writeString(teacher);
    dest.writeInt(canEvaluate);
    dest.writeInt(evaluateContent);
    dest.writeInt(evaluateTeacher);
    dest.writeInt(isAccomplished);
    dest.writeInt(isBlocked);
    dest.writeInt(hvVideo);
    dest.writeString(bannerUrl);
    dest.writeString(blockName);
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getTitlePref() {
    return titlePref;
}

public void setTitlePref(String titlePref) {
    this.titlePref = titlePref;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getTeacher() {
    return teacher;
}

public void setTeacher(String teacher) {
    this.teacher = teacher;
}

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public Integer getEvaluateContent() {
    return evaluateContent;
}

public void setEvaluateContent(Integer evaluateContent) {
    this.evaluateContent = evaluateContent;
}

public Integer getEvaluateTeacher() {
    return evaluateTeacher;
}

public void setEvaluateTeacher(Integer evaluateTeacher) {
    this.evaluateTeacher = evaluateTeacher;
}

public Integer getCanEvaluate() {
    return canEvaluate;
}

public void setCanEvaluate(Integer canEvaluate) {
    this.canEvaluate = canEvaluate;
}

public Integer getIsAccomplished() {
    return isAccomplished;
}

public void setIsAccomplished(Integer isAccomplished) {
    this.isAccomplished = isAccomplished;
}

public Integer getIsBlocked() {
    return isBlocked;
}

public void setIsBlocked(Integer isBlocked) {
    this.isBlocked = isBlocked;
}

public Integer getHvVideo() {
    return hvVideo;
}

public void setHvVideo(Integer hvVideo) {
    this.hvVideo = hvVideo;
}

public Video getVideoObj() {
    return videoObj;
}

public void setVideoObj(Video videoObj) {
    this.videoObj = videoObj;
}

public String getBannerUrl() {
    return bannerUrl;
}

public void setBannerUrl(String bannerUrl) {
    this.bannerUrl = bannerUrl;
}

public String getBlockName() {
    return blockName;
}

public void setBlockName(String blockName) {
    this.blockName = blockName;
}

public Video getVideo()
{
    return videoObj;
}
public Video makeVideo(String video){ return videoObj = new Video(this.getId(), video);}

So I pass the object to the other android activity (2):

listViewMyCoursesBlocks.setOnChildClickListener(new ExpandableListView.OnChildClickListener()
    {
        @Override
        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id)
        {
            myActivity = (Activity)parent.getExpandableListAdapter().getChild(groupPosition,childPosition);
            if( myActivity.getIsBlocked() == 0 )
            {
                gPosition = groupPosition;
                cPosition = childPosition;
                Intent i = new Intent(getApplicationContext(), MyClassActivity.class);
                i.putExtra("myActivity", myActivity);
                startActivity(i);
                return true;
            }
            return  false;
        };
    });

I receive it like this:

Intent i = getIntent();
myActivity = i.getExtras().getParcelable("myActivity");

I make the set like this:

myActivity.setEvaluateTeacher(3);

When returning to the activity (1):

In my onResume I wanted to update an ExpandableListView image that indicates that this course activity is "evaluated".

but when doing

myActivity.getEvaluateTeacher();

Returns as value 0

I was reading and apparently in JAVA it does not work to pass a value by reference, but by value. Then each object should have value in its own "Android activity", if I did not understand wrong.

How can I set a value in my activity (2) and when I return to the activity (1) I can receive the value I gave ... and do something like:

listAdapter.notifyDataSetChanged();

To update the image of the list.

Thanks

    
asked by Makeyourmove 25.05.2017 в 22:12
source

1 answer

0

In the end as nobody helped me haha, no joke. I found the answer, although from what I understood there are a couple of ways to solve it.

Without going very deep, the problem of passing an object from one Activity to another (1) to (2), is that they are passed by "value" and not by "reference". It's as if you had a duplicate object and if you can set new values, but it will only serve for the android activity you are in.

One can occupy parcelable, serialize, create your own hash in json, so you can pass the object as such and not field by field. But the problem is the same.

The way I found to update my list from another activity was:

1. In your first activity, take startActivityForResult

Intent i = new Intent(getApplicationContext(), MyClassActivity.class);
i.putExtra("myActivity", myActivity);
startActivityForResult(i,1);

Where the first parameter is the attempt and the second is a value of request , you tell the second android activity, in my case, MyClassActivity that has a request with value 1, this value must be integer and you define it ex: 500, 6600, 2, 3, 4.

2. In your second activity, receive the attempt as always

Intent i = getIntent();
myActivity = i.getExtras().getParcelable("myActivity");

3. In my case I needed to return or set the object of my first activity, when I backed up with the cell or app back button

@Override
public void onBackPressed()
{
    Intent intent = new Intent();
    intent.putExtra("IsAccomplished", myActivity.getIsAccomplished());
    setResult(RESULT_OK, intent);
    finish();

    super.onBackPressed();
}

You create an attempt, you tell it that you are going to pass a value, in my case IsAccomplished and I say it is OK with RESULT_OK

4. Finally, receive the answer in your first activity

// This method is called when the second activity finishes
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // check that it is the SecondActivity with an OK result
    if (requestCode == 1) {
        if (resultCode == RESULT_OK) {

            // get String data from Intent
            Integer IsAccomplished = data.getIntExtra("IsAccomplished", 0);

            myActivity.setIsAccomplished(IsAccomplished);
        }
    }
}

In short, requestCode is the value 1 that we passed in the first activity to the second. resultCode , is the response value we give you. data , it has all the values added with putExtra, they can be one or more or none.

For my particular problem I wanted to update an image on my expandable list, in the onResume function of my first activity add the following:

@Override
public void onResume()
{
    super.onResume();
    if( listAdapter != null )
    {
        listAdapter.notifyDataSetChanged();
    }
}

With this I said, when the adapter exists (it is created in onCreate), when returning from the second activity to the first one (this is in the background and resumes in onResume), I say with notifyDataSetChanged , that if there is a change update.

Add to your manifest file:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Since in some tablets and cell phones, they try to access usb memory either by SDcard or another device and if you do not have it, the app is dropped.

Here is the documentation: link

In my adapter when the field IsAccomplished = 1, add an image with a "check", if it is 0, add an image with a circle WITHOUT "check".

I saw several possible solutions and this one adapts to my needs, without having to study a lot, I occupy functions that are in android and also if for some reason the device where your app runs takes many resources, if the app needs to free memory or another thing, this does it automatically without you throwing an error, as you could if you wanted to occupy a static model as "object".

If someone wants to contribute more, with pleasure the answer will be edited and tips can be added, since I spend a lot of time on this and it's not fun

For more information you can review by looking in stackoverflow with the word "startActivityForResult" and in the android documentation link

    
answered by 27.05.2017 / 00:09
source