I am creating a android library, that need to get the layout informations from Activities in background. So this is what I have done :
1) called the library in onPause() for an Activity:
Mylibrary.start(this)
2) Inside the library, i am passing this context to create a static object of a different class. like
private static DiffClass myClass;
..........
public void start(Activity activity)
{
myClass = new DiffClass(activity);
}
3) Next in onPause() of the activity, I am calling sdk to mark this object as null to avoid memory leak problem . like :
MyLibrary.stop() //inside onPause() of the Activity
and inside the sdk :
public void stop(){
myClass =null; //making the object holding activity reference null
}
Is this the best approach ? Because I don't want the application context and also I need the activity context for a static class outside activity?
Related
I have defined a function in MainActivity now I want to access the function from another class in my app. I have created an object of the MainActivity and with that object I have called the function. Although there is no error, it's not executing. Every time I try to execute, the app crashes.
Activity A should have a variable
static ActivityA activityA;
In onCreate state:
activityA = this;
and add this method:
public static ActivityA getInstance(){
return activityA;
}
In activity B, call
ActivityA.getInstance().myFunction(); //call myFunction using activityA
You cannot just create objects of Activities by using:
MyActivity activity = new MyActivity();
as you would with normal Java classes. All Activities in Android must go through the Activity lifecycle so that they have a valid context attached to them.
By treating an Activity as a normal Java class, you end up with a null context. As most methods in an Activity are called on its Context, you will get a null pointer exception, which is why your app crashes.
Instead, move all such methods which need to be called from other classes into a Utility class which accepts a valid context in its constructor, and then use that context in the methods to do the work.
Make the variable public and then create object in adapter like this:
public int i; // Variable in Activity class
((ActivityName) context).i // accessing in adapter
I have a problem about setting a TextView from a class which is not a child class of Activity. This class is basically used for handling registration and REST request with 3rd party server.
After getting textfield info from 3rd Party server, it is too late to set TextView in the Main Activity.
I can't use SharedPreferences to set this info, because MainActivity has already started.
I can't pass this info with Bundle since my java class is not an activity class.
How can I pass this info and set the TextView in the MainActivity? Is there any way to do this?
The proper way of doing this this is to create a listener.
Create an interface :
public interface OperationCompletedListener{
void onOperationCompleted(String resultValue);
}
Then in your class which calls Rest services, create a variable for this listener and a method to set it.
private OperationCompletedListener mListener;
public void setOperationCompletedListener(OperationCompletedListener listener){
mListener=listener;
}
Then when the your rest service completed call like below :
if(mListener!=null){
mListener.onOperationCompleted("your value to be passed");
}
Then in your activity class which contains the TextView, create an object of OperationCompletedListener and set it to the other class using the set method that we created earlier. Then in the onOperationCompleted method, set the text view with your value and you are done.
private OperationCompletedListener mOperationCompletedListener=new OperationCompletedListener() {
#Override
public void onOperationCompleted(String resultValue) {
yourTextView.setText(resultValue);
}
};
restServiceClassObject.setOperationCompletedListener(mOperationCompletedListener);
You can create an static method which update textview in your activity class . Then call this method from your other class whenever you want.
Try to pass the Activity to the non-Activity class when you instantiate it. For example:
public class NonActivityClass {
private Activity parentActivity;
public NonActivity(Activity parentActivity) {
this.parentActivity = parentActivity;
}
}
Or you can just pass the Activity to a static method in your NonActivityClass if you don't want to instantiate it (it's abstract). Then, you can inflate the TextView or do a findViewById from the parent and set the text.
From my experience, you should never use a static non-final variable to maintain a reference across activities. When you restart the app or the phone, or when Android kills your app's process, the reference and state of the variable becomes lost and may cause your app to crash.
i have an Android application in which i use a class to store static data among activities, something like:
class Global
{
private static boolean mInitialized = false;
private static String mData = null;
public static void init()
{
mData = "something";
mInitialized = true;
}
public static boolean isInitialized()
{
return mInitialized;
}
public static String getData()
{
return mData;
}
}
So in the main activity onCreate i do:
if( Global.isInitialized() == false )
Global.init();
And then starts other activities, the action flow is:
MainActivity -> ActionActivity -> PluginActivity
Where Main is where i init the Global class, and Action & Plugin is where i use the getData() method of that class.
Now in some cases, i get really strange behaviour ... if something unepected happens in PluginActivity ( NullPointerException for instance ), the activity crashes and the application goes back to the ActionActivity which launched it, but, at this point, during the onCreate of the ActionActivity ( where the Global class is supposed to be initialized ) i get an exception because the getData() returns null ( and isInitialized() is false ) as the Global class was never initialized by the MainActivity.
So, can an object with static members like my Global class be deallocated/cleared/whatever if something like an unexpected exception occurs ?
In general, activities should be independent of each other. You should not depend on them being launched in any particular order, or at all.
Instead, if you need to share global state data between activities, i.e. not just parameter passing in intent extras or results via onActivityResult(), subclass Application, put the init code in its onCreate() and access it from activities using getApplication(). Also remember to declare the application class in your manifest. The system takes care that the application object is there when any of your activities are running.
In Android, whenever application crashes the static variable will be discarded. This is the reason why you are getting NullPointerException. Instead of making the object static create a Parcelable or Serializable class and get and set the fields and then pass that object with the intent. In another activity you can get that Parcelable or Serializable class and you can use its property.
I am trying to call this method:
public static void trackFunXStartActivity(Activity a)
{
s.startFunXActivity(a);
}
I'm trying to call it using this code in my LayoutsActivity.java:
public void onStart() {
TrackFunX.trackFunXStartActivity(LayoutsActivity);
}
but I'm not sure how to create or reference the Activity that I can pass to trackFunXStartActivity(Activity a). I don't think I can pass LayoutsActivity as an Activity.
How do I go about instantiating or reference an activity in LayoutsActivity.java to pass to trackFunXStartActivity.
I'm a Android newbie and have done some searches on StackOverflow but didn't see anything to help with this questions.
Thanks
take a static context for the LayoutsActivity like
static Context context;
and in the oncreate method use
context = LayoutsActivity.this
and finally you can use this context in the class where you need
After read this topic avoiding memory leaks some doubts arouse.
If I need to use an activity context (example: inflate a view in a PopupWindow class to show a popup) how can I hold the context of actual activity to do it? If I need to avoid a static context reference the only way to do it is creating an attribute in my class? And all the other classes I'll need the actual activity context I need to do it?
update-
I want to use this actual activity context in many classes that don't inherited Context, like I use with the application Context in my Application class that has a static method called getApplicationContext() declared. This method follows the Singleton Design Pattern and works fine.
Working from the code you linked in the comments, why not do this:
//my main activity
public class ExampleStaticReferenceActivity extends Activity {
//...
public void methodCalledWhenUserPressesButton(){
LinearLayout masterLayout = (LinearLayout) findViewById(R.id.masterLayout);
//now passing a reference to the current activity - elevine
masterLayout.addView(ButtonCreator.createButton(this));
}
}
//this class is in another package
public class ButtonCreator {
//added a Context parameter - elevine
public static Button createButton(Context context) {
Button button;
button = new Button(context);
//... some configurations for button
return button;
}
}
That will crash your Application since Your Activity will be killed by OS when it runs out of Resources thus Context will also be null.. And its meaningless to give A background Activities Instance when you want to show pop up in the Foreground Activity.. What the Blog says is avoid passing activity.this where even getApplicationContext() can do the job..