How to "call" this correctly?

6

When Elements are within onCreate , using (this) is 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

If I put it inside a function (outside onCreate ), the thing changes and the following function does not work. The compiler does not accept this this because it does not find 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 this last this (for Example 2)?

    
asked by Camila Yamamoto 27.01.2017 в 11:06

6 answers

10

The first factor to note in this situation is that calling the setOnItemSelectedListener() method enforces the implementation of the AdapterView.onItemSelectedListener interface 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 you should explore AsyncTask . / a>. This class gives us some interesting features : onPreExecute() and onPostExecute() . These methods are used to define some action that we want to perform before the asynchronous task and what we want to do after the task is completed.

We go to this

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

Key words 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 loading. Java, having a few key words and purposely re-using words whenever possible has a much greater semantic charge than other languages. However, in practice it is not possible to confuse the various meanings.

The keyword super is used to refer to super class methods or attributes. Imagine that you have a class named Manager that inherits from the Employee class and that both classes have a method named calcularPontos() . In the Manager class how do I call the calcularPontos() method of the superclass (Official)?

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

Reserved keyword is typically used within methods that receive parameters with the same class instance attribute name or to refer to the object itself , let's look at 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 that you are in the Gerente class and call the method of another class that expects as an argument an object of class Gerente . Then you can use 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 that the intended scope for the invocation of   a method or access to an attribute is that of the current object itself.   Also used to refer to another builder of the same   class. It is still using as a way of referring to the instance that encapsulates   the current instance when in a nested class

A comparison

  

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

Situation

See a way you could solve this case. First implementing AdapterView.OnItemSelectedListener to superclass JSONAsyncTask . Then declaring Spinner as the global variable. In onPreExecute the connection between XML and JAVA is made, which would be before executing doInBackGround . In background the category list is created as an example, as well as the adapter definition. Finally, in% w / o%, the data is appended to the adapter. Here is exactly how your% custom% should be:

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've asked a question that is What is the difference between methods to get a context? , where I comment that we can in addition to onPostExecute , get the context in various ways, with different methods like AsyncTask and this that apparently has the same purpose. Read the answers and see more details on how to use them.

Reference

29.01.2017 / 18:51
6
  

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

Short answer:

If the JSONOAsyncTask class is declared inside (outer class) of the Activity (outer class) and this implements the AdapterView.OnItemSelectedListener interface, instead of this it should use NomeDaActivity.this .

Explanation:

this is a reserved word that, in this context, is a reference to the current object. It is as if it were a variable (attribute) that holds the current object. To refer to an inner class you must include the outer class name: NomeDaOuterClasse.this

The setOnItemSelectedListener() method receives, as an argument, an object that implements the AdapterView.OnItemSelectedListener interface.

So if Activity implements the AdapterView.OnItemSelectedListener interface, this can be used as an argument to setOnItemSelectedListener() , if the call is made inside it, for example, within the onCreate() method.

The same applies to the second example. In this case the class is JSONOAsyncTask, this now refers to an object of this type. In order to be used as the setOnItemSelectedListener() argument, the JSONOAsyncTask class must implement the AdapterView.OnItemSelectedListener interface.

However, if the JSONOAsyncTask class is declared inside (outer class) of the Activity (outer class) and this implements the AdapterView.OnItemSelectedListener interface, use NomeDaActivity.this to reference it.

    
27.01.2017 в 13:31
2

Because when you use THIS within an onClickListener, for example, you are using this for the onClickListener object. For example, when you give new onClickListener and within that object (called anonymous class) you give this one with the intention of being that of the activity, but in fact in that case it will be of the onClickListener object created.

Edit: In your case it is in asynctask, but the operation is the same. As it is inside the asynctask, it will have to pass in its constructor a this, that is going to be the activity, and later to 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;
}
    
27.01.2017 в 13:25
1

Since @Pagotti said this refers to the class itself, what is probably happening is that the JSONOAsyncTask class is in the same file of the class where its onCreate() right?

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

Come on

According to method documentation setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener)

The parameter must be an instance of class AdapterView.OnItemSelectedListener as you used this your class should have implemented the onItemSelected(AdapterView<?> parent, View view, int position, long id) and onNothingSelected(AdapterView<?> parent) methods you probably did this and so the first example works.

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

27.01.2017 в 13:28
0

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

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

What you will use instead, depends on the case of who refers to whom. For example, in a snippet, you can use getActivity() instead of this .

Android Studio itself gives hints of what it expects to see. Just drop the mouse over% w / o underlined red.

Detail: this on Android does not exist, it must always be THIS in lowercase. Just comment because someone can read this in the future and get confused.

    
27.01.2017 в 13:18
0

As @Pagotti commented, "this" refers to a class and is only available within the same class, so here it would be best if you did so:

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

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

try using your own code within the call of the onItemClick method.

But that helps!

    
27.01.2017 в 13:22