I am running a book services app on android where the user downloads the book onto his device.The book files are 1mb and above. Can Async Task be considered as the best practice for this kind of operation. Are there any other approaches to performing downloads in the background thread. Please Advice.
-
http://stackoverflow.com/questions/3028306/download-a-file-with-android-and-showing-the-progress-in-a-progressdialog?rq=1 – Yuva Raj May 13 '15 at 07:57
-
whether 1mb or 1kb all network call are advised to do in background thread and not on main thread so using Async Task is best for all cases. – Nikunj Sakhrelia May 13 '15 at 09:22
1 Answers
Generally it is beleived that AsyncTask is not meant for long running tasks, but sometimes it is a simple way to perform a simple task (no matter how much time it will take). But the thing is,some of the developers perform it in a wrong way.
public class MainActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Somewhere the AsyncTask is started
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
@Override protected String doInBackground(Void... params) {
// Do work
return result;
}
@Override protected void onPostExecute(String result) {
Log.d("MyAsyncTask", "Received result: " + result);
}
}
}
The Problem with the above code is, When you start an AsyncTask inside an Activity and you rotate the device or any configuration change happens, the Activity will get destroyed and a new instance will be created. But the AsyncTask will not die and keep on going until it completes.
Problems
1) Since activities are heavy, this could lead to memory issues if several AsyncTask are started.
2) Another issue is that the result of the AsyncTask could be lost, if it's intended to act on the state of the activity.
So we need to fix two problems
1) Activity should not be kept in memory when destroy by the framework.
2) Result of the AsyncTAsk should be delivered to the current Activity Instance.
And to Solve these Problems we need otto http://square.github.io/otto/
To use otto create a MyBus.java which we have to use it as a singleton
public class MyBus {
private static final Bus BUS = new Bus();
public static Bus getInstance() {
return BUS;
}
}
Create a AsyncTaskResultEvent.java file
public class AsyncTaskResultEvent {
private String result;
public AsyncTaskResultEvent(String result) {
this.result = result;
}
public String getResult() {
return result;
}
}
Now in your MainActivity, Do AsyncTask
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
@Override protected String doInBackground(Void... params) {
Random random = new Random();
final long sleep = random.nextInt(10);
try {
Thread.sleep(sleep * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Slept for " + sleep + " seconds";
}
@Override protected void onPostExecute(String result) {
MyBus.getInstance().post(new AsyncTaskResultEvent(result));
}
}
Now the Activity that starts the AsyncTask will get the result later.
To fix the memory leak problem add the below code in MainActivity
@Override protected void onDestroy() {
MyBus.getInstance().unregister(this);
super.onDestroy();
}
@Subscribe public void onAsyncTaskResult(AsyncTaskResultEvent event) {
Toast.makeText(this, event.getResult(), Toast.LENGTH_LONG).show();
}
and put this line of code in your OnCreate Method
MyBus.getInstance().register(this);
Now If a configuration change happens we'll automatically be notified of the result in the new Activity instance since it's registered to the event bus.

- 375
- 3
- 9