Referencing Activity Components

1

I searched but found no answer.

I need to access a TextView that is present in my Activity within a Java Class that is independent of the Java Class of Activity itself.

The form I tried was creating a reference: public static TextView txtJogo; , however, is giving an exception:

  

"Only the original thread that created the view hierarchy can touch its views."

How I'm trying:

CadastroAnuncioActivity.txtJogo.setText(anuncio.getTitulo());

Here is the class where I need access to TextView :

public class IGDBHelper {

    //  public JSONArray json = new JSONArray();

    // public void setJsonArray(JSONArray jsonArray){
    //    this.json = jsonArray;
    // }

    public void pesquisarJogo(String string) {
        IGDBWrapper igdbWrapper = new IGDBWrapper("c59880bb3fdc0b21e75c85b89745fd8d", Version.STANDARD, false);
        Parameters parameters = new Parameters().addSearch(string).addFields("id,name,summary,popularity,total_rating").addLimit("1");
        igdbWrapper.search(Endpoints.GAMES, parameters, new OnSuccessCallback() {
            @Override
            public void onSuccess(@NotNull JSONArray jsonArray) {
                System.out.println(jsonArray + "anuncio");
                jsonToObj(jsonArray);
            }

            @Override
            public void onError(@NotNull Exception e) {

            }
        });

    }

    public void jsonToObj(JSONArray resultadoDaPesquisa) {
        Anuncio anuncio = new Anuncio();
        JSONObject jsonObject = null;
        try {
            for (int i = 0; i < resultadoDaPesquisa.length(); i++) {
                jsonObject = resultadoDaPesquisa.getJSONObject(i);
                String id = jsonObject.getString("id");
                String nome = jsonObject.getString("name");
                String descricao = jsonObject.getString("summary");
                String popularidade = jsonObject.getString("popularity");
                //String rating = jsonObject.getString("rating");

                anuncio.setUid(id);
                anuncio.setTitulo(nome);
                anuncio.setDescricao(descricao);
                anuncio.setPopularidade(popularidade);
                //anuncio.setRating(rating);

                System.out.println(anuncio.toString());
                CadastroAnuncioActivity.txtJogo.setText(anuncio.getTitulo());
                CadastroAnuncioActivity.txtId.setText(anuncio.getUid());
                CadastroAnuncioActivity.txtDescricao.setText(anuncio.getDescricao());
                CadastroAnuncioActivity.txtPopularidade.setText(anuncio.getPopularidade());
                //CadastroAnuncioActivity.txtRating.setText(anuncio.getRating());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
    
asked by anonymous 18.10.2018 / 20:22

1 answer

1

As the error itself says, another thread, other than main, is trying to change views - which is not allowed.

The solution is to always execute code that changes views in the main thread.

If you are within the activity:

runOnUiThread(() -> {
  // Seu codigo
});

Or, when out of an activity:

Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> {
  // Seu codigo
});

To also solve the problem of having to create a static field in a "simple" way, I suggest refactoring your code as follows.

Create an interface, which can be used for callbacks:

public interface Consumer<T> {

    void accept(T t);

}

And have your methods call a callback when the object has been converted:

public void pesquisarJogo(String string, Consumer<Anuncio> callback) {
    ...
        @Override
        public void onSuccess(@NotNull JSONArray jsonArray) {
            System.out.println(jsonArray + "anuncio");
            jsonToObj(jsonArray, callback);
        }
    ...
}

public void jsonToObj(JSONArray resultadoDaPesquisa, Consumer<Anuncio> callback) {
    ...
    anuncio.setUid(id);
    anuncio.setTitulo(nome);
    anuncio.setDescricao(descricao);
    anuncio.setPopularidade(popularidade);
    callback.accept(anuncio);
}

Now in your Activity you will have access to the ad inside the callback:

// Na activity, sem campos estáticos
igdbHelper.pesquisarJogo("hello", (anuncio) -> {
    runOnUiThread(() -> atualizarCampos(anuncio));
})

private void atualizarCampos(Anuncio anuncio) {
    txtJogo.setText(anuncio.getTitulo());
    txtId.setText(anuncio.getUid());
    txtDescricao.setText(anuncio.getDescricao());
    txtPopularidade.setText(anuncio.getPopularidade());
}
    
19.10.2018 / 14:00