取消AsyncTask的内部ListArrayAdapter和辞退通知 [英] Cancel AsyncTask inside ListArrayAdapter and dismiss notification

查看:129
本文介绍了取消AsyncTask的内部ListArrayAdapter和辞退通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

应用程序的目的是提供一个简单的方法来下载并提取了一堆档案(〜200mo),要删除它,打开它。下载显示的显示进度的通知。

我用一个ListView显示每一个可以下载​​的存档。每个阵列包含一个图像,一些文字,和两个按钮(用于读/删除,下载,或取消)。这些数据来自一个JSON检索。

当我尝试取消其显示通知的AsyncTask并下载文件我有一些问题。当我打电话的 async.cancel(真); 的,通知和下载仍​​在运行。

也许我是从错误的地方调用AsyncTask的,但我不知道如何解决这个问题。

我的适配器:

 公共类ListArrayAdapter扩展ArrayAdapter<串GT; {私人最终上下文的背景下;
公众可绘制D组;
私人的ArrayList<&HashMap的LT;字符串,字符串>>清单;
公共布尔finishDownload = FALSE;
JSONArray jsonArray;//构造
公共ListArrayAdapter(上下文的背景下,列表与LT;弦乐>的价值观,
        ArrayList的<&HashMap的LT;字符串,字符串>>名单){
    超(背景下,R.layout.activity_list_array_adapter,价值观);
    this.context =背景;
    this.list =清单;
}@覆盖
公共查看getView(最终诠释的立场,观点convertView,父母的ViewGroup){    LayoutInflater吹气=(LayoutInflater)上下文
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    查看rowView = inflater.inflate(R.layout.activity_list_array_adapter,
            父母,假);    //声明
    TextView的日期=(TextView中)rowView.findViewById(R.id.date);
    TextView的标题=(TextView中)rowView.findViewById(R.id.title);
    TextView中描述=(TextView中)rowView.findViewById(R.id.description);
    ImageView的ImageView的=(ImageView的)rowView.findViewById(R.id.cover);
    进度PD =(进度)rowView.findViewById(R.id.progress);
    最终按钮按钮1 =(按钮)rowView.findViewById(R.id.button1);
    最后的按钮按钮2 =(按钮)rowView.findViewById(R.id.button2);    //装满JSON文件数组
    title.setText(list.get(位置)获得(标题));
    date.setText(list.get(位置)获得(日期));
    description.setText(list.get(位置)获得(说明));
    新ParseImage(位置,ImageView的,PD).execute();    最终文件的文件=新的文件(Environment.getExternalStorageDirectory()
            .getPath()+/杂志/+ list.get(位置)获得(姓名)+.ZIP);    //如果文件存在,让用户打开它
    如果(file.exists()){
        button1.setText(里拉);
        button2.setVisibility(View.VISIBLE);
        button2.setText(Supprimer);
    }    //否则,让用户下载
    其他{
        button1.setText(Télécharger);
        button2.setVisibility(View.GONE);
    }    最后DownloadTask异步=新DownloadTask(上下文,位置,清单);    button1.setOnClickListener(新Button.OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){
            如果(button1.getText()==Télécharger){
                button1.setEnabled(假);
                button2.setVisibility(View.VISIBLE);
                button2.setText(更改或取消);
                finishDownload = FALSE;
                async.execute(0);
            }否则如果(button1.getText()==里拉){
                意图I1 =新意图(背景下,WebActivity.class);
                context.startActivity(I1);
            }
        }
    });    button2.setOnClickListener(新Button.OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){
            如果(button2.getText()==更改或取消){
                async.cancel(真);
                button1.setEnabled(真);
                button2.setVisibility(View.GONE);
                button1.setText(Télécharger);
            }否则如果(button2.getText()==Supprimer){
                button1.setEnabled(真);
                button2.setVisibility(View.GONE);
                button1.setText(Télécharger);                如果(file.exists()){
                    file.delete();
                }
            }
        }
    });    返回rowView;
}公共类DownloadTask扩展的AsyncTask<整数,整数,太虚> {    私人NotificationHelper mNotificationHelper;
    公众诠释的位置;
    公众的ArrayList<&HashMap的LT;字符串,字符串>>清单;    公共DownloadTask(上下文的背景下,INT位置,
            ArrayList的<&HashMap的LT;字符串,字符串>>名单){
        mNotificationHelper =新NotificationHelper(背景);
        this.position =位置;
        this.list =清单;
    }    @覆盖
    在preExecute保护无效(){
        mNotificationHelper.createNotification();
    }    @覆盖
    保护无效doInBackground(整数...整数){
        诠释计数= 0;
        尝试{
            视频下载(1);
            网址URL =新的URL(list.get(位置)获得(内容));
            URLConnection的连接如= url.openConnection();
            conection.connect();
            INT lenghtOfFile = conection.getContentLength();            输入的InputStream =新的BufferedInputStream(url.openStream()
                    8192);            OutputStream的输出=新的FileOutputStream(环境
                    .getExternalStorageDirectory()的getPath()
                    +/杂志/
                    + list.get(位置)获得(姓名)
                    +的.zip);            字节的数据[] =新的字节[1024];            总长= 0;
            INT progress_temp = 0;
            而((计数= input.read(数据))!= - 1)
            {
                总+ =计数;
                progress_temp =(int)的总* 100 / lenghtOfFile;
                output.write(数据0,计);
            }            publishProgress(progress_temp);
            output.flush();
            output.close();
            input.close();        }赶上(例外五){
            Log.e(错误,e.getMessage());
        }
        返回null;
    }    @覆盖
    保护无效onProgressUpdate(整数...进度){
        mNotificationHelper.progressUpdate(进展[0]);
    }    @覆盖
    保护无效onCancelled(){
        mNotificationHelper.completed();        super.onCancelled();
    }    @覆盖
    保护无效onPostExecute(虚空结果){        mNotificationHelper.completed();        finishDownload = TRUE;
    }
}
}

