How to "call" this correctly?

Asked

Viewed 422 times

8

When the Elements are inside the onCreate, use the (this) it’s very easy...

Example 1 : that works from within onCreate itself

protected void onCreate(Bundle savedInstanceState) {

Spinner spinner = (Spinner) findViewById(R.id.memo_confirmation_spinner);
    spinner.setOnItemSelectedListener(this);
}

Example 2: Another class

Already if I put it in a function (outside the onCreate), the thing changes and the following function does not work. The compiler does not accept this this because he doesn’t find the onCreate:

public class JSONOAsyncTask extends AsyncTask<String, Void, Boolean> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Boolean doInBackground(String... urls) {
        try {
            Log.e("****** MESSAGE ******", " Json Object  = " + JSONParser.getJSONFromUrl( URL ).get("ReportDetailTextList"));

            Spinner spinner = (Spinner) findViewById(R.id.memo_confirmation_spinner);
            spinner.setOnItemSelectedListener(this);  // NESTE EXEMPLO, ESTA DANDO ERRO NESTE THIS
        }
        catch (Exception e) {}
    }
}

That is, in Example 2 Android Studio no longer accepts this.

What is the **correct way to write the latter this(for Example 2)?

  • this refers to the instance of the class itself. When you say it doesn’t work, what exactly do you mean? You can improve the issue to make it clearer?

  • Maybe it’ll help Reserved word "this". Is there an error/Exception? or is it an unexpected result? Android Studio provides some hint (on the line as a problem)?

  • it is not clear what is your doubt... what is the error?

  • I edited the question, I hope it was clear... call this off on create, it’s not working........

  • @ldeoliveira, answering your question, when I use the second example, ie a function outside the "onCreate", the android does not let continue.. just like that! he underlines all that red line!

6 answers

11


The first factor to note in this situation is that to call the method setOnItemSelectedListener() requires the implementation of the interfaceAdapterView.onItemSelectedListener in the class. An example:

public class JSONOAsyncTask 
    extends AsyncTask<String, Void, Boolean> 
    implements  AdapterView.OnItemSelectedListener{
    ...

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
}

Another factor is that one should explore more the AsyncTask. This class provides some Features interesting: onPreExecute() and onPostExecute(). These methods serve to define some action we wish to perform before the asynchronous task and what we wish to do after the task is completed.

Let’s go to the this

First you should know, like any programming language, that there are some reserved words. In JAVA, it has the this and the super, respectively the instructions this() and super().

Keywords are divided into categories according to their purpose. Some words are used in more than one scenario. The meaning of the word depends on the context in which it is used. This is called: semantic load. Java, for having few key words and purposely reuse the words whenever possible has a much larger semantic load than other languages. However, in practice it is not possible to confuse the various meanings.

The reserved word super is used to reference methods or attributes of the super class. Imagine that you have a class called Manager that inherits from the Employee class and that both classes have a method called calcularPontos(). Being in the Manager class how to call the method calcularPontos() of the superclass (Funcio)?

//o compilador sabe que você quer utilizar o método da superclasse e não o método local.
super.calcularPontos(); 

Reserved word this is normally used within methods that receive parameters with the same class instance attribute name or to do reference to the object itself, let’s take an example:

public void setNome(String nome){
    /*o this nesse caso informar que o atributo de instancia 
    "nome" vai receber o valor do paramentro "nome". 
     Se não tivesse o this, como ele saberia? ficaria ambiguo.*/
    this.nome = nome; 
}

Another example, imagine you’re in class Gerente and calls the method of another class that expects as argument an object of the class Gerente. Then you can use the this to do this.

/* o método salvar gerente espera como argumento um objeto da classe
Gerente, como estou dentro da classe gerente eu disse que o 
objeto a ser salvo é "este"(this).*/
Armazenamento.salvarGerente(this); 

this: used to indicate the intended scope for invoking a method or access to an attribute is own object chain. Also used to reference another constructor of the same class. It is also used as a way of referring to the instance that encapsulates the current instance when in a nested class

