Can I create an object of an Activity in other class? - android

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

Related

How to update view in a method in called from another class?

In class A a have a method that updates a view.
First I called Class b to download some data, once the data is recieved I call the method in class A.
When the view is updated (when the method is called from class b) the view is throws NPE.
However if the view is updated (when called from its native class (class A)) it works perfectly.
Class A is an activity.
In some cases it reported there is some sort of context problem.
I have tried implementing an interface however even that threw an NPE
How can I fix this problem?
public class A extends activity {
public() {
}
B b = new B();
b.doSomething();
public void myMethod(String string) {
textView.setText(string)
}
}
public class B {
public void doSomething() {
String data = getData;
A a = new A();
a.myMethod(data)
}
}
You should not call new A(). This will not invoke a new Activity with the application lifecycle, and will not provide you a reference to the original Activity that contains the View you are trying to update.
I would recommend A should implement a simple interface YourInterface that contains a void callbackMethod(String data);.
Pass your object A (as this) into B, such as on doSomething(this), changing the signature of doSomething to doSomething(YourInterface callback).
In B you may then call callback.callbackMethod(data), processing data within your Activity A.

Passing Activity context to android Library - Is this the right approach?

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?

How to set a TextView from another class (not extending to Activity.class)

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.

Android app and static storage between activities

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.

Call Activity Method From Fragment

I'm dealing with fragments.
I have an Activity and different fragments.
Each fragment need the access to a Class(call it X) that allow it to access a database, but, because I have a lot of fragments, I don't want to create a different instance of the Class X in every fragment as I think it will require lots of memory.
So how can I do?
I wrote something like this (with a getter), but it doesn't work!
public class MyActivity {
private ClassX classx;
.....
public ClassX getClassX() {
return classx;
}
.....
}
But than, how can I call it from the fragment?
From the fragment call your activity's method
((MyActivity ) getActivity()).getClassX() ;
This is a little bit more of a Java question and android.
If you looking at accessing the database, look at creating a database singleton.
So something like:
public class Database {
// This starts off null
private static Database mInstance;
/**
* Singleton method, will return the same object each time.
*/
public static final Database getInstance() {
// First time this method is called by Database.getInstance() from anywhere
// in your App. It will create this Object once.
if(mInstance == null) mInstance = new Database();
// Returns the created object from a statically assigned field so its never
// destroyed until you do it manually.
return mInstance;
}
//Private constructor to stop you from creating this object by accident
private Database(){
//Init db object
}
}
So then from your fragments and activities you can then place the following field in your class's (Better use use a base activity and fragment to save you repeating code).
public abstract class BaseFragment extends Fragment {
protected final Database mDatabase = Database.getInstance();
}
Then your concrete fragments can extend your BaseFragment e.g. SearchListFragment extends BaseFragment
Hope this helps.
Worth reading about singletons and database
Regards,
Chris
Define an interface called Callbacks (or something else if you want). In it, have a public method called getClassX(). Then make your Activity implement the Callbacks interface.
In your Fragments, in onAttach, store a reference to a Callbacks object (i.e. your activity via something like:
if(activity instanceof Callbacks)
mCallbacks = (Callbacks)activity;
This will guarantee that the Fragments are able to call the function. (in case you want to reuse the fragments later in another app)
Then in your Activity, in onCreate(), create an instance of ClassX. In your getClassX() method, just return a reference to it.
When you want a reference to it from your Fragments, call mCallbacks.getClassX() and you should be sorted.
You can use a static object in your activity, and use it from the fragment, or call the getActivity() method in your fragment to access the whole activity objects/methods

Categories

Resources