该notificationHelper类管理的通知:

 公共类NotificationHelper {
    私人语境mContext;
    私人INT NOTIFICATION_ID = 1;
    私人通知mNotification;
    私人NotificationManager mNotificationManager;
    私人的PendingIntent mContentIntent;
    私人CharSequence的mContentTitle;    公共NotificationHelper(上下文的背景下){
        mContext =背景;
    }    @燮pressWarnings(德precation)
    公共无效createNotification(){
        mNotificationManager =(NotificationManager)mContext
                .getSystemService(Context.NOTIFICATION_SERVICE);        INT图标= android.R.drawable.stat_sys_download;
        CharSequence的tickerText = mContext.getString(R.string.download_ticker);
        时长= System.currentTimeMillis的();
        mNotification =新的通知(图标,tickerText时);        mContentTitle = mContext.getString(R.string.content_title);
        的CharSequence contentText =0%téléchargé;        意图notificationIntent =新意图(mContext,MainActivity.class);
        mContentIntent = PendingIntent.getActivity(mContext,0,
                notificationIntent,0);        mNotification.setLatestEventInfo(mContext,mContentTitle,contentText,
                mContentIntent);        mNotification.flags = Notification.FLAG_ONGOING_EVENT;        mNotificationManager.notify(NOTIFICATION_ID,mNotification);
    }    @燮pressWarnings(德precation)
    公共无效progressUpdate(INT percentageComplete){
        CharSequence的contentText = percentageComplete +%téléchargé;        mNotification.setLatestEventInfo(mContext,mContentTitle,contentText,
                mContentIntent);
        mNotificationManager.notify(NOTIFICATION_ID,mNotification);
    }    公共无效完成(){
        mNotificationManager.cancel(NOTIFICATION_ID);
    }
}


解决方案

