Fire Asynctask class exception

Asked

Viewed 197 times

5

The class below is responsible for obtaining data from a WCF Rest service:

public class MyAsyncTaskGeneric<T> extends AsyncTask<String, Void, T>{

    private final Class<T> typeGeneric;         

    public MyAsyncTaskGeneric(Class<T> typeGeneric) {
        this.typeGeneric = typeGeneric;     
    }

    @Override
    protected T doInBackground(String... params) {      
        T result = null;        
        try {               
            RestTemplate restTemplate = new RestTemplate();
            restTemplate.getMessageConverters().add(new GsonHttpMessageConverter());
            result = restTemplate.getForObject(params[0], typeGeneric);
        } catch (Exception e) {
            Log.i("Teste", e.getMessage());         
        } 
        return result;
    }
}

It is consumed by business class:

public class CidadeBll {    

    public CidadeBll() {

    }

    public Cidade[] GetCidades(String url) throws Exception {
        Cidade[] result = null;
        try {
            MyAsyncTaskGeneric<Cidade[]> myAsync = new MyAsyncTaskGeneric<Cidade[]>(Cidade[].class);
            result = myAsync.execute(url + "/cidades").get();
        } catch (Exception e) {
            throw e;
        }
        return result;
    }
}

Which in turn is consumed by an Activity:

btnGetCidades.setOnClickListener(new View.OnClickListener() {           
        @Override
        public void onClick(View v) {
            try {
                CidadeBll cidadeBll = new CidadeBll();
                Cidade[] cidades = cidadeBll.GetCidades(url2);

                if (cidades.length > 0){
                    Toast.makeText(getApplicationContext(), "Qtde de Cidades: " + cidades.length, Toast.LENGTH_LONG).show();
                }

            } catch (Exception e) {
                Toast.makeText(getApplicationContext(), "Erro:" + e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
    });

Considering possible exceptions triggered by WCF Rest, I wish the Asynctask class could trigger the exception for the business class, and the business class for Activity.

That’s possible?

1 answer

4


It is possible yes. But before, I wanted to resurface that you are making a design mistake: a AsyncTask is intrinsically linked to the UI, so much so that the methods onPreExecute(), onProgressUpdate(Progress...) and onPostExecute(Result) have access to UI Thread (see The 4 Steps). So you don’t have to create Toasts in the Activity, but in the AsyncTask. Therefore, in the Activity you instance a AsyncTask and in the AsyncTask you instance an object of the business class to perform the work in background.

Returning to your question: you can add an attribute of the type Exception at its instance of AsyncTask and check the result in the method onPostExecute(Result). Here’s an example code:

Activity with Asynctask:

    btnGetCidades.setOnClickListener(new View.OnClickListener() {
        
        @Override
        public void onClick(View v) {
            
            new AsyncTask<String, Void, Cidade[]>() {
                
                // atributo que guarda excecao lancada
                private Exception e;
                
                @Override
                protected Cidade[] doInBackground(String... params) {
                    // em background
                    Cidade[] cidades = null;
                    
                    try {
                        CidadeBll cidadeBll = new CidadeBll();
                        cidades = cidadeBll.GetCidades(params + "/cidades");
                    } catch (Exception e) {
                        this.e = e;
                        return null;
                    }
                    
                    return cidades;
                }
                
                @Override
                protected void onPostExecute(Cidade[] cidades) {
                    // acesso a UI thread
                    if (cidades == null && e != null) {
                        // erro
                        Toast.makeText(
                                getApplicationContext(),
                                "Erro:" + e.getMessage(),
                                Toast.LENGTH_LONG).show();
                    } else {
                        // ok ..
                        if (cidades.length > 0){
                            Toast.makeText(
                                    getApplicationContext(),
                                    "Qtde de Cidades: " + cidades.length,
                                    Toast.LENGTH_LONG).show();
                        }
                    }
                }
            }.execute(url2);
        }
    });

Cidadebll.java (business class):

    public class CidadeBll {

        public CidadeBll() {
    
        }

        public Cidade[] GetCidades(String ... params) throws Exception {
            Cidade[] result = null;
    
            try {
                RestTemplate restTemplate = new RestTemplate();
                restTemplate.getMessageConverters().add(new GsonHttpMessageConverter());
                result = restTemplate.getForObject(params[0], Cidade[].class);
            } catch (Exception e) {
                Log.i("Teste", e.getMessage());
                
                throw e;
            }
            
            return result;
        }
    }

If the code of Activity has become large/confused can be found in another class, but keep the logic of modifying UI from the methods of AsyncTask who have access to the Thread UI.

I hope I’ve helped and for more information on how it works AsyncTask see the documentation.

Browser other questions tagged

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