Android AsyncTask and How To Make It Less Painful

If you are an android developer you probably know for doing tasks that take too much time from processor or tasks that keep the user waiting for couple of seconds if you run such task on current thread, android will  freeze the UI therefore you have to develop your application in multi-threading fashion and one of the solutions for making the app multi-threaded is by using AsyncTask abstract class.

Let us check the way of using AsyncTask in a very simplistic example :

(Assume you want to get a page from a url) :

 private class DownloadFilesTask extends AsyncTask {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }
 
     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }
 
     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

For executing AsyncTask:

new DownloadFilesTask().execute(url1, url2, url3);

Reference : http://developer.android.com/reference/android/os/AsyncTask.html

But what if you want to use AsyncTask in several different places?
Suppose you want to do several different tasks (e.g. counting a long list or process a text, etc…) If you want to implement AsyncTask everywhere you will end up with a stack of codes which are literally doing the same thing but with very minor changes.

So I thought how can I make it less painful?
I started to write one generic class for AsyncTsak to make it generic and I ended up with something as  following :

But its not the whole story for using this generic class I invent a technique (not quite sure if I can call it “design pattern”) to make it easier to use you need to create following interface as well:

Then inside your actual class you need to implement the ITask and then initialize  the overridden  methods then at the end instantiate the ParrelelTask class to run the actual AsyncTask class behind the scene.

here you can download the sample code to see it in action.

Conclusion

By the help of this technique I manage to reduce lines of codes from several classes inside my real application but yet this technique is not efficient and I think it still can be polished to become less confusing, and remember AsyncTask is not very efficient  in terms of doing several tasks at the same time. The whole idea of AsyncTask is keeping away the UI from freezing for having an actual muti-thread application you need to use JAVA threading APIs.

At the end let me know if you have better way of designing a technique or pattern for calling AsyncTask.

Deep dive into the C macros

Not long ago I was reading an article about C macro and its potential pitfalls and author suggested not to use them more often in the code and he mentioned about some example such as following to expose the problem of macros :

#include <stdio.h>
#define MAX(x,y) ((x) > (y) ? (x) : (y))
int increment(){
static int i=45;
i+=5;
return i;
}
int main(int c,char ** v)
{
int x=20;
printf("the maximum number between %d and %d is : %d",x,increment(),MAX(x,increment()));
return 0;
}

If you try to run this code you will see a very interesting result which makes most of the programmer suspicious about accuracy of C programming language, but the problem is not C. It is resides on macros mechanism and the way compiler treat the macros.

I disassembled the complied version and following is output

.file "macroTest.c"
 .text
 .globl increment
 .type increment, @function
increment:
.LFB0:
 .cfi_startproc
 pushq %rbp
 .cfi_def_cfa_offset 16
 .cfi_offset 6, -16
 movq %rsp, %rbp
 .cfi_def_cfa_register 6
 movl i.2162(%rip), %eax
 addl $5, %eax
 movl %eax, i.2162(%rip)
 movl i.2162(%rip), %eax
 popq %rbp
 .cfi_def_cfa 7, 8
 ret
 .cfi_endproc
.LFE0:
 .size increment, .-increment
 .section .rodata
 .align 8
.LC0:
 .string "the maximum number between %d and %d is : %d"
 .text
 .globl main
 .type main, @function
main:
.LFB1:
 .cfi_startproc
 pushq %rbp
 .cfi_def_cfa_offset 16
 .cfi_offset 6, -16
 movq %rsp, %rbp
 .cfi_def_cfa_register 6
 pushq %rbx
 subq $40, %rsp
 .cfi_offset 3, -24
 movl %edi, -36(%rbp)
 movq %rsi, -48(%rbp)
 movl $20, -20(%rbp)
 movl $0, %eax
 call increment
 cmpl -20(%rbp), %eax
 jl .L4
 movl $0, %eax
 call increment
 movl %eax, %ebx
 jmp .L5
.L4:
 movl -20(%rbp), %ebx
.L5:
 movl $0, %eax
 call increment
 movl %eax, %edx
 movl -20(%rbp), %eax
 movl %ebx, %ecx
 movl %eax, %esi
 movl $.LC0, %edi
 movl $0, %eax
 call printf
 movl $0, %eax
 addq $40, %rsp
 popq %rbx
 popq %rbp
 .cfi_def_cfa 7, 8
 ret
 .cfi_endproc
.LFE1:
 .size main, .-main
 .data
 .align 4
 .type i.2162, @object
 .size i.2162, 4
i.2162:
 .long 45
 .ident "GCC: (Ubuntu/Linaro 4.7.2-4precise1) 4.7.2"
 .section .note.GNU-stack,"",@progbits

As you see there is no clue about macros in compiled code in other words all the macros will be replaced by proper C code during compilation and if you look at assembly code carefully you will see the increament() function called by main() three times rather than two times and the reason is code replacement of compiler.

printf("the maximum number between %d and %d is : %d",x,increment(),MAX(x,increment()));

In above line after calling MAX macro we send the increment() function to MAX macro whereas the defintion of MAX is :

#define MAX(x,y) ((x) > (y) ? (x) : (y))

and the compiler will translate it to something like :

((x) > (increment()) ? (x) : (increment())

as you can see we’re going to get two increment() function in MAX and one in printf() statement and thats the reason of having three calling to increment() inside assembly code.

Conclusion

I am not big fan of making tasks convoluted and I personally think for having a lean and working code its good to step aside from mixed code or combined languages when its unnecessary and this inspection shows how complex it could be in case of using an approach without knowing it thoroughly. So next time think more before making your code complex.

Happy coding!

System.out.print(“Hello World”);

Hi there,

I am Seyed Vahid Hashemi(MscEng) software engineer also an enthusiastic software developer.

I start developing software since I was 14 but as a professional software developer I start when I graduated from high school.

I have been working with different firms form small to big in different areas such as news, media, advertisement, live broadcasting channel, print industry, etc…

I don’t mind about different programming languages or platforms, what I mostly care is best practices in terms of design patterns, approaches, managing projects in software engineering and adapt them in different platforms and technologies.

Here I will share my thoughts and experiences with rest of the world, I will put my thoughts into a bottle  and send it to the vast ocean of internet hope to find the right person at the right time!

You can find me on LinkedIn