取消() AsyncTasks 方法(容易混淆)实际上并没有停止运行线程,而是设置一个标志的任务。你可以在这里找到有关一些讨论。如此看来,目前,如果你想你的线程真正停止中旬执行,你需要使用手动检查标志在你的循环code中的 isCancelled()方法。例如,在doInBackground while循环

 ,而((数= input.read(数据))!= -1)
{
    总+ =计数;
    progress_temp =(int)的总* 100 / lenghtOfFile;
    output.write(数据0,计);
    如果(isCancelled())
    {
        // code在这里,可能...
        //跳出循环,
        //停止线程,
        //关闭通知,
        //执行任何清理,等等。
    }
}

下可以找到用法这在AsyncTask的文档另一个例子头。希望这有助于!

The aim of the application is to offer a simple way to download and extract a bunch of archives (~200mo), to delete it, and to open it. The download display a notification which display the progress.

I'm using a ListView to display every archive that can be downloaded. Each array contain an image, some text, and two buttons (for reading/deleting, downloading, or cancel). The data are retrieved from a json.

I've got some issues while I try to cancel the AsyncTask which display the notification and download the file. When I call the async.cancel(true);, the notification and the download are still running.

Maybe am I calling the asyncTask from the wrong place, but I don't know how to fix this.

My adapter :

public class ListArrayAdapter extends ArrayAdapter<String> {

private final Context context;
public Drawable d;
private ArrayList<HashMap<String, String>> list;
public boolean finishDownload = false;
JSONArray jsonArray;

// Constructor
public ListArrayAdapter(Context context, List<String> values,
        ArrayList<HashMap<String, String>> list) {
    super(context, R.layout.activity_list_array_adapter, values);
    this.context = context;
    this.list = list;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.activity_list_array_adapter,
            parent, false);

    // Déclaration
    TextView date           = (TextView) rowView.findViewById(R.id.date);
    TextView title          = (TextView) rowView.findViewById(R.id.title);
    TextView description    = (TextView) rowView.findViewById(R.id.description);
    ImageView imageView     = (ImageView) rowView.findViewById(R.id.cover);
    ProgressBar pd          = (ProgressBar) rowView.findViewById(R.id.progress);
    final Button button1    = (Button) rowView.findViewById(R.id.button1);
    final Button button2    = (Button) rowView.findViewById(R.id.button2);

    // Fill the array with the json file
    title.setText(list.get(position).get("Title"));
    date.setText(list.get(position).get("Date"));
    description.setText(list.get(position).get("Description"));
    new ParseImage(position, imageView, pd).execute();

    final File file = new File(Environment.getExternalStorageDirectory()
            .getPath() + "/Magazine/"   + list.get(position).get("Name") + ".zip");

    //If the file exist, let the user open it
    if (file.exists()) {
        button1.setText("Lire");
        button2.setVisibility(View.VISIBLE);
        button2.setText("Supprimer");
    } 

    // else, let the user download it
    else {
        button1.setText("Télécharger");
        button2.setVisibility(View.GONE);
    }

    final DownloadTask async = new DownloadTask(context, position, list);

    button1.setOnClickListener(new Button.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (button1.getText() == "Télécharger") {
                button1.setEnabled(false);
                button2.setVisibility(View.VISIBLE);
                button2.setText("Annuler");
                finishDownload = false;
                async.execute(0);
            } else if (button1.getText() == "Lire") {
                Intent i1 = new Intent(context, WebActivity.class);
                context.startActivity(i1);
            }
        }
    });

    button2.setOnClickListener(new Button.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (button2.getText() == "Annuler") {
                async.cancel(true);
                button1.setEnabled(true);
                button2.setVisibility(View.GONE);
                button1.setText("Télécharger");
            } else if (button2.getText() == "Supprimer") {
                button1.setEnabled(true);
                button2.setVisibility(View.GONE);
                button1.setText("Télécharger");

                if (file.exists()) {
                    file.delete();
                }
            }
        }
    });

    return rowView;
}

public class DownloadTask extends AsyncTask<Integer, Integer, Void> {

    private NotificationHelper mNotificationHelper;
    public int position;
    public ArrayList<HashMap<String, String>> list;