A comparison

super: used to indicate the intended scope for invoking a method or access to an attribute is that of the parent class. Also used to reference another constructor of the class immediately superior in the hierarchy of inheritance

Situation

Here’s how you could solve this case. First, by implementing AdapterView.OnItemSelectedListener to the superclass JSONAsyncTask. Soon after declaring the Spinner as a global variable. No onPreExecute is made the connection between XML and JAVA, which would be before running the doInBackGround. In background the list of categories is created, as an example, and also the definition of the adapter. Finally, in the onPostExecute, is attached the data to the adapter. Below follows exactly as it should be AsyncTask personalized:

public class JSONOAsyncTask extends AsyncTask<String, Void, Boolean> implements  AdapterView.OnItemSelectedListener{

    private Spinner spinner;
    private ArrayAdapter<String> dataAdapter;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        spinner = (Spinner) findViewById(R.id.spinner);
        spinner.setOnItemSelectedListener(this);
    }

    @Override
    protected Boolean doInBackground(String... urls) {

        // criando lista de elementos
        List<String> categories = new ArrayList<String>();
        categories.add("Balaco Bacco");
        categories.add("Capitão G. Nascimento");
        categories.add("JBuenos's Dias");
        categories.add("Marceleza");
        categories.add("Ramarelo");

        // criação do adapter
        dataAdapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_spinner_item, categories);

        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        return false;
    }

    protected void onPostExecute(Boolean result) {

        // anexando o adapter aos dados
        spinner.setAdapter(dataAdapter);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
}

Recently I asked a question that is What difference between methods to obtain a context?, where I comment that we can beyond the this, obtain the context in various ways, with different methods, such as getApplicationContext() and the getBaseContext() which apparently has the same purpose. Read the answers and see more details about how to use.

