Android Loader vs AsyncTask on button tap

风格不统一 提交于 2019-12-06 15:41:35
public class TestActivity extends FragmentActivity {

    private Button one;
    private Button two;

    private final int ONE_ID = 0;
    private final int TWO_ID = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        one = (Button) findViewById(R.id.one);
        two = (Button) findViewById(R.id.two);

        one.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getLoaderManager().restartLoader(ONE_ID, null, callbacks);
            }
        });

        two.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getLoaderManager().restartLoader(ONE_ID, null, callbacks);
            }
        });

        Loader<AsyncTaskLoaderResult<Result>> loader = getLoaderManager().getLoader(ONE_ID);
        if (loader != null) {
            getLoaderManager().initLoader(ONE_ID, null, callbacks);
        }
        loader = getLoaderManager().getLoader(TWO_ID);
        if (loader != null) {
            getLoaderManager().initLoader(TWO_ID, null, callbacks);
        }


    }

    public static class AsyncTaskLoaderResult<E> {
        public E data;
        public Bundle args;
    }

    public static class Result {

    }

    private LoaderManager.LoaderCallbacks<AsyncTaskLoaderResult<Result>> callbacks = new LoaderManager.LoaderCallbacks<AsyncTaskLoaderResult<Result>>() {
        @Override
        public Loader<AsyncTaskLoaderResult<Result>> onCreateLoader(int id, Bundle args) {
            /**
             * according different Id, create different AsyncTaskLoader
             */
            switch (id) {
                case ONE_ID:
                    return new OneAsyncTaskLoader(TestActivity.this);
                case TWO_ID:
                    return new TwoAsyncTaskLoader(TestActivity.this);
            }
            return null;
        }

        @Override
        public void onLoadFinished(Loader<AsyncTaskLoaderResult<Result>> loader, AsyncTaskLoaderResult<Result> data) {
            /**
             * handle result
             */
            switch (loader.getId()) {

            }

            getLoaderManager().destroyLoader(loader.getId());
        }

        @Override
        public void onLoaderReset(Loader<AsyncTaskLoaderResult<Result>> loader) {

        }
    };

    public static class OneAsyncTaskLoader extends AsyncTaskLoader<AsyncTaskLoaderResult<Result>> {

        private AsyncTaskLoaderResult<Result> result;

        public OneAsyncTaskLoader(Context context) {
            super(context);
        }

        @Override
        protected void onStartLoading() {
            super.onStartLoading();
            if (result != null) {
                deliverResult(result);
            } else {
                forceLoad();
            }
        }

        @Override
        public AsyncTaskLoaderResult<Result> loadInBackground() {
            /**
             * send request to server
             */
            result = new AsyncTaskLoaderResult<Result>();
            result.data = null; //  result.data comes from server's response
            return result;
        }
    }

    public static class TwoAsyncTaskLoader extends AsyncTaskLoader<AsyncTaskLoaderResult<Result>> {


        private AsyncTaskLoaderResult<Result> result;

        public TwoAsyncTaskLoader(Context context) {
            super(context);
        }

        @Override
        protected void onStartLoading() {
            super.onStartLoading();
            if (result != null) {
                deliverResult(result);
            } else {
                forceLoad();
            }
        }

        @Override
        public AsyncTaskLoaderResult<Result> loadInBackground() {
            /**
             * send request to server
             */
            result = new AsyncTaskLoaderResult<Result>();
            result.data = null; //  result.data comes from server's response
            return result;
        }
    }
}

First, you can eliminate the orienatation change issue by declaring

android:configChanges="orientation"

or savedInstanceState()

But the real problem here is having the user stare at a spinner for 10 seconds. Most users aren't going to be patient enough for this. I don't know what your app is doing so its hard to give an accurate suggestion but I can say that you need to do your network stuff in your AsyncTask but allow the user to do other things

You can allow the user to do other things while the AsyncTask finishes or put that code in a [Service(http://developer.android.com/guide/components/services.html). Either way, don't make your users stare at a screen for 10 seconds of spinning...they won't be YOUR users for long

If you're using an AsyncTask for this you might want to either use a Service instead or use onRetainNonConfigurationInstance or Fragment.setRetainInstance to allow the AsyncTask to live through configuration changes.

Or disable configuration changes: I've used that in the past with some success.

Here's a good article on the subject:

http://www.javacodegeeks.com/2013/01/android-loaders-versus-asynctask.html

Anyways, as @codeMagic mentioned, AsyncTask with android:configChanges="orientation|screenSize" should be enough for you (it prevents activity from being recreated on config changes)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!