Диалоговое окно «Ход выполнения» в асинхронной задаче (PostExecute)

Я реализовал асинхронную задачу, которая создает миниатюры для списка воспроизведения видео. Во время фонового потока я реализовал диалог Progress, который запускается в PreExecute Task. На данный момент я закрываю диалоговое окно метода postExecute, но я должен что-то упустить. Могу ли я получить помощь по этому поводу?

Мой код ниже

Видеолистактивити.java

package com.oneplc.viessmannapp;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;



import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import wseemann.media.FFmpegMediaMetadataRetriever;
import android.media.ThumbnailUtils;
import android.provider.MediaStore;
import android.widget.GridView;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class VideoListActivity extends Activity {

    private static ProgressDialog pDialog;

    private static String MEDIA_PATH;

    String[] fileList = null;

    ListView mList;
    String FILE_PATH;
    String MIME_TYPE = "video/mp4";

    private ImageView goBack;
    private static Context mContext;

    private ImageAdapter mAdapter;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            mAdapter.notifyDataSetChanged();                       
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_list);

        goBack = (ImageView) findViewById(R.id.back_btn);
        mContext = this;
        setActionListeners();

        String folder = getIntent().getStringExtra("folder");

        MEDIA_PATH = new String(Environment.getExternalStorageDirectory().getPath() + "/"+folder+"/");
        updateVideoList();
        FILE_PATH = Environment.getExternalStorageDirectory().getPath() + "/"+folder+"/";

        mList = (ListView) findViewById(R.id.listView1);
        if(fileList !=null){
            mAdapter = new ImageAdapter(this, fileList);
            mList.setAdapter(mAdapter);
        }
        mList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View v,
                    int position, long id) {
                Toast.makeText(
                        getApplicationContext(),
                        ((TextView) v.findViewById(R.id.item_title))
                        .getText(), Toast.LENGTH_SHORT).show();
                String videoFilePath = FILE_PATH + fileList[position];
                System.out.println("******************************videoFilePath****************" + videoFilePath);
                System.out.println("******************************MiME_TYPE****************"+ MIME_TYPE);
                //                Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
                //                File newFile = new File(videoFilePath);
                //                intent.setDataAndType(Uri.fromFile(newFile), MiME_TYPE);
                //                startActivity(intent);
                Intent intent = new Intent(VideoListActivity.this, VideoViewActivity.class);
                intent.putExtra("videopath", videoFilePath);
                startActivity(intent);
            }
        });

    }

    private void setActionListeners() {
        // TODO Auto-generated method stub
        goBack.setOnClickListener(new View.OnClickListener() {

            @SuppressLint("NewApi")
            @Override
            public void onClick(View view) {
                // TODO Auto-generated method stub
                //Clear up VM heap stack
                System.gc();
                finish();
            }
        });
    }

    public static String FormatDate(Date yourDate) {

        SimpleDateFormat sdf = new SimpleDateFormat("mm:ss",Locale.US);

        return sdf.format(yourDate);

    }

    public void updateVideoList() {
        File videoFiles = new File(MEDIA_PATH);
        Log.d("*********Value of videoFiles******", videoFiles.toString());
        System.out.println(MEDIA_PATH);
        if (videoFiles.isDirectory()) {
            fileList = videoFiles.list();
        }
        if (fileList == null) {
            System.out.println("File doesnot exit");
            Toast.makeText(this, "There is no file", Toast.LENGTH_SHORT).show();
        } else {
            System.out.println("fileList****************" + fileList);
            for (int i = 0; i < fileList.length; i++) {
                Log.e("Video:" + i + " File name", fileList[i]);
            }
        }
    }

    public static Bitmap scaleBimtap(Bitmap bitmap, int width, int height) {
        final int bitmapWidth = bitmap.getWidth();
        final int bitmapHeight = bitmap.getHeight();

        final float scale = Math.min((float) width / (float) bitmapWidth,
                (float) height / (float) bitmapHeight);

        final int scaledWidth = (int) (bitmapWidth * scale);
        final int scaledHeight = (int) (bitmapHeight * scale);

        final Bitmap decoded = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);

        return decoded;
    }

    private class ProcessImageTask extends AsyncTask<Void, Void, Bitmap> {

        private Handler mHandler;
        private ImageView mImageView;
        private String mUri;

        public ProcessImageTask(Handler handler, ImageView imageView, String uri) {
            mHandler = handler;
            mImageView = imageView;
            mUri = uri;
        }

        protected void onPreExecute(){
            super.onPreExecute();
            pDialog = new ProgressDialog(mContext);
            pDialog.setMessage("Loading Playlist...");
            pDialog.show();
        }

        @Override
        protected Bitmap doInBackground(Void... v) {
            FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
            mmr.setDataSource(mUri);

            //here you change the thumbnail frame
            Bitmap bmThumbnail = mmr.getFrameAtTime(2000000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST); // frame at 2 seconds
            if(bmThumbnail !=null){
                scaleBimtap(bmThumbnail, 20, 20);

            }
            mmr.release();
            //-----------------
            return bmThumbnail;
        }

        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            //-----------------
            if (bitmap != null) {
                System.out
                .println(">>>>>>>>>>>>>>>>>>>>>>>>>>>> THUMB NAIL>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                mImageView.setImageBitmap(bitmap);
                mHandler.sendEmptyMessage(0);

            } else {
                System.out
                .println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>NO THUMB NAIL>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            }
            pDialog.dismiss();
        }
    }

    public class ImageAdapter extends BaseAdapter {
        private final Context context;
        private final String[] VideoValues;

        public ImageAdapter(Context context, String[] VideoValues) {
            this.context = context;
            this.VideoValues = VideoValues;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            System.out.println("***********IngetView************");
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View listview;

            if (convertView == null) {

                listview = new View(context);    
                listview = inflater.inflate(R.layout.gridlayout, null);          
                TextView textView = (TextView) listview
                        .findViewById(R.id.item_title);      
                TextView tv_time = (TextView) listview
                        .findViewById(R.id.tv_time);

                textView.setText(fileList[position]);
                System.out.println("value of fileList[position]" + fileList[0]);
                // set image
                ImageView imageThumbnail = (ImageView) listview
                        .findViewById(R.id.item_image);
                int msec = MediaPlayer.create(context, Uri.fromFile(new File(FILE_PATH + fileList[position]))).getDuration();

                tv_time.setText(FormatDate(new Date(msec)));
                System.out
                .println(">>>>>>>>>>>>>>>>>>>>>>>>>>>> file path>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
                        + fileList[position]);
                /*FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
                                mmr.setDataSource(FILE_PATH + fileList[position]);

                                //here you change the thumbnail frame
                                Bitmap bmThumbnail = mmr.getFrameAtTime(2000000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST); // frame at 2 seconds

                                mmr.release();
                                //-----------------
                                if (bmThumbnail != null) {
                                        System.out
                                        .println(">>>>>>>>>>>>>>>>>>>>>>>>>>>> THUMB NAIL>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        imageThumbnail.setImageBitmap(bmThumbnail);
                                } else {
                                        System.out
                                        .println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>NO THUMB NAIL>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                }*/

                new ProcessImageTask(mHandler, imageThumbnail, FILE_PATH + fileList[position]).execute();

            } else {
                listview = convertView;
            }
            return listview;
        }
        @Override
        public int getCount() {
            // return 0;
            return VideoValues.length;
        }
        @Override
        public Object getItem(int position) {
            return null;
        }
        @Override
        public long getItemId(int position) {
            return 0;
        }
    }


}

