简体   繁体   中英

Android: How to show ProgressDailog from Async Task in Activity from another Pack?

I'm still trying to make my first App. So, it grows... and i try divide it to few Packeges. My first Pack works with Files, it will contains classes which can: download files, read data from files and et.c.

So i try to move out of my main activity first class, but have problem with ProgressDialog it does not work. So i have few qwestions:

1) What is the best way to sent % of downloading to activity of My App? 2) What will happens, if user changes current Activity during download progress?

package com.domen.myapplication.Files;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.PowerManager;
import android.widget.Toast;


import com.domen.myapplication.R;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by DL  on 01.08.2016.
 */
public class DownloadTask extends AsyncTask<String, Integer, String> {

    private Context context;
    private PowerManager.WakeLock mWakeLock;
    public int progress=0;
    public int progressShow=0;
    public ProgressDialog mProgressDialog;




    public DownloadTask(Context context) {
        this.context = context;

        mProgressDialog = new ProgressDialog(this.context);
        mProgressDialog.setMessage(this.context.getResources().getString(R.string.loading_empty));
        mProgressDialog.setIndeterminate(true);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setCancelable(true);


    }

    @Override
    protected String doInBackground(String... sUrl) {
        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(sUrl[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            // expect HTTP 200 OK, so we don't mistakenly save error report
            // instead of the file
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return "Server returned HTTP " + connection.getResponseCode()
                        + " " + connection.getResponseMessage();
            }

            // this will be useful to display download percentage
            // might be -1: server did not report the length
            int fileLength = connection.getContentLength();

            // download the file
            input = connection.getInputStream();
            //output = new FileOutputStream("/sdcard/file_name.extension");


            File cacheFile = new File(this.context.getCacheDir(), "FIRMWARE");

            output = new FileOutputStream(cacheFile);

            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                // allow canceling with back button
                if (isCancelled()) {
                    input.close();
                    return null;
                }
                total += count;
                // publishing the progress....
                if (fileLength > 0) // only if total length is known
                    publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }
        } catch (Exception e) {
            return e.toString();
        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException ignored) {
            }

            if (connection != null)
                connection.disconnect();
        }
        return null;
    }


    //метод выше (doInBackground) запускается отдельным поток все сотальное ниже в главном потоке
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // take CPU lock to prevent CPU from going off if the user
        // presses the power button during download
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                getClass().getName());
        mWakeLock.acquire();
        progressShow=1;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        // if we get here, length is known, now set indeterminate to false
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgress(progress[0]);
        this.progress=progress[0];
    }

    @Override
    protected void onPostExecute(String result) {
        mWakeLock.release();
        progressShow=1;
        mProgressDialog.dismiss();
        if (result != null)
            Toast.makeText(context, "Download error: " + result, Toast.LENGTH_LONG).show();
        else
            Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT).show();
    }


}

If you want to download the file only in the activity, Make AsyncTask as a inner class in the activity and use it.

But if you want to download file irrespective of Activity, Create a service and implement the download logic in the service and show a file download progress notification from service and update it with download percentage, Just like Play Store app download progress.

Your second question What will happens, if user changes current Activity during download progress?

Yes, Async Task will be running even after the activity is destroyed, until it finishes its job. check this link for more info https://stackoverflow.com/a/13147992/1066839

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM