So, lets say in my main activity, i have an array declared like this, that im not having any problems using inside any of main's methods:
public int currentPrices[] = {0,0,0,0,0,0,0,0,0};
Now, my buyDialog class is as follows:
package foosh.Frontier;
import android.app.Activity;
import android.os.Bundle;
import foosh.Frontier.*;
public class buyDialog extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// Be sure to call the super class.
super.onCreate(savedInstanceState);
currentPrices[0]=999;
//insert setup magic here
setContentView(R.layout.buydialog);
} }
Eclipse persistently says that currentPrices can't be resolved. How do I link a child activity to the parent activity's variables?
I may have done my intent wrong, as I'm quite new at constructing them. But here's that line, from main:
case R.id.buyButton1:
currentRes = masterRes.get(0);
Intent intent = new Intent();
intent.setClass(main.this, buyDialog.class);
startActivity(intent);
The simple answer is you have to qualify it with the containing instance's name.
So if the instance is myinstance to access the currentPrices field, you would do this:
myinstance.currentPrices
However, you really should be using getters and setters and there are a lot more issues here regarding actually getting a handle on the instance of the activity. I would suggest looking into an intro Java book before you get your hands dirty with Android. Check out http://math.hws.edu/javanotes/ for a good online introduction.
Based on your tag, I assume you have some notion of global variables. There is no such thing in Java. In practice, you can have static variables that are globally accessible. For instance
public class MyClass{
public static int MY_VALUE = 4;
}
You can access by writing
MyClass.MY_VALUE
However, with instance variables, that is, one's that aren't qualified by the static keyword, you have have an instance of the class that has been allocated via the new keyword.
For example
MyClass someInstance = new MyClass();
someInstance.currentPrices
The reason this is more complicated with Activities is because you don't have access to the instance of the activity class that is being used unless you do something really creative.
Does that make sense?
If you ever need to do this without making a static variable, you can also pass the array through the Intent as an extra, like so:
intent.putExtra("currentPrices", currentPrices);
startActivity(intent);
Then, once you're in the new Activity, retrieve it like so:
int[] currentPrices = getIntent().getIntArrayExtra("currentPrices");
It looks like you're modifying the original from the dialog though, so short of using startActivityForResult() and handling it that way, Chris' method is much simpler.
Related
I'm in the process of completely redesigning my Android app. Before, EVERYTHING was in the same class.
So I tried to redraw everything so that the code is clearer apart Admob than the doc advice to put in the Main thread, I separate the different part of my code in class. So I used two technique: I created a songleton that contains variables that I want to have access to constantly,and I call my classes via weak reference.
Here is what it looks like:
For example, the UIManager class that needs to update the game's IU have a weak reference looks like this:
private static SoftReference<UIManager> ManageUI;
static{ManageUI= new SoftReference<>(null);}
static UIManager get()
{
if(ManageUI.get()==null)
{
ManageUI= new SoftReference<>(new UIManager());
}
return ManageUI.get();
}
GameManager Manager=GameManager.getInstance();
to be able to use the findviewbyid for example I place in method argument the main class that is the mainthread
the singleton that contains all my variables that I want to have permanent access to looks like this:
private GameManager()
{}
/** Holder */
private static class Manager
{
/** Instance unique non préinitialisée */
private final static GameManager instance = new GameManager();
}
/** Point d'accès pour l'instance unique du singleton */
public static GameManager getInstance()
{
return Manager.instance;
}
To separate all in different class, I pass argument to my method so I can call au stuff belong to Activity like that:
(My main class is called GamePlay)
void OpenGlobalScene(GamePlay activity)
{
Manager.OnTitle=false;
if (!checkLayout(activity,R.id.globalscene)) {
LayoutInflater(activity,9, true);
LinearLayout GamePlan = (LinearLayout) activity.findViewById(R.id.globalscene);
GamePlan.setAlpha(Manager.AlphaBord);
}
}
For now, I have not noticed any problems except a few slownesses on old android phone 4.4.2.
Also compared to my old code were EVERYTHING was in the same class, it's much easier to change pieces of code (going to the inapp billing V3 was simpler since everything was in one class that I call like the others with weak referencre)
My questions are:
-What are the problems that such a structure might pose?
I had also chosen that structure to not load or leave in memory things that are not useful
-How are chance that Android will erase from memory an action in progress called with weak reference?
-As you can see I pass the activity has argument to the method, sometimes I pass it from a method to another. Is that fact can cause some trouble?
Thank you for your help.
Check Dagger2 is better than the clasic singleton https://developer.android.com/training/dependency-injection/dagger-android?hl=es-419
thanks for your answer and your tips. I'am gonna check this out.
Anyone else know something about consequences on memory when using weak references ?
I have more than 50+ activities in a single project so each and every time I need to write code to move a single activity from one to other.
What is in my mind, may I make a single function which can move more than one activity from a single static method of a class?
Like given in code below.
public static void moveActivity(Parameters)
{
//Code to move activity
}
Or may I follow any other idea for the same.
Any help would be really appreciated.
Thanks in advance.
What is in my mind, may I make a single function which can move more than one activity from a single static method of a class?
I believe not because startActivity needs a Context which can't be used in a static context, I believe.
Or may I follow any other idea for the same.
This depends on what you are doing but maybe ViewPager and/or Fragments could make your life easier. If you have that many Activities then most likely you won't want to try and manage them all from one function anyway because you have to consider extras, flags, etc... You will have two lines to start an Activity (sometimes more) just write the code. What you are trying to do will most likely result in more headaches, IMHO.
If there is a lot of the same data that you are passing around and that is your concern then you can use Bundles to pass them all around.
Try this:
public class Utils {
public static void launchActivity(
Class<? extends Activity> nextActivityClass,
Activity currentActivity, Map<String, Integer> extrasMap) {
Intent launchIntent = new Intent(currentActivity, nextActivityClass);
if (extrasMap != null && extrasMap.size() > 0) {
Set<String> keys = extrasMap.keySet();
for (String key : keys) {
launchIntent.putExtra(key, extrasMap.get(key));
}
}
launchIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
currentActivity.startActivity(launchIntent);
}
}
To use it:
From your activity class, make this call:
Utils.launchActivity(ActivityB.class, this, extrasMap);
How do you pass an object between views in an android application. I have googled and found that your class needs to implement the appropriate interface. How though do we do it if we do not own the class/object type we are passing (for example from an external library or a random class within the sdk)
I need to pass a HtmlSelect item object (from HtmlUnit open source project) to another class to process it but I cant bundle it up.
Thanks
My best guess is you create a static helper object and pass it like that.
HelperObject class {
static HtmlSelect myHtmlObject
}
source activity:
HelperObject.myHtmlObject = currentHtlmlObject;
startActivity(intent);
Destination activity:
onCreate() {
HtmlSelect htmlSelect = "create a copy copy of HelperObject.myHtmlObject not to have problems and then set it to null"
}
Just use the putExtra() method of your Intent to pass parameters.
At times you need to first "deconstruct" your object into simple elements (Strings, Integers) and then reconstitute it at the other end with getExtras().
Is something wrong with this construct in Android?
class A extends Activity {
private Object myObject = new Object();
#Override
protected void onCreate(Bundle savedInstanceState) {
//myObject = new Object();
}
}
Because at some point(s) later I get (sometimes, not reproducible yet) exceptions because myObject is null. I don't know if it's because I have to initialize in onCreate.
Edit: Additional details:
The actual class of myObject is List<Object> (Where Object is a domain specific type)
At some point later in the activity I'm storing myObject as a static field of a "Parameter passer" class and starting other Activity (because I'm avoiding to implement Parcelable. If this is good or bad practice should not be discussed here, unless that's causing my error). In the other Activity I pick up myObject. There it's (sometimes) null.
Edit 2: I don't understand why this object becomes null if I'm storing a reference to it as static field of my parameter passer class (a standalone, dedicated class). That's how garbage collection works, right, it just removes when the objects are not referenced anymore. So since I have a static reference this object should not be removed. According to this thoughts, if they are correct, the problem should be somewhere else.
When you start a new activity your old one goes on the block for possible garbage collection (including any classes instantiated in it, including your parameter passer class), so your object is not necessarily going to be available (which is why you see an intermittent failure.).
I see two option:
1) Pass it along in the bundle with your intent that starts the new activity. As you were trying to avoid this, probably not your best choice.
2) Extend the Application class and store the object in there.
EDIT
I think the accepted answer to this SO Question might fix your issue (and explain what is actually happening).
No. That code is just fine. You can create objects in the constructor.
You may want to check a previous question about it Instance variable initialization in java and the section 3.2.4. Field Defaults and Initializers which basically states that the first case:
private Object myObject = new Object();
is identical to an initialization in the class constructor. (NOTICE onCreate is NOT the constructor).
So, myObject should never be null, except in the case the "new Object()" instruction failed, generating an exception.
Isn't this possible your code is changing the contents of myObject later on the code?
I have lots of Activities chained together with Intents and some Intents require parameters passed in the extras Bundle. When I have to forward parameters through multiple Activities, should I copy each one explicitly or is there a best-practice way of doing it? For instance, I could clone-copy the current Intent as a starting point for calling other subtask Intents, and this would (presumably) copy all previous Bundle parameters.
As an illustration, say you have a file explorer Activity that is in one of two modes: Expert and Novice. You want to pass this state to some subtask Activity like a file properties page, which you could do by calling putExtra("skillLevel", "Expert") on the Intent before you launch it. Now if the property page also has a subtask Activity, compression options for instance, how should you forward on the "skillLevel" parameter?
I dont know why you would want to copy all the other properties using a constructor.
newIntent.putExtras(oldIntent);
Should do the trick.
I think the best and cleaner way to do it is to initialize the next Intent using the received Intent through the Intent(Intent) constructor.
Intent newIntent = new Intent(receivedIntent);
If a parameter is system wide, it may be easier to store it in Shared Preferences until it is changed (such as difficulty of a game). It would have the side effect of remembering the set difficulty when the user leaves the app.
Since we don't have Global variables in Android you can create a class with your application wide informations and use the Singleton pattern . Since it will be changed for all the system, this way you can always get the same instance of this object, hence always the same information.
An example:
public class Object {
private static Object instance;
private Object objectcall;
private Object(){
}
public void setObject(Object newObject){
this.objectcall = newObject;
}
public Object getObject(){
return this.objectcall;
}
public static synchronized Object getInstance(){
if(instance==null){
instance=new Object();
}
return instance;
}
}
when you want to retrieve it in a Activity just call
Object objectSingleton = Object.getInstance();