Search code examples
androidandroid-install-apk

Static Keyword , Reinstallation Required


In my application I have an Activity" Model" in which i get a value 'n' from an edit text , I have declared this value n as static int . So , that i can access it inside any class of the Application.

The problem is that when I restart my application without reinstalling it , the value of 'n' remains the same as it was in the first case . And this affects my output.

I cannot use intent to send values because , the value is accessed randomly in the application even in classes that are not activities.

Can u please tell , where I m wrong.??

package com.integrated.mpr;

import java.io.File;

import android.app.Activity;
import android.app.Dialog;

import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class Model extends Activity implements OnClickListener{



    EditText etPos;
    Button bmodel;


    static int n;//static variable to be used in other classes


    File folder ;
    File subfolder;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.inputpage);


        etPos = (EditText) findViewById(R.id.etpos);
        bmodel = (Button) findViewById(R.id.bModel);

        bmodel.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch(v.getId()){
        case R.id.bModel:


            String check = etPos.getText().toString();

            String check1 = etNs.getText().toString();
            n = Integer.parseInt(check);
            Intent openAlternative = new Intent("com.integrated.mpr.ALTERNATIVE");
            startActivity(openAlternative);


            break;
        }

    }
}

If i first install my app , and enter value in the edittext as 2 , the value of n =2 ; If second time i run my app without installing it , even if i enter 3 in the edittext , value of n remains 2 Where is the twist??


Solution

  • Kumar,

    The behavior you are seeing is the result of using a static member. static members do not require an instance and are therefore set upon first access (regardless of whether an instance was created or not) and stays in memory until Android decides it is no longer valid. In essence, it is doing exactly what it was supposed to. The proper use of static variables is a topic of extensive discussion among veteran and novice programmers alike, but essentially always leads to "be choosy about where and how you use static members".

    That said, your need to access this from another component is a common problem, however, and there are a number of ways to solve it. If you need to have each instance have a different value, then it should not be static. Instead you will have to find a way to pass the instance of the Activity.

    If each instance need not be different, but the value need to change according to some other parameter, simply find the appropriate place to change the value. If you can access it from anywhere in your application, you may also change it from anywhere in your application.

    Solution 1: Passing by Intent

    This solution is useful when the information is subject to change and must be sent to another component and the classes that it uses exlusively. You may pass virtually any value via an Intent extra.

    openAlternative.putExtra("MyValue", Integer.parseInt(check));
    

    In your responding component, you may retrieve the value by:

    Intent myIntent = getIntent();
    int n = myIntent.getIntExtra("MyValue", 0); //0 is the default if no value is sent.
    

    From here, you may easily pass the retrieved value to any class being utilized by that component. An example:

    MyClass.setN(n);
    

    Solution 2: Storing outside of the LifeCycle

    A safer alternative is to move the value to an extended Application. This is not subject to UI or LifeCycle processing.

    public class MyApplication extends Application
    {
        static int n;
    }
    

    Adjust your AndroidManifest.xml...

    <application android:name=".MyApplication" ... >
        <!-- All of your components -->
    </application>
    

    Now, you can set the variable this way:

    MyApplication.n = Integer.parseInt();
    

    And you can get it by

    int myN = MyApplication.n;
    

    This solution has gotten me through many a troubled day. However, it should really be used for non-instance related data.

    Solution 3: The REALLY UNSAFE method

    This solution only works if you can guarantee a single instance of the component. This requires that singleTask is set. Be very careful with this

    Change n to non-static

    int n;
    

    Change Activity to Singleton

    static private Model myInstance;
    

    In OnCreate, set myInstance

    myInstance = this;
    

    Create a getter:

    static public Model getStaticInstance()
    {   
        return myInstance;
    }
    

    This is unreliable (at best) and can cause huge memory leaks if not managed correctly.

    Hope this helps,

    FuzzicalLogic