person AndroidKrayze    schedule 24.02.2014    source источник
comment
В чем проблема? Переместите pDialog.dismiss(); из if, чтобы ProgressDialog отклонялось, даже если bitmap равно нулю   -  person Apoorv    schedule 24.02.2014
comment
Я хочу закрыть pdialog, как только все ImageViews будут заполнены...   -  person AndroidKrayze    schedule 24.02.2014
comment
Я переместил его из оператора if, но pdialog все еще продолжает отображаться после заполнения ImageViews.   -  person AndroidKrayze    schedule 24.02.2014
comment
Разместите отредактированный код здесь.   -  person Apoorv    schedule 24.02.2014
comment
Вы пытаетесь заполнить все ImageView, но эта AsyncTask, похоже, заполняет только один ImageView. Означает ли это, что вы создаете несколько ProgressDialog, отправляя несколько AsyncTasks, по одному на ImageView?   -  person PaF    schedule 24.02.2014
comment
Где, черт возьми, декларация pDialog? Разве это не статично?   -  person Milan Baran    schedule 24.02.2014
comment
Да, это частная статика... Я обновлю код до полного класса..   -  person AndroidKrayze    schedule 24.02.2014
comment
Привет, Паф, Нет, я фактически не заполняю ListView, который имеет настраиваемый макет, содержащий imageView...   -  person AndroidKrayze    schedule 24.02.2014
comment
Я разместил полный класс, пожалуйста, обратитесь к нему! Спасибо!   -  person AndroidKrayze    schedule 24.02.2014
comment
Просто удалите свой статический ProgressDialog и сделайте его частной переменной в своей AsyncTask! Он должен работать.   -  person Milan Baran    schedule 24.02.2014
comment
@AndroidKrayze На самом деле это означает, что у вас есть несколько ImageView (внутри вашего ListView).   -  person PaF    schedule 24.02.2014


