Android - Accessing Array in multiple activities - java

Just a real quick question. I've defined an array in one activity and I'm trying to access it in another one. I was planing to extend it as so:
public class MyChallenges extends Main {
But I need to extend 'ListActivity' to get my code to work, as I am using a custom listview, so I can't extend two activities. As shown:
public class MyChallenges extends ListActivity {
Is there any other way, apart from extending the main activity? This is the array I'm trying to access for read and write:
public String[][] arr = new String[2][6];
So, in short, how can I access the array 'arr' from another class? Thanks guys!

Make a class that contains the array, and reference that class from your activities. For example:
public class ArrayOfStuff
{
public static String[][] arr = new String[2][6];
}
Then, to modify the array, use something like ArrayOfStuff.arr[1][1] = "foo";
Happy coding!

The element of a resources file can only be used for single dimension arrays. In other words, everything between and is considered to be a single string.
If you want to store data in the way you describe (effectively pseudo-XML), you'll need to get the items as a single String[] using getStringArray(...) and parse the and elements yourself.
Personally I'd possibly go with a de-limited format such as...
Bahrain,12345
...then just use split(...).
Alternatively, define each as a JSONObject such as... and treat this array as JSON object and use JSON method for get value for element...
{name:Bahrain,codes:12345}
->simply create string array at res/values/strings.xml:
->after u can access this string array in whole application...

Related

How do I set and get a Vector<Integer> in two different classes?

I need to set and get a Vector in two different classes but I seem to be losing the size of the Vector in the process. If I do v.size() I get 100 for example. Then I use a setter. Then in another class I use a getter to access this Vector again. If I do v.size() in this new class I get 0. The below code is a rough example of what I have, as I can't copy paste my code exactly, since it's part of a larger private project.
public class Params {
private Vector<Integer> _v = new Vector<Integer>();
public Vector<Integer> get_v(){return _v;}
public void set_v(Vector<Integer> _v){this._v = _v;}
}
public class a {
v.add(10);
System.out.println(v.size()); //returns 1
Params p = new Params();
p.set_v(v);
}
public class b {
Params p = new Params();
v = p.get_v();
System.out.println(v.size()); //Returns 0
}
When you make Params = new Params() on b you create a new object of the class Params, and this new object initializes a new empty Vector on the _v property.
You should pass the object created on a to b so this class can use it.
Your problem is you are re initializing your Params class. In essence, you are creating two Params Objects and both have their own Vector, they are completely separate. You could solve this by making your vector static thus making the different instances have the same vector.
You create two difference instances of Params. Each of them has a different variable named _v.
To solve this problem You need to use only a single copy of Params or define _v as static.
Some tips not directly related to the question
Don't use Vector. The use of Vector is deprecated.
If you are not in a multithreading environment use an ArrayList, if you are in a multithreading environment use a synchronized List created with the synchronizedList method of Collections class.
Name your classes in uppercase.
Give readable names to your classes and variables.
Thanks so much for all the help! Wow I've never used this before and I was very pleased with the results. So I solved my problem, I basically just defined my Params once and pass it on to each class instead of recreating it.

Passing custom HashMap between activities in Android

I have a HashMap which takes in a String ID(ID of a chatroom) as a key and stores all the chats from that specific room in an arraylist as follow:
HashMap<String, ArrayList<ChatMessage>> chatHistoryHashMap = new HashMap<String, ArrayList<ChatMessage>>();
This is created in RoomActivity and I want to pass it to ChatActivity. How am I able to do this? I tried to make it a public static but using the "put" method in ChatActivity seems to do nothing, not sure why.
I also need this HashMap to be passed back to RoomActivity when the back button is pressed in ChatActivity.
Do I need to use Intents?
When you made anything static in your class then that variable is visible to all classes in that package so it cannot happen that you are not able to get the value in another activity.
To access the static variable you can either make th object of the class or you can directly access it by using function name.
You can also pass the object using intent.putExtra() and intent.getExtra()

Java: Getting object associated with enum

I have an ArrayList full of custom objects. I need to save this ArrayList to a Bundle and then retrieve it later.
Having failed with both Serializable and Parcelable, I'm now simply trying to somehow save the objects that are associated with the indexes in the ArrayList, then checking these when restoring the Bundle and adding the objects back in.
What I have is something like this:
When saving the Bundle:
//Create temporary array of the same length as my ArrayList
String [] tempStringArray = new String[myList.size()];
//Convert the enum to a string and save it in the temporary array
for (int i = 0; i<myList.size();i++){
tempStringArray [i] = myList.get(i).getType(); //returns the enum in string form
}
//Write this to the Bundle
bundle.putStringArray("List", tempStringArray);
So I now have an array of strings representing the enum types of the objects that were originally in the ArrayList.
So, when restoring the Bundle, what I'm trying is something like this:
//Temporary string array
String[] tempStringArray = savedState.getStringArray("List");
//Temporary enum array
ObjectType[] tempEnumArray = new ObjectType[tempStringArray.length];
for (int i = 0; i<tempStringArray.length;i++){
tempEnumArray[i]=ObjectType.valueOf(tempEnemies[i]);
}
So, now I have the enum type of each item that was originally in the ArrayList.
What I'm now trying to do now, is something like (would go inside the for loop above):
myList.add(tempEnumArray[i].ObjectTypeThisEnumRefersTo());
Obviously the "ObjectTypeThisEnumRefersTo()" method above doesn't exist but this is ultimately, what I'm trying to find out. Is this possible or perhaps there is some other way of doing this?
To get an enum value of the enum type Enemy from a string, use
Enemy.valueOf(String).
Enemy.valueOf("SPIDER") would return Enemy.SPIDER, provided your enum looks like
enum Enemy { SPIDER, BEE};
EDIT: It turns out Zippy also had a fixed set of Enemy objects, each mapped to each value of EnemyType, and needed a way to find an Enemy from a given EnemyType. My suggestion is to create a
HashMap<EnemyType, Enemy>
and put all the objects in there upon creation, then at deserialization convert strings to enum values and enum values to Enemy objects using the hashmap.
It later occurred to me though that depending on how much logic you have in Enemy, you might want to consider scrapping either Enemy or EnemyType and combine them into one parameterized enum, similar to the example with Planet over here:http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
That would spare you from having to go two steps from a string to your final object and simplify things a bit as you wouldn't need any hashmap after all.

Creating a deep copy method, Java

I want to make a deep copy method. I seeked help here the other day with this issue, but that was for a copy constructor. Now I need a regular method. I have the code created (nonworking), but I'm just not understanding it completely.
public GhostList deepCopy(){
int length=this.getLength();
GhostList jadeed=new GhostList();
Ghost[] data = new Ghost[length];
for (int i=0;i<this.getLength();i++){
data[i] = new Ghost();
data[i].setX(this.ghosts[i].getX());
data[i].setY(this.ghosts[i].getY());
data[i].setColor(this.ghosts[i].getColor());
data[i].setDirection(this.ghosts[i].getDirection());
}
return jadeed;
}
Now when I create a new GhostList named jadeed, and then under that I create a new data array of ghosts, does it know that data belongs to the jadeed GhostList? I dont see how the two can be associated, even though they should be.
Also, I'm not getting the lengths to match up for the copy and this.object. What is my problem?
You created a new GhostList and a new Ghost array.
You fill in the Ghost array and return the GhostList but the returned GhostList has nothing to do with the Ghost array.
You should add all the new ghosts to the GhostList
First, you mentioned a copy constructor. If you already have that working, then all you need to do in your deepCopy method is:
return new GhostList(this);
Let's forget that for now and get back to the code you posted. You are creating an array named data but you never used it anywhere. Aren't you supposed to assign this array to jadeed? Something like:
jadeed.ghosts = data;
And finally, instead of calling the method deepCopy, it would be better to call it clone and implement the Cloneable interface. Doing this allows everyone to know how to get a copy of your object using a standard interface.
Your GhostList class will have as its data member a reference to the array of Ghost. You've not shown us the class definition, so lets say that member is named foo. Now all you need to do is make the foo reference of the newly created jadeed object refer to the array of Ghost which you've created and populated. You can do it as:
jadeed.foo = data;
before you return jadeed.
If GhostList and everything it's composed of is Serializable, you can serialize the GhostList instance into a byte array and re-read it. It's a few lines of code, unless you use `Jakarta Commons Lang - one line of code:
http://commons.apache.org/lang/api-2.5/org/apache/commons/lang/SerializationUtils.html#clone%28java.io.Serializable%29

Decoupling - OOP

I have a simple question (working with Java). I have two classes, one represents a Document, a second represents a Word.
The Document class needs to know some info about the words that is kept in Word. My question is, what's the best way to decouple the two classes? I have 2 options in mind:
Have no connection between the classes, and each time I call a method in Document, I pass it an object of Word (so I have a third class with a main method that initiates
both Document and Word).
Declare a private object of Word inside Document.
One thing to note, I only have one object for Word and one for Document. I don't create a new object for every new document or word. I store a list of the entire documents in Document, and a list pf the entire words in Word.
Thanks!
I don't agree with your understanding of Decoupling. Decoupling is not just about which objects create other objects, it's also about which objects know about the behaviour of other objects and (crucially) what needs to change in (your example) Document if Word changes.
However, also I really don't understand what your mean by these two phrases:
I only have one object for Word and
one for Document. I don't create a new
object for every new document or word.
I store a list of the entire documents
in Document, and a list pf the entire
words in Word
Start from Document. What can objects of this class do? You seem to be saying that
class Document {
private List<??OfWhat??> allDocuments;
}
If class Document contains a List, what's it a List of? I think you need:
class Shelf {
private List<Document> allDocuments;
}
class Document{
private List<Word> wordInOneDocument;
}
class Word {
private String wordContents;
}
Now a Shelf could offer methods such as getRecentDocumets() findDocumentsContaining(String text)
and Document could contain getWordCount() and insertParagraph(List, START); and so on.
To have a better discussion we need to see a bit more of what you had in mind, a bit more about behaviour.
I do agree with your general thought that there is Something other than Document and Word out there. Something that can reasonably invoke methods such as createDocument() and insertParagraph()
From my point of view...
public class Document{
private List<Word> words = new ArrayList<Word>();
public void setWord(ArrayList<Word> words){this.words = words;}
public ArrayList<Word> getWord(return this.words;)
}
It's a reasonable approach. In this example you can create a Document without any Word's, which makes for an empty Document, which is valid.
You could still create a third class as you suggest, however, I don't see the benefit with it.
Your problem should be solved by composition. Thus having a List of Word seems to be a valid approach. By separating out Documents and Words, you have already achieved the required de-coupling. I do not get your exact point of de-coupling Document and Word objects.
Your question is
what's the best way to decouple the two classes? I have 2 options in mind:
Neither option satisfies your request. If they are going to work together, then they are going to be coupled. The only thing is how tight or loose the coupling is.
Both of your options sound like tight coupling. A form of looser coupling would be to store an interface reference and take it in on a constructor or setter method.
If you want to decouple the classes, one standard way is to use an interface:
public interface IWord {
...
}
public class Word implements IWord {
...
}
public class Document {
public boolean append(IWord word) { ... }
...
}
This way both Class and Word depend on IWord, but neither class nor Word depends on the other. This is known as Dependency Inversion.
Well first of all I think you're naming your classes incorrectly.
I don't create a new object for every new document or word. I store a list of the entire documents in Document, and a list pf the entire words in Word.
Judging by what you said here you have something like this:
public class Words {
private List<Word> = new ArrayList<Word>;
// getters+setters
}
public class Documents {
private List<Document> = new ArrayList<Document>;
// getters+setters
}
And you want to use the Words class in the Documents. If you want to do that, that means you can't decouple it (as it's against the very definition of the word "decouple"). I'm guessing here again, but I think you want to code it so you can change the implementation of the Documents class so in the future it could use another class like for example BetterWords.
In order to do that I would create either an abstract class or an interface (depending on the rest of your architecture) and then make the Words class either extend it or implement. Then you can do something like this:
public class Documents {
private List<Document> = new ArrayList<Document>;
private IWords wordsInterface = new Words(); //in case you want to make an interface
private AbstractWords wordsAbstract = new Words(); //in case you want to make an abstract class
// getters+setters
}
Or you can put it in the Document class (the words), don't really know where you want them.

Categories

Resources