当前位置: 代码迷 >> Android >> android 撤销网络加载过程
  详细解决方案

android 撤销网络加载过程

热度:37   发布时间:2016-04-28 06:28:14.0
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);        }    }

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

  相关解决方案