Ответы (3)


Проблема в том, что вы снова и снова создаете новые ProgressDialogs и теряете ссылку на старые.

Поскольку я не вижу pDialog, объявленного где-либо внутри вашего AsyncTask, я предполагаю, что он внешний. С другой стороны, вы, очевидно, создаете несколько AsyncTask для работы с несколькими изображениями. Это означает, что вы запускаете код несколько раз:

pDialog = new ProgressDialog(mContext);

Каждый раз теряя старый ProgressDialog.


Предлагаемое решение:

Добавьте счетчик вместе с pDialog:

private static ProgressDialog pDialog;
private static int pDialogCounter = 0;

Затем измените onPreExecute() на:

protected void onPreExecute(){
    super.onPreExecute();
    if(pDialog == null) {
        pDialog = new ProgressDialog(mContext);
        pDialog.setMessage("Loading Playlist...");
        pDialog.show();
    }
    ++pDialogCounter;
}

и измените onPostExecute() на:

protected void onPostExecute(Bitmap bitmap) {
    super.onPostExecute(bitmap);
    ...
    if(--pDialogCounter == 0) {
        pDialog.dismiss();
        pDialog = null;
    }
}

Таким образом, вы будете создавать диалоговое окно, только если оно не существует, и закрывать его только в том случае, если у вас больше нет запущенных асинхронных задач.

person PaF    schedule 24.02.2014
comment
Благодарим PaF за правильное решение. Спасибо!! - person AndroidKrayze; 24.02.2014

Вызовите конструктор и поместите pDialog.dismiss(); снаружи, если еще

protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
//-----------------
if (bitmap != null) {
    System.out
    .println(">>>>>>>>>>>>>>>>>>>>>>>>>>>> THUMB NAIL>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    mImageView.setImageBitmap(bitmap);
    mHandler.sendEmptyMessage(0);

} else {
    System.out
    .println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>NO THUMB NAIL>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
}
pDialog.dismiss();
}
person Vivek Warde    schedule 24.02.2014
comment
Привет Warde и спасибо за код, но загрузчик продолжает крутиться! - person AndroidKrayze; 24.02.2014

Попробуйте это:

ProgressDialog dialog; 

protected void onPreExecute() {
          dialog = ProgressDialog.show(importExportActivity.this, "",
                                  "Loading Playlist...", true);
    }

    @Override
    protected void onPostExecute(final Void success) {
          dialog.dismiss();
    }
person Rakesh    schedule 24.02.2014