1

EDIT:

This is the method I use to initialize variables after the layout of the activity is loaded in the onCreate() method

private void initializeVariables() {
    randomButton = (Button) findViewById(R.id.randomButton);
    gameButton = (Button) findViewById(R.id.gameButton);
    i = 1;
    listIndex = 0;
    nameList = PlayersNames.nameList;
    villagerBundle = new ArrayList<>();
    characters = new ArrayList<Card>();
    players = new ArrayList<Player>();


    villagerOne = new Villager();
    villagerTwo = new Villager();
    villagerThree = new Villager();
    villagerFour = new Villager();
    villagerFive = new Villager();

    villagerBundle.add(villagerOne);
    villagerBundle.add(villagerTwo);
    villagerBundle.add(villagerThree);
    villagerBundle.add(villagerFour);
    villagerBundle.add(villagerFive);
}

ORIGINAL QUESTION:

I have 2 activities in Android.

In one i create:

public static Villager villagerOne;

villagerOne = new Villager();

Then in the other one I should access to the villagerOne's mAlive variable:

villagerOne.getMAlive();

For reference, these is the Card class:

public class Card {

//Names
public String mCharacter;

//Status
private boolean mAlive;
private boolean mDefended;
private boolean mOwled;
private boolean mLastSavaged;
private boolean mLastLynched;


//Constructor
public Card(){
}

public void setMCharacter(String value){
    this.mCharacter = value;
}

public void setMAlive(boolean alive){
    this.mAlive = alive;
}

public String getMCharacter(){
    return mCharacter;
}

public boolean getMAlive(){
    return mAlive;
}

}

And this is the Villager class which extends Card:

public class Villager extends Card {

public Villager(){
    mCharacter = "Villager";
}


}
FET
  • 942
  • 4
  • 13
  • 35
  • 1
    Accessing other activities' variables directly is bad practice, and also complicates the whole lifecycle thing. So try passing the `mAlive` boolean thru an intent. – Mehmet K Mar 07 '16 at 14:05
  • If you intend to pass a `Villager` object from one Activity into another, you must use `Intent` and your `Card` objects must implements the `Parcelable` interface. Here's a good example: https://stackoverflow.com/questions/7181526/how-can-i-make-my-custom-objects-be-parcelable – victorantunes Mar 07 '16 at 14:08
  • Thanks, I'll update my code to that when I'm done with the app, thanks for the tip! – FET Mar 07 '16 at 14:09

3 Answers3

1

I think if you make the Villager class implement Serializable you could send it with an intent like:

Intent i = new Intent(FirstActivity.this, SecondActivity.class);
Villager villagerOne;
villagerOne = new Villager();
i.putExtra("Villager", strName);
startActivity(i);

And on the second activity you get the results:

Villager villager = (Villager) getIntent.getSerializableExtra("Villager");
Dennis van Opstal
  • 1,294
  • 1
  • 22
  • 44
  • 1
    While it wouldn't make a huge difference here, implementing `Parcelable` is generally much better on Android than Serializable. – DeeV Mar 07 '16 at 14:14
  • You are right, but I have more experience using Serializable than with Parcelable, so that's why I use Serializable – Dennis van Opstal Mar 07 '16 at 14:23
0

Since you declared your villager as static in activity one you should be able to access it from anywhere by

one.villagerOne.getMAlive()

(here I assume the name of the activity class one is one)

Since this solution seems to be controversial I'll tell you why I think it is a good one:

If you pass a copy of the Villager through intent and your Villager gets "killed", the original Villager will be destroyed, why the copies will still be alive. this means you have to communicate to every activity with a copy and tell them to defunct their copy of the villager. Listeners and all.

If you use the reference to the static member, as I suggested, all you have to do is test the reference for null before you call any method:

