Referencing components of Activity

Asked

Viewed 71 times

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 itself Activity.

The way I tried was by creating a reference: public static TextView txtJogo;, however, is giving an Exception:

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

How I’m trying:

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

Follow 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();
        }

    }

}
  • Is there any way you can put in the code for this class? Because depending on what you do inside it, just vc from your Activity call the class and put your return in the setText of your Textview

  • It is not a good practice, the best way would be to use Viewmodel to make the logic of JSON and a Mutablelivedata of the object that will notify the Activity and ai you of the update in the text fields

  • Making it work later I can perfect but at the moment, I just want to make it work, regardless of the way I’m going to use it

1 answer

1

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

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

If you’re inside Activity:

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

Or, when out of an Activity:

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

To also solve in a "simple" way the problem of having to create a static field, 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());
}

Browser other questions tagged

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