    public DownloadTask(Context context, int position,
            ArrayList<HashMap<String, String>> list) {
        mNotificationHelper = new NotificationHelper(context);
        this.position = position;
        this.list = list;
    }

    @Override
    protected void onPreExecute() {
        mNotificationHelper.createNotification();
    }

    @Override
    protected Void doInBackground(Integer... integers) {
        int count = 0;
        try {
            Thread.sleep(1);
            URL url = new URL(list.get(position).get("Content"));
            URLConnection conection = url.openConnection();
            conection.connect();
            int lenghtOfFile = conection.getContentLength();

            InputStream input = new BufferedInputStream(url.openStream(),
                    8192);

            OutputStream output = new FileOutputStream(Environment
                    .getExternalStorageDirectory().getPath()
                    + "/Magazine/"
                    + list.get(position).get("Name")
                    + ".zip");

            byte data[] = new byte[1024];

            long total = 0;
            int progress_temp = 0;


            while ((count=input.read(data)) != -1)
            {
                total += count;
                progress_temp = (int) total*100/lenghtOfFile;
                output.write(data, 0, count);
            }

            publishProgress(progress_temp);
            output.flush();
            output.close();
            input.close();

        } catch (Exception e) {
            Log.e("Error: ", e.getMessage());
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        mNotificationHelper.progressUpdate(progress[0]);
    }

    @Override
    protected void onCancelled() {
        mNotificationHelper.completed();

        super.onCancelled();
    }

    @Override
    protected void onPostExecute(Void result) {

        mNotificationHelper.completed();

        finishDownload = true;
    }
}
}

The notificationHelper class which manage the notification :

public class NotificationHelper {
    private Context mContext;
    private int NOTIFICATION_ID = 1;
    private Notification mNotification;
    private NotificationManager mNotificationManager;
    private PendingIntent mContentIntent;
    private CharSequence mContentTitle;

    public NotificationHelper(Context context) {
        mContext = context;
    }

    @SuppressWarnings("deprecation")
    public void createNotification() {
        mNotificationManager = (NotificationManager) mContext
                .getSystemService(Context.NOTIFICATION_SERVICE);

        int icon = android.R.drawable.stat_sys_download;
        CharSequence tickerText = mContext.getString(R.string.download_ticker);
        long when = System.currentTimeMillis();
        mNotification = new Notification(icon, tickerText, when);

        mContentTitle = mContext.getString(R.string.content_title);
        CharSequence contentText = "0% téléchargé";

        Intent notificationIntent = new Intent(mContext, MainActivity.class);
        mContentIntent = PendingIntent.getActivity(mContext, 0,
                notificationIntent, 0);

        mNotification.setLatestEventInfo(mContext, mContentTitle, contentText,
                mContentIntent);

        mNotification.flags = Notification.FLAG_ONGOING_EVENT;

        mNotificationManager.notify(NOTIFICATION_ID, mNotification);
    }

    @SuppressWarnings("deprecation")
    public void progressUpdate(int percentageComplete) {
        CharSequence contentText = percentageComplete + "% téléchargé";

        mNotification.setLatestEventInfo(mContext, mContentTitle, contentText,
                mContentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mNotification);
    }

    public void completed() {
        mNotificationManager.cancel(NOTIFICATION_ID);
    }
}

解决方案

The cancel() method on AsyncTasks (confusingly) doesn't actually stop the Thread from running, but rather sets a flag on the Task. You can find some discussion about that here. It seems that currently, if you want your Thread to actually stop mid-execution, you'll need to manually check that flag in your looping code using the isCancelled() method. For example, in your while loop in doInBackground:

while ((count=input.read(data)) != -1)
{
    total += count;
    progress_temp = (int) total*100/lenghtOfFile;
    output.write(data, 0, count);
    if(isCancelled())
    {
        //Code here that may...
        //    break out of the loop, 
        //    stop the thread, 
        //    close the notification,
        //    perform any cleanup, etc...
    }
}

You can find another example of this in the AsyncTask docs under the "Usage" header. Hope this helps!

这篇关于取消AsyncTask的内部ListArrayAdapter和辞退通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