if( one.villagerOne != null ) alive = one.villageOne.getMAlive();
ilomambo
  • 8,290
  • 12
  • 57
  • 106
  • 2
    While it would work its horrible stylewise and can cause issues if the activity is relaunched with stale data. If you need to do this your architecture is off. – Gabe Sechan Mar 07 '16 at 14:08
  • @GabeSechan Android source code is plagued with access to static members of classes. you should look at it. If it is good enough for android coders, it is good enough for everyone – ilomambo Mar 07 '16 at 14:09
  • Its not static members that are necessarily evil. But static members of Activities definitely are. And I've read a lot of android source code, other than static constants there really isn't much. THis is a bad idea and it would be an automatic rejection by any competent code reviewer. – Gabe Sechan Mar 07 '16 at 14:10
  • @GabeSechan I do not agree, that's why they are static. the belong to the class, not to the class instances state, relaunched or not. – ilomambo Mar 07 '16 at 14:11
  • 1
    But they don't belong to the activity. THey're being shared between activities. That means they belong at some other scope, and making them static members of an Activity is an amateurish hack. And one that will turn your code to spaghetti if its any nontrivial app. – Gabe Sechan Mar 07 '16 at 14:12
  • Those static variables are also created at class creation where as in this case the Villager could be created some time later. It could also be destroyed if an Activity holding it is destroyed. – DeeV Mar 07 '16 at 14:12
  • @DeeV the static members are always there, the instance (hence the "new Villager()" ) is what can be created later. It is not different from a variable, which if it is not initialized it cannot be used. Static members are not destroyed when the class instance is destroyed. – ilomambo Mar 07 '16 at 14:15
  • @ilomambo Ok. It's created in static space, but what if it's altered? If the process is wiped and the state is restored, the Villager object will be in it's default state. It's not final or immutable. Should also note that "Why is my static variable null?" is a very common StackOverflow question like here: http://stackoverflow.com/questions/9541688/static-variable-null-when-returning-to-the-app – DeeV Mar 07 '16 at 14:19
  • @DeeV I get your point, but it is not specific to my answer. Look at the other answers. Let's say you successfully pass the reference via intent -> same question, what happens if the original is altered or destroyed? It is the programmer responsibility to track the life cycle of his objects. Not a reason not to use static members. Just code responsibly – ilomambo Mar 07 '16 at 14:23
  • Well, thanks for the discussion, as I'm not an expert yet in Android, I wanted to achieve this as @ilomambo did, but if then there will be a better way I'll surely upgrade, but for now ilomambo got what I asked for :) – FET Mar 07 '16 at 14:39
  • @ilomambo just one more question, I typed your way around to this problem, but unfortunately it gives me (at runtime) a NullPointerException, any ideas? (Sorry for the delay from your answer) – FET Mar 16 '16 at 18:11
  • @FET I see you posted your code. The second line, where you create `VillagerOne` is not executed until you create an instance of `One` class. You should create the villager in the same line as you declare the static variable (which is null until you assign a vaild villager to it) `public static Villager villagerOne = new Villager()` – ilomambo Mar 17 '16 at 21:04
  • So, everything in the same line? The fact is I create it on a method, and it says the "static" tag isn't allowed there – FET Mar 17 '16 at 21:16
  • Try to see my updated question, added some mode code ;) @ilomambo – FET Mar 17 '16 at 21:26
  • Oh and not every Villagers gets created as soon as the activity gets launched, it depends on the players amount! @ilomambo – FET Mar 17 '16 at 21:59
  • Oh, and sorry for my many comments, but if you think it may help, I've uploaded my code on GitHub, if you want give it a click: https://github.com/SnipCode/lupusInTabula – FET Mar 17 '16 at 22:05
  • @FET these comment are not meant for chats or discussions. That said, point #1, the static villager must be a field of a class, not of a method. Point #2, see in my answer I check for null before using the method `getMAlive()` to avoid the nullpointer exception. – ilomambo Mar 18 '16 at 06:40
  • But Not all the villagers should be created at first, that's why I'm using that initializevariables() method to do that for the ones I need to @ilomambo – FET Mar 18 '16 at 20:29
  • @FET Please don't take it the wrong way, but it seems you have some holes in your programming education. This topic is not just a recipe, you must understand how java classes work to use it properly. We could chat back and forth for a long time, but what I think you need is to go back to the book and refresh (or learn) java and object oriented design. – ilomambo Mar 19 '16 at 10:23
  • Alright @ilomambo. thank you for your honesty, I will surely get back to it, thank you – FET Mar 19 '16 at 15:36
0

If you need a copy of that variable, you should pass it in via extras. If you need to access that actual variable- you probably should rearchitect. Data that's needed by multiple Activities shouldn't be owned by any Activity, it should be owned by another data structure that both Activities could reach. For example a singleton Player object which can be queried for its list of cards.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127