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

前端 未结 2 1484
难免孤独
难免孤独 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:41

    @J. Kowalski: This is indeed a good practice, although onPost and onPre AsyncTasks methods are executed on UI thread, its better to do this way.

    Just a small edit, don't pass activity/interface instance in the task constructor, rather use onResume and onPause of activity to set and remove (nullify) the interface reference to the AsyncTask, that way you can even save the response, for later use if the activity goes in pause state while the task is running, and GC can flush the activity objects, if the task is taking too much time.

    Pseudo Code

    AsyncTask

    public class GetCategoriesFromServerAsync extends AsyncTask> {
    
    private OnCategoriesDownloadedListener listener;
    private ArrayList categoryNamesArray;
    private String reason;
    
    public GetCategoriesFromServerAsync() {
        //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);
            }
    
        } else {
            //listener is null, activity gone in onPause, either save to file, or run the task again
        }
        super.onPostExecute(categoryNames);
    }
    
    public void setInterface(OnCategoriesDownloadedListener listener) {
        this.listener = listener;
    }
    }
    

    Activity

    public class SampleActivity extends Activity {
    GetCategoriesFromServerAsync mTask;
    boolean isDataLoaded = false;
    
    protected void onResume() {
        if(mTask != null) {
            switch(mTask.getStatus()) {
            case Status.PENDING:
            case Status.RUNNING:
                mTask.setInterface(this);
            break;
    
            case Status.FINISHED:
                if(isDataLoaded) {
                    //success case, do nothing...
                } else {
                    //load from file, or start the task again
                }
            break;
            } 
        }
    }
    
    protected void onPause() {
        if(mTask != null) mTask.setInterface(null);
    }
    }
    

    Hope that helps.

提交回复
热议问题