Reference

  • 1

    THANKS! I’m already studying!!! as always a complete answer!

  • @ramaral found a situation in which I really needed to use the getBaseContext(). In this case, precisely it would not be so ideal to use the getApplicationContext().

  • I managed to implement!! THANKS ONCE MORE! now I will study all this.... what pain... I suffered so before on account of learning C.. that in fact, I know very little yet... affe.. how there’s a thing.. concept...language to understand... good, there I go

  • LOOK that interessnte... 500 round points.... who knows means something... rsrs

  • @Camilayamamoto cool that went all right there. Well, growing hurts. You’re growing, learning, it’s tiring, but it’s worth it. You can never have too much knowledge.

  • 1

    rsrs.. yes.. I have noticed that from growing... rsrsr ! GOOD, it did not go all right, there were other errors... rsrs... BUT I realize that this part of (this) worked, and so I will be able to study, already the "next mistakes" trying to understand here! : D

  • desolate here... I spent the day researching this and nothing.... THERE APPEARED another mistake that I just don’t know what it is.. the most I can say is that, (maybe) the spinner has not found the ARRAY.. After the APP crashes, the error appears on the line spinner.setOnItemSelectedListener(this);, and on the console the code that appears eh: ...Attempt to invoke virtual method 'android.view.View android.app.Activity.findViewById(int)' on a null Object Reference...

  • @Acklay I don’t see why I need to wear it there getBaseContext() can use the Activity context this.

  • @ramaral no, cannot use the this in the method doInBackground unless I insert the MinhaActivityPrincipal.this instead of only this. So I don’t know, I’m still looking for your legacy.

  • 1

    @Camilayamamoto as for this mistake that is happening, you have to see which id is set for your spinner. Apparently you’re not setting it correctly, or you’re using the spinner before even instantiating.

  • @Acklay Yes, inside a Inner class, to refer to Outer class, have to use NomeDaOuterClasse.this.

  • cool!!! studying!! Well I checked the ID right, ta identical! but I couldn’t solve it, so I asked one more question in the OS, so it doesn’t get too much in one post! (http://answall.com/questions/180980/o-que-eh-como-resolver-um-erro-null-object-reference-que-aparece-no-cons)

Show 7 more comments

6

What is the correct way to write this last THIS? (for example 2)??

Short answer:

If the Jsonoasynctask class is declared within (Inner class) of Activity(Outer class) and it implements the Adapterview.Onitemselectedlistener interface instead of this must use NomeDaActivity.this.

Explanation:

this is a reserved word which in this context is a reference to the current object. It is like a variable that stores the current object.
In this case the current object is Inner class thus to reference the Activity(Outer class) shall include its name: NomeDaOuterClasse.this

The method setOnItemSelectedListener() takes, as an argument, an object that implements the Adapterview interface.Onitemselectedlistener.

Thus, if Activity implements the Adapterview.Onitemselectedlistener interface, this can be used as argument to setOnItemSelectedListener(), if the call is made within it, for example within the method onCreate().

The same applies to the second example. In this case the class is Jsonoasynctask, this now refers to such an object.
In order to be used as an argument setOnItemSelectedListener(), the Jsonoasynctask class must implement the Adapterview interface.Onitemselectedlistener.

However, if the Jsonoasynctask class is declared within (Inner class) of Activity(Outer class) and it implements the Adapterview.Onitemselectedlistener interface, use NomeDaActivity.this to reference it.

2

Because when Voce uses THIS inside an onClickListener, for example, you are using this for the onClickListener object. Notice for example, when Voce gives new onClickListener and inside this object (called anonymous class) you give this with the intention of being the Activity, but in fact in this case it will be the object onClickListener created.

Edit: in your case it is in asynctask, but the operation is the same. Since you are inside the asynctask, you will have to pass this constructor, which will be Activity, and then use this parameter in the spinner. Ex:

// na activity
MyAsync ma = new MyAsync(this); // 
ma.execute();

// na async
private Context contexto; // usa essa veriável onde voce tinha colocado o this
public MyAsync (Context contexto){
this.contexto = contexto;
}

1

As @Pagotti said this makes reference to own class, what is probably happening is that the class JSONOAsyncTask is in the same class file where your onCreate() right?

Since the this refers to the own class (type localhost, which always points to the machine itself) this It’s actually kind of JSONOAsyncTask which is an extension of AsyncTask which in turn is the incorrect type for the parameter setOnItemSelectedListener()

Come on

According to the documentation of the method setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener)

The parameter shall be a class instance AdapterView.OnItemSelectedListener how did you use the this your class must have implemented the methods onItemSelected(AdapterView<?> parent, View view, int position, long id) and onNothingSelected(AdapterView<?> parent) you probably did it and so the first example works.

In the second example your class does not implement the class AdapterView.OnItemSelectedListener since it does not implement the class so the methods (cited above) do not exist, and that is what should be leading to its error.

0

I went through the same difficulties The reserved word this is used when the method references the object itself. For example, mainActivity.

AS does not accept when referencing another object. For example, a fragment will not accept references to this.

What you are going to use instead depends on the case of who references whom. For example, in a fragment, you can use getActivity() in place of this.

Android Studio itself gives hints of what it expects to see. Just leave the mouse on this underscored.

Detail: THIS on Android, does not exist, has to be always this in minuscules. I only comment because someone can read it in the future and get confused.

  • 1

    That second sentence is not "very correct" and even contradicts the first.

  • Dear @ramaral, please correct me. And explain to me that they contradict, even so that I can express myself better.

  • In the first you say: "make reference to the object itself" in the second you say: "a Fragment will not accept references to this". The first one is correct, this refers to the current object, the second contradicts because it implies that a Fragment does not "accept" this. thiscan be used in any object, it will always make reference to that object. The question relates to its use as an argument of a method, it has to be the kind the method expects.

  • Really, it was a choice of bad words. Thank you for clarifying

0

as @Pagotti commented, "this" refers to a class and is only available within that same class, so in the case here, it would be best to:

spiner.OnItemClickListener listener = new AdapterView.OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
        // ...
        int p = position;
        // ...
    }
};

try it out using its own code within the call of the onItemClick method.

I hope it helps!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.