Apologize :-
due to my mistake, because last time i didn't asked this Question properly and that's why most of the answers posted below are related to "this" keyword and that's the reason i got that much down votes. So i updated this Question, because i don't want to misguide anyone.
.
EDIT-1 :
Question-1 My question was that why we pass "this" (Object of current class or MainActivity) twice in the GestureDetectorCompact() Constructor
new GestureDetectorCompat(this,this);
Rest of the block of code is given below,
public class MainActivity extends ActionBarActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
protected void onCreate(){
private GestureDetectorCompat gestureDetector;
this.gestureDetector = new GestureDetectorCompat(this,this);
gestureDetector.setOnDoubleTapListener(this);
}
}
EDIT-2 : for quite close answer you can click at following link
EpicPandaForce
's answer is very close to my question and it is helpful as well.
The this keyword, which exists in many OOP languages, is a reference to the current instance of the object in which you are contained in memory..
Your example:
this.gestureDetector = new GestureDetectorCompat(this,this);
You are basically saying:
This instance - access gestureDetector is equal to a new instance of GestureDetectorCompat that is constructed with 2 paramaters, in this case, both of them references to this instance of MainActivity.
As people are saying, this is a fundamental principal and it may be more beneficial for you to start with building a strong foundation in Java before moving on to Android.
If you want to understand this, probably you should read this.
Android is a Java based platform and a good Java/OOP knowledge is required in order to make (native) apps.
I strongly suggest you to read at least one Java/OOP book/tutorial. Some good examples are:
Bruce Eckel, Thinking in Java (a great classic)
Oracle Java Tutorial
Object Oriented Programming on Wikibooks (no specific language)
Good learning!
public class MainActivity
extends
ActionBarActivity
implements
GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener {
private Context context;
private GestureDetector.OnGestureListener onGestureListener;
private GestureDetector.OnDoubleTapListener onDoubleTapListener;
private GestureDetector gestureDetector;
protected void onCreate(Bundle saveInstanceState){
super.onCreate(saveInstanceState);
this.context = this; //mainActvity instance as a context
this.onGestureListener = this; //mainActvity instance as GestureDetector.OnGestureListener
this.onDoubleTapListener = this; //mainActvity instance as GestureDetector.OnDoubleTapListener
//the gesture detector of this activity instance
this.gestureDetector = new GestureDetectorCompat(context, onGestureListener);
//activity as context
//activity as onGestureListener
gestureDetector.setOnDoubleTapListener(onDoubleTapListener);
//activity as double tap listener
}
}
For more information, read about the constructor of GestureDetectorCompat here
Here,
this.gestureDetector = new GestureDetectorCompat(this,this);
the first "this" is referring the 'context' and second "this" is referring to the 'listener'.
You can have a look on this,
public GestureDetectorCompat(Context context, OnGestureListener listener) {
this(context, listener, null);
}
GestureDetectorCompat is the constructor in which we are passing the two "this" keywords, meaning first is context(which refers to the object of current class) and the second one is the listener.
Definition of GestureDetectorCompat constructor is,
GestureDetectorCompat(GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener) { }
So There is need of 2 arguments to call this function. In your case MainActivity is implementing both the Listener interfaces, that's why you need to pass the same reference in both the arguments to handle the callbacks respective to both the interfaces.
In some other implementation, both the interfaces can be handled separately too.
this
Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
Over here this refers to current Activity called MainActivity
Related
I am creating a Listener class that a couple instances of a custom button in different Activities/Fragments are using. This class has listener methods that will update the respective ViewModel for that Activity/Fragment.
How do you define a ViewModel in a non-activity/fragment class? The documentation says to implement ViewModelStoreOwner, but I'm not really sure on how and what I should be implementing. I'm assuming if I don't implement it correctly, I'll have some sort of memory leak...
public class Listeners implements View.OnClickListener, ViewModelStoreOwner {
#NonNull
#org.jetbrains.annotations.NotNull
#Override
public ViewModelStore getViewModelStore() {
return // what do I do here, and how do I tell it to close the scope appropriately
// when the context is destroyed?
}
// Implement OnClick...
}
Am I just trying to abstract too much here? Does Android really just revolve around Activities and Fragments thus requiring me to have annoyingly long files? The above class is my attempt to reduce redundant implementations of a button listener between two activity/fragments
EDIT:
Is it wrong to just pass the store owner of the activity that this listener instance will eventually reside in? For example:
// Custom class constructor
public Listeners(ViewModelStoreOwner storeOwner) {
mModel = new ViewModelProvider(storeOwner).get(Model.class);
}
// Calling/parent activity/fragment/context
Listeners listeners = new Listeners(this);
mButton.setOnClickListener(listeners);
Unless someone posts an answer to this that says otherwise (and that this is a bad idea), I ended up utilizing the latter solution I updated my question with.
I passed the store owner into the custom Listener class as a parameter, then used this value to initialize my ViewModelProvider inside the custom class.
I believe this is safe, since the class is instantiated within the scope of that parent Fragment/Activity anyway.
So for instance, if you were calling this class from an activity/fragment:
// Calling from Activity
Listeners listeners = new Listeners(this);
// Calling from Fragment
Listeners listeners = new Listeners(requireActivity());
And the relevant class definition:
public Listeners(ViewModelStoreOwner storeOwner) {
mModel = new ViewModelProvider(storeOwner).get(Model.class);
}
Hi I am kind of new to android, still learning. And my problem is that, for example I have a method which was created in the MainActivity and I need to call it from another class.
Is it a good practice to get the instance of the MainActivity so that I may be able to call the method in the MainActivity from another class?
This is an example:
public class MainActivity extends AppCompatActivity {
private static MainActivity inst;
public static MainActivity instances()
{
return inst;
}
#Override
public void onStart() {
super.onStart();
inst = this;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void showToast (String text){
Toast.makeText(inst, text, Toast.LENGTH_SHORT).show();
}
Then this is the other class:
public class broadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
MainActivity instance = new MainActivity();
instance.showToast(AnyText);
}
}
I saw this type of coding while looking at tutorials and wondered if it's a good practice or maybe there might be a better way? Since I get the warning of Do not place Android Context Classes in static classes
Thanks in advance for any insight or help! :D
I guess You want to make A singleton of Activity Class
but as Mention in All Pattern Design
using Singleton
If and Only If its only way to Make A Global Variable
Singleton is based on Lazing Initialing and Load On Memory
so I guess If you cant to Interact With Activiy You can Use
BroadCast Or Intents
You can call method from another class like this:
MainActivity instance = new MainActivity();
String data = instance.data();
and create data method in that class:
public String data() {
return mangaId;
}
Is it a good practice to get the instance of the MainActivity so that
I may be able to call the method in the MainActivity from another
class?
You totally can do this but you don't need to make it static and use a constructor. Just create a new instance like follows and you'll access the public methods
MainActivity mainActivity = new MainActivity();
mainActivity.showToast(text);
About the warning
It suggests avoiding having context fields defined as static. The warning itself explains why: It's a memory leak. If you make it static it will be accessible anywhere in your app and some methods can hold the reference to this context for a really long time and it won't be garbage collected. It will lead to a outofmemory exception and the app could crash. But here you're trying to invoke showToast() from broadcastreceiver so you can just get rid of static references. And it you need them in the future you safe ways to inject context
You cannot create instances of an Activity using the new operator.
You have to use an Intent to let an Activity to be created.
So you cannot get a reference to an instance of your activity.
The only methods you can use of your activity class are static ones.
In the docs, it says I should make the new class like this:
class MyView extends GLSurfaceView {
public MyView(Context context) {
super(context);
setRenderer(renderer);
}
}
Now I tried to re-do that in Scala:
class BaseGameActivity extends Activity {
object glview extends GLSurfaceView(this) {
setRenderer(renderer)
setEGLContextClientVersion(2)
}
}
However, the App crashes now with the exception "java.lang.IllegalStateException: setRenderer already called for this instance". I suspect this has to do with the way Scala calls the super-constructor.
I've tried to find out how to override the constructor in the way the docs describe, but couldn't find it. I'd appreciate any hint.
It seems to me that your are propagating the call to a different constructor from the base class. You are passing a reference to this instead of a reference to the Context object. It might be that this other constructor is calling setRenderer.
Could you try to create an inner class MyGLView like this:
class MyGLView(ctx: Context) extends GLSurfaceView(ctx) {
setRenderer(renderer)
}
And see what happens?
The problem is that object does not allow arguments to its constructor. Top-level objects must be initializable without any arguments (nobody calls their ctors). In your case you have an inner object, which can reference the members of the surrounding class instance. If you really need an inner object in your Activity class, you could do:
object glview extends GLSurfaceView(ctx) {
setRenderer(renderer)
}
where ctx is a member of the surrounding class.
In java likewise in scala constructors are not inherited.
So you can not override thing, you didnt inherit. And you should use one of existing constructors for base class. If all of them are calling setRenderer(renderer) it will be called during constructing super object and you obviously should not call it second time in a subtype constructor ( wheither it class, object or mixing-in trait ).
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..