Kotlin / anko

Pleasant Android application development

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

doAsync corrouting task seems to have a time limit

carlos-mg89 opened this issue · comments

Hi,

I'm testing the anko doAsync corroutine to start with this library that seems pretty interesting and clean.

At first glance, it seemed that everything was working alright, but somehow I have bumped into an issue related with a maximum time for the async task that's limiting seriously my code.

This is my code (a call to unzip a file and a method to unzip it):

doAsync {
    unzipFile(fileToUnzip, destination)
}

// Sorry for mixing Java and Kotlin code, but that's how I have it
public static void unzipFile(String zipFile, String location)
    {
        try {
            unzipInputStream(new FileInputStream(zipFile), location);
        } catch (Exception e) {
            Log.e("", "Unzip exception", e);
        }
    }

    public static void unzipInputStream(InputStream inputStream, String location)
    {
        try {
            if ( !location.endsWith(File.separator) ) {
                location += File.separator;
            }
            File f = new File(location);
            if(!f.isDirectory()) {
                f.mkdirs();
            }
            ZipInputStream zin = new ZipInputStream(new BufferedInputStream(inputStream, BUFFER_SIZE));
            try {
                ZipEntry ze;
                while ((ze = zin.getNextEntry()) != null) {
                    String path = location + ze.getName();
                    File unzipFile = new File(path);

                    if (ze.isDirectory()) {
                        if(!unzipFile.isDirectory()) {
                            unzipFile.mkdirs();
                        }
                    } else {
                        createParentDirectoriesIfMissing(unzipFile);
                        unzipFile(zin, unzipFile);
                    }
                }
            } finally {
                zin.close();
            }
        } catch (Exception e) {
            Log.e("", "Unzip exception", e);
        }
    }

    private static void createParentDirectoriesIfMissing(File unzipFile)
    {
        File parentDir = unzipFile.getParentFile();
        if ( null != parentDir ) {
            if ( !parentDir.isDirectory() ) {
                parentDir.mkdirs();
            }
        }
    }

    private static void unzipFile(ZipInputStream zin, File unzipFile) throws IOException
    {
        int size;
        byte[] buffer = new byte[BUFFER_SIZE];
        FileOutputStream out = new FileOutputStream(unzipFile, false);
        BufferedOutputStream fout = new BufferedOutputStream(out, BUFFER_SIZE);

        try {
            while ( (size = zin.read(buffer, 0, BUFFER_SIZE)) != -1 ) {
                fout.write(buffer, 0, size);
            }

            zin.closeEntry();
        } finally {
            fout.flush();
            fout.close();
        }
    }

And this is the code I had before using Anko:

Thread(Runnable {
    run {
        unzipFile(fileToUnzip, destination)
    }
}).start()

The code before using Anko works perfectly fine. It unzips my zip file and all it's contents. It has been used many many times and it always works fine.

However, when I migrated it to Anko (which I expected it'll work normally), now my zip files are only partly unzipped. Some of the files aren't being extracted. And it ONLY happens while using the doAsync instead of the runnable thread.

To be honest, I would prefer using Anko. It has proved to be cleaner and simpler, and way easier to remember than the current setup. Perhaps there is any limitations with the kind of task it can be done? Or there is a maximum time for the async task to be done?

Thanks in advance

doAysnc returns a Feature object, you need to await it. the doAsync may start slower than the thread version since it is backed by a ScheduledThreadPool, your unzip task may have to wait in the task queue for a while.

In the Thread version, how do you know the unzip operation is complete?

I'm using a BroadcastReceiver that awaits for a download to be completed. Once it completes, the the BroadcastReceiver.onReceive method gets an Intent with the information I need to unzip the downloaded file.

So actually this thread is already being called outside the user flow. And in that onReceive call, I simply open a thread (the one I tried to replace by Anko version) where I unzip the file.

But it makes sense now I had to wait for the doAsync to finish. Will test the Anko doAsync version somewhere else in my app, where I want to achieve a multithreaded code, so it runs faster with parallel threads for different tasks.

Thanks for replying back!