Alan Wang
Alan Wang

Reputation: 153

How to Loop 2 AsyncTasks?

any answers would be much appreciated.

I have two AsyncTasks, one that measures download speed and one that measures upload speed. I want the app to continuously measure download and upload speeds until the user says stop. Right now, I have a toggle button that keeps crashing because of OutOfMemoryError:

togglebutton = (ToggleButton) findViewById(R.id.toggleButton);
togglebutton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            while (isChecked) {
                new Download.execute();
                new Upload.execute();
            }
        } else {
            // The toggle is disabled
        }
    }
});

When I click the toggle button, the app freezes and then crashes. I'm assuming creating multiple instances of my Asynctasks are the cause of the problem. Is there any better way to implement this?

Note: I don't think looping in doInBackground will work because the Asynctasks need to run in an alternating fashion, i.e. Download.execute, Upload.execute, Download.execute, Upload.execute...

Here's the logcat:

03-25 23:31:36.261 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art: Throwing OutOfMemoryError "Failed to allocate a 28 byte allocation with 0 free bytes and 3GB until OOM" (recursive case)
03-25 23:31:36.261 15881-15881/com.kingrandesigns.uploadpicturetutorial I/art: Alloc sticky concurrent mark sweep GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 0% free, 128MB/128MB, paused 25.421ms total 29.582ms
03-25 23:31:36.261 15881-15894/com.kingrandesigns.uploadpicturetutorial I/art: WaitForGcToComplete blocked for 29.847ms for cause Background
03-25 23:31:36.261 15881-16557/com.kingrandesigns.uploadpicturetutorial I/art: WaitForGcToComplete blocked for 877.665ms for cause Alloc
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art: "JDWP" daemon prio=5 tid=3 Runnable
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:   | group="system" sCount=0 dsCount=0 obj=0x12c5f080 self=0xaf20e400
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:   | sysTid=15888 nice=0 cgrp=apps sched=0/0 handle=0xb4922200
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:   | state=R schedstat=( 2731136812 186756673 920 ) utm=267 stm=6 core=0 HZ=100
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:   | stack=0xb4366000-0xb4368000 stackSize=1012KB
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:   | held mutexes= "mutator lock"(shared held)
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:     at java.nio.ByteBuffer.wrap(ByteBuffer.java:113)
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:     at org.apache.harmony.dalvik.ddmc.ChunkHandler.wrapChunk(ChunkHandler.java:80)
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:     at android.ddm.DdmHandleHeap.handleHPIF(DdmHandleHeap.java:112)
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:     at android.ddm.DdmHandleHeap.handleChunk(DdmHandleHeap.java:85)
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial E/art:     at org.apache.harmony.dalvik.ddmc.DdmServer.dispatch(DdmServer.java:171)
03-25 23:31:36.271 15881-15888/com.kingrandesigns.uploadpicturetutorial I/art: Exception thrown by dispatcher for 0x48504946

Upvotes: 0

Views: 275

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317342

Take a good look at this code:

    if (isChecked) {
        while (isChecked) {
            new Download.execute();
            new Upload.execute();
        }
    } else {
        // The toggle is disabled
    }

When the checkbox is checked for the first time, you're entering into an infinite loop that keeps creating new instances of Download and Upload until it runs out of memory. The main thread will never enter an idle state where the checkbox can be checked again.

Bear in mind that execute on AsyncTask returns immediately while the AsyncTask gets scheduled for work on another thread. When you call execute, it is not waiting for the task to complete.

Upvotes: 1

Related Questions