android 取消网络加载过程

     以前文章中对网络加载数据过程都是一笔带过,在这里分析一种特殊情况:加载过程中,点击取消加载。

     异步加载数据过程,有人喜欢用AsyncTask,有人喜欢自己控制线程池来管理加载任务队列,其实质是一样的都是实现了异步加载。

加载网络数据我大体分为两类:

     1、数据加载完,刷新页面,一般用到等待框,比如新闻列表信息请求。

     2、数据加载任务后台进行,不影响正常操作,比如,日志请求、数据已读请求等。

那么第一类就存在一种情况,在加载过程中,用户不想等待了,点击返回取消等待框。等待框取消证明用户放弃该页面加载,即要取消加载线程。

我们以实用AsyncTask来看以上功能的实现,直接上核心代码:

 

public abstract class IsAsyncTask<Params, Progress, Result> extends
        AsyncTask<Params, Progress, Result> {
    /**
     * 加载进度条
     */
    private DialogLoading dialog_loading = null;
    
    protected String exception;
    
    protected Activity activity;

    /**
     * 是否显示加载进度条 为了下拉和上拉刷新不显示加载进度条
     */
    private boolean isShow = true;

    public IsAsyncTask(Activity activity) {
        this(activity, true, true);
    }

    public IsAsyncTask(Activity activity, final DialogInterface.OnCancelListener l,
            boolean isShow) {
        this(activity, l, true, isShow);
    }

    public IsAsyncTask(Activity activity, final boolean cancelable, boolean isShow) {
        this(activity, null, cancelable, isShow);
    }

    public IsAsyncTask(Activity activity, final DialogInterface.OnCancelListener l,
            final boolean cancelable, boolean isShow) {
        super();
        this.activity = activity;
        this.isShow = isShow;
        if (null == dialog_loading && isShow) {
            dialog_loading = new DialogLoading(activity);
            dialog_loading.setCanceledOnTouchOutside(false);
            dialog_loading.setCancelable(cancelable);
            dialog_loading.setOnCancelListener(new DialogInterface.OnCancelListener() {

                @Override
                public void onCancel(DialogInterface dialog) {
                    if (cancelable) {
                        IsAsyncTask.this.cancel(true);
                    }
                    if (l != null) {
                        l.onCancel(dialog);
                    }
                }
            });
        }

    }

    @Override
    protected Result doInBackground(Params... params) {
        return null;
    }

    @Override
    protected void onPostExecute(Result result) {
        super.onPostExecute(result);
        if (null != activity && !activity.isFinishing() && dialog_loading != null) {
            dialog_loading.dismiss();
        }

    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if (null != activity && !activity.isFinishing() && dialog_loading != null && isShow) {
            dialog_loading.show();
        }
    }

}


过程分析:

    1、创建这个异步任务的时候,就要把是否显示等待框isShow、是否允许取消cancelable。

    2、当需要显示等待框时候,创建、显示并且绑定一个取消监听,当等待框取消掉时候,也取消对应的异步加载任务。

通过这样简单的把dialog和asynctask的绑定在一起,可以实现两种异步任务的加载,还可以实现等待框和加载任务的取消。

怎么使用呢,来个例子:

首先实现asynctask

 private class GetPageHtmlDataTask extends
            IshuguiAsyncTask<String, Void, BSPageHtmlResBeanInfo> {

        private WebView webView;

        public GetPageHtmlDataTask(Activity activity, WebView webView) {
            super(activity, null, true);
            this.webView = webView;
        }

        @Override
        protected BSPageHtmlResBeanInfo doInBackground(String... params) {

            BSPageHtmlResBeanInfo bsBeanInfo = null;
            try {

                bsBeanInfo = IshuguiLib.getInstance(activity).getBSPageHtmlBeanInfo(params[0],
                        params[1], params[2], params[3], params[4], params[5]);

            } catch (HttpRequestException e) {
                exception = e.getMessage();
                e.printStackTrace();
            } catch (JSONException e) {
                exception = e.getMessage();
                e.printStackTrace();
            }

            return bsBeanInfo;
        }

        @Override
        protected void onPostExecute(BSPageHtmlResBeanInfo result) {
            if (exception != null) {
                LogUtil.d(TAG, exception);
                exception = null;
                ToastAlone.showToast(activity, R.string.net_work_notcool, Toast.LENGTH_LONG);
                super.onPostExecute(result);
                return;
            }

            if (result != null) {

                if ("0".equals(result.getPublicBean().getStatus())) {

                    result.insertJsAndCssMethod(activity);

                    setWebView(webView, result);

                } else {
                    ToastAlone.showToast(activity, R.string.request_data_failed,
                            Toast.LENGTH_SHORT);
                }
            } else {
                ToastAlone.showToast(activity, R.string.request_data_failed,
                        Toast.LENGTH_SHORT);
            }
            super.onPostExecute(result);
        }
    }

getBSPageHtmlBeanInfo数据获取协议时通过httpclient实现的,这个大家应该比较熟悉了。

这样直接调用就可以了:

 if (NetworkUtils.checkNet(this)) {
            if (getBSPageHtmlDataTask != null) {
                getBSPageHtmlDataTask.cancel(true);
            }

            getBSPageHtmlDataTask = new GetBSPageHtmlDataTask(this, webVi_specialTopic);
            getBSPageHtmlDataTask.execute(bsType, strId, "", "", "", clientAgent);
        }


还有一种加载过程是跟activity一起消亡的话:

 @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();

        if (getBSPageHtmlDataTask != null) {
            getBSPageHtmlDataTask.cancel(true);
        }

    }

数据加载过程与人机交互息息相关,如果控制不好,很可能多个线程去刷新一个界面数据,引起异常,所以要根据需求控制好每个异步加载任务。

android 取消网络加载过程,布布扣,bubuko.com

android 取消网络加载过程

上一篇:Problem E: 编写函数:Swap (I) (Append Code)


下一篇:Xcode 5.1 & iOS7.1 自动打包问题解决