简体   繁体   中英

Starting new Activity after finish of several Async-Tasks

I tried to Download and Unzip files if there is an update on a server and all works perfect. But I want to open the next Activity only after all files have been downloaded and unzipped, not when it started downloading.

This is my Activity:

package com.example;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class Update extends AppCompatActivity {

    private ProgressDialog ringProgressDialog;

    private static Boolean finished = false;

    private String read(String fileName) {
        StringBuilder retString = new StringBuilder();
        String zeilenumbruch = "\n";
        BufferedReader reader = null;

        try {
            File file = new File(fileName);
            FileInputStream in = new FileInputStream(Environment.getExternalStorageDirectory().toString() + "/.example/Anleitungen/.data/Versions/" + fileName);
            reader = new BufferedReader(new InputStreamReader(in));

            String zeile;
            while ((zeile = reader.readLine()) != null) {
                retString.append(zeile);
            }
            reader.close();
        } catch (IOException ex) {
            Log.e(getPackageName(), ex.getMessage());
        }

        return retString.toString();
    }

    public static String getTextOfUrl(String uri) throws Exception {

        StringBuilder result = new StringBuilder();

        URL url = new URL(uri);

        String line = null;
        BufferedReader reader = null;
        finished = false;
        try {
            reader = new BufferedReader(new InputStreamReader(url.openStream()));

            while ((line = reader.readLine()) != null) {
                result.append(line);

            }
            return result.toString();
        } finally {
            if (reader != null) {
                reader.close();
            }
            finished = true;
        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_update);

        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        final PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "Updating");
        wl.acquire();
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        AsyncTaskRunner runner = new AsyncTaskRunner();
        runner.execute();

    }

    private void downloadAndUnzipContent(String path, String urlPath) {
        String url = urlPath;
        DownloadFileAsync download = new DownloadFileAsync(path, this, new DownloadFileAsync.PostDownload() {
            @Override
            public void downloadDone(File file) {
                Log.i(getPackageName(), "file download completed");


                // check unzip file now
                Decompress unzip = new Decompress(Update.this, file, true);
                unzip.unzip();

                Log.i(getPackageName(), "File unzip completed");

            }
        });
        download.execute(url);
    }

    private void downloadContent(String path, String urlPath) {
        DownloadFileAsync download = new DownloadFileAsync(path, this, new DownloadFileAsync.PostDownload() {
            @Override
            public void downloadDone(File file) {
                Log.i(getPackageName(), "file download completed");

            }
        });
        download.execute(urlPath);
    }

    private class AsyncTaskRunner extends AsyncTask<String, String, String> {

        private String resp;

        @Override
        protected String doInBackground(String... params) {
            try {
                List<String> files = new ArrayList<String>();
                files.add("Archiv");
                files.add("Funkempfaenger");
                files.add("Funkhandsender");
                files.add("Funksender");
                files.add("Funksensoren");
                files.add("Hausautomatisierung");
                files.add("Jalousieantriebe");
                files.add("Rohrantriebe");
                files.add("SensorenKabelgebunden");
                files.add("Sonderantriebe");
                files.add("Torantriebe");
                files.add("Torsteuerungen");
                files.add("WandgeraeteKabelgebunden");

                for (int uI = 0; uI < files.size(); uI++) {
                    try {
                        String newVersion = getTextOfUrl("http://www.example.com/zip/Versions/" + files.get(uI) + ".txt");
                        int nV = Integer.parseInt(newVersion);
                        String readString = files.get(uI) + ".txt";
                        String oldVersion = read(readString);
                        int iV = Integer.parseInt(oldVersion);
                        if (iV < nV) {
                            while (!finished) {
                                Log.i(getPackageName(), "Finished = False");
                            }
                            String dlPath = Environment.getExternalStorageDirectory() + "/.example/Anleitungen/.data/" + files.get(uI) + ".zip";
                            String dlPath2 = Environment.getExternalStorageDirectory() + "/.example/Anleitungen/.data/Versions/" + files.get(uI) + ".txt";
                            downloadAndUnzipContent(dlPath, "http://www.example.com/zip/Versions/" + files.get(uI) + ".zip");
                            downloadContent(dlPath2, "http://www.example.com/zip/Versions/" + files.get(uI) + ".txt");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        publishProgress(e.toString());
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

            return "HI!";
        }

        /*
         * (non-Javadoc)
         *
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */
        @Override
        protected void onPostExecute(String result) {
            // execution of result of Long time consuming operation
            Toast.makeText(Update.this, getString(R.string.UpdateFinished), Toast.LENGTH_LONG).show();
            Intent intent = new Intent(Update.this, Home.class);
            startActivity(intent);
            finish();
        }

        /*
         * (non-Javadoc)
         *
         * @see android.os.AsyncTask#onPreExecute()
         */
        @Override
        protected void onPreExecute() {

        }

        /*
         * (non-Javadoc)
         *
         * @see android.os.AsyncTask#onProgressUpdate(Progress[])
         */
        @Override
        protected void onProgressUpdate(String... text) {
            Toast.makeText(Update.this, text[0], Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onBackPressed() {
        Log.i(getPackageName(), "Back pressed");
    }
}

This is my Decompress.class :

package com.example;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Decompress {
    private File _zipFile;
    private InputStream _zipFileStream;
    private Context context;
    private static String ROOT_LOCATION = "/sdcard";
    private static final String TAG = "UNZIPUTIL";
    private Boolean pathNew;

    public Decompress(Context context, File zipFile, Boolean path) {
        _zipFile = zipFile;
        this.context = context;
        pathNew = path;

        if (pathNew) {
            ROOT_LOCATION = "/sdcard/.example/Anleitungen";
        }

        _dirChecker("");
    }

    public Decompress(Context context, InputStream zipFile) {
        _zipFileStream = zipFile;
        this.context = context;

        _dirChecker("");
    }

    public void unzip() {
        try  {
            Log.i(TAG, "Starting to unzip");
            InputStream fin = _zipFileStream;
            if(fin == null) {
                fin = new FileInputStream(_zipFile);
            }
            ZipInputStream zin = new ZipInputStream(fin);
            ZipEntry ze = null;
            while ((ze = zin.getNextEntry()) != null) {
                Log.v(TAG, "Unzipping " + ze.getName());

                if(ze.isDirectory()) {
                    _dirChecker(ROOT_LOCATION + "/" + ze.getName());
                } else {
                    FileOutputStream fout = new FileOutputStream(new File(ROOT_LOCATION, ze.getName()));
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1024];
                    int count;

                    // reading and writing
                    while((count = zin.read(buffer)) != -1)
                    {
                        baos.write(buffer, 0, count);
                        byte[] bytes = baos.toByteArray();
                        fout.write(bytes);
                        baos.reset();
                    }

                    fout.close();
                    zin.closeEntry();
                }

            }
            zin.close();
            Log.i(TAG, "Finished unzip");
        } catch(Exception e) {
            Log.e(TAG, "Unzip Error", e);
            Toast.makeText(context, "Error while unzipping: " + e.toString(), Toast.LENGTH_LONG).show();
        }

    }

    private void _dirChecker(String dir) {
        File f = new File(dir);
        Log.i(TAG, "creating dir " + dir);

        if(dir.length() >= 0 && !f.isDirectory() ) {
            f.mkdirs();
        }
    }
}

This is my DownloadFileAsnyc.class :

package com.example;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class DownloadFileAsync extends AsyncTask<String, String, String> {

    private static final String TAG ="DOWNLOADFILE";

    public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
    private PostDownload callback;
    private Context context;
    private FileDescriptor fd;
    private File file;
    private String downloadLocation;

    public DownloadFileAsync(String downloadLocation, Context context, PostDownload callback){
        this.context = context;
        this.callback = callback;
        this.downloadLocation = downloadLocation;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... aurl) {
        int count;

        try {
            URL url = new URL(aurl[0]);
            URLConnection connection = url.openConnection();
            connection.connect();

            int lenghtOfFile = connection.getContentLength();
            Log.d(TAG, "Length of the file: " + lenghtOfFile);

            InputStream input = new BufferedInputStream(url.openStream());
            file = new File(downloadLocation);
            FileOutputStream output = new FileOutputStream(file); //context.openFileOutput("content.zip", Context.MODE_PRIVATE);
            Log.d(TAG, "file saved at " + file.getAbsolutePath());
            fd = output.getFD();

            byte data[] = new byte[1024];
            long total = 0;
            while ((count = input.read(data)) != -1) {
                total += count;
                publishProgress(""+(int)((total*100)/lenghtOfFile));
                output.write(data, 0, count);
            }

            output.flush();
            output.close();
            input.close();
        } catch (Exception e) {}
        return null;

    }
    protected void onProgressUpdate(String... progress) {
        //Log.d(TAG,progress[0]);
    }

    @Override
    protected void onPostExecute(String unused) {
        if(callback != null) callback.downloadDone(file);
    }

    public static interface PostDownload{
        void downloadDone(File fd);
    }
}

Please help me. Sorry for my bad English.

Thank you.

You are starting the new Activity whenever AsyncTaskRunner finishes executing its background job. AsyncTaskRunner is basically just launching multiple DownloadFileAsync tasks.

AsyncTaskRunner won't wait for the launched tasks to complete. It will just launch them and finish the task which causes your new Activity to start.

The optimal way to fix this is to use only one AsyncTask that process each file sequentially. A dirty way would be to make AsyncTaskRunner wait for each DownloadFileAsync task to finish before launching the next. You can do this by calling the .get() method on each task:

download.execute(url).get();

But again, this defeats the purpose of AsyncTasks.

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