Utility classes in Android, AsyncTask, and loose-coupling please advise

前端 未结 2 1454
难免孤独
难免孤独 2021-02-06 10:59

I\'ve attempted to search for any discussion on this topic, but I haven\'t found anything useful thus far. Therefore, I decided to go ahead and post this.

So my query i

2条回答
  •  后悔当初
    2021-02-06 11:45

    This is what I do, I learned that from StackOverflow:

    Lets say we are downloading categories from the server database

    First, create an interface

    public interface OnCategoriesDownloadedListener {
        public void onCategoriesDownloadSuccess(ArrayList categories);
        public void onCategoriesDownloadFailure(String reason);
    }
    

    then, in the activity that is waiting for those categories to be downloaded, I implement this interface:

    public class MyActivity extends Activity implements  OnCategoriesDownloadedListener {
    
        @Override
        onCategoriesDownloadSuccess(ArrayList categories) {
            //get the categories and do whatever my soul desire
        }
    
        @Override
        onCategoriesDownloadFailure(String reason) {
           //get the reason and come up with appropriate failure excuse
        }
    
    }
    

    in my asynctask class, I do the following

    public class GetCategoriesFromServerAsync extends AsyncTask> {
    
    
    private OnCategoriesDownloadedListener listener;
    private ArrayList categoryNamesArray;
    private String reason;
    
    public GetCategoriesFromServerAsync(OnCategoriesDownloadedListener listener) {
        this.listener = listener;
                //usually I pass more data here, for example when Im registering a user in the server database, Im using the constructor to pass their data.
    }
    
    @Override
    protected ArrayList doInBackground(String... args) {
        int success;
    
        try {
            //JSON stuff
    
                return categoryNames;
    
            } else if (success == 2) {
                reason = "failure";
                return null;
            } else {
                reason = "Connection error";
                return null;
            }
        } catch (JSONException e) {
            e.printStackTrace();
            reason = "Connection error";
            return null;
        }
    }
    
    @Override
    protected void onPostExecute(Object[] categoryNamesAndLogos) {
    
        if (listener != null) {
            if (categoryNames!=null) {
                listener.onCategoriesDownloadSuccess(categoryNames);
            } else if (reason.contentEquals(TAG_FAILURE)) {
                listener.onCategoriesDownloadFailure(reason);
            } else if (reason.contentEquals(TAG_CONNECTION_ERROR)) {
                listener.onCategoriesDownloadFailure(reason);
            }
    
        }
        super.onPostExecute(categoryNames);
    }
    

    }

    From the activity that implements the listener I start the asynctask, using its constructor:

    new GetCategoriesFromDatabase(this).execute();
    

    thus noting that that activity is implementing the listener and is awaiting the results.

    In the asynctask postExecute I just deal with the results, send them to the activity that is waiting for them and deal with them in the onCategoriesDownloadSuccess method

    If you want to display a Loader, you can do that alongside starting the asynctask from your activity and end displaying it in the onSuccess and onFailure methods. At this point Im doing this in the onPreExecute and onPostExecute of the AsyncTask, but I gotta take some time or advice and think about which is the better approach.

    Not sure whether this is a best practice, because its the only one I know but it certainly works for me.

提交回复
热议问题