I'm implementing an app that uses many methods that requires an AsyncTask with a waiting dialog.
Actually my approach is to use every time an inner class that extends AsyncTask
something like
private class AsyncOperation extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute(){
pDialog = new ProgressDialog(CurrencyConverterActivity.this);
pDialog.setMessage("Waiting...");
pDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
...
return null
}
protected void onPostExecute(Void params){
pDialog.dismiss();
runOnUiThread(new Runnable() {
public void run() {
//dialogs according status the
//int status is a static variable declared in external class
}
});
}
since with this approach i have to write this inner class too many times and this result in dirty code not well readable, I'm looking for a smarter solution
Could someone help me?
Are you calling the same network each time you use the async task?
If yes, then you can have one class which extends the async and pass the values for each call. You can have response listener to get the response from the method called the async
Something like this:
MainActivity:
First method:
AsyncOperation asyncCall = new AsyncOperation(MainActivity.this, "abc", "bcd");
asyncCall.execute();
Second method:
AsyncOperation asyncCall = new AsyncOperation(MainActivity.this, "aaa", "bbb");
asyncCall.execute();
callback(…){
}
Async Class:
private class AsyncOperation extends AsyncTask<Void, Void, Void> {
AsyncOperation(listener, string, string)
{
}
#Override
protected void onPreExecute(){
pDialog = new ProgressDialog(CurrencyConverterActivity.this);
pDialog.setMessage("Waiting...");
pDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
...
return null
}
protected void onPostExecute(Void params){
pDialog.dismiss();
listener.callback(…);
}
You can create an AsyncTask in a separate file (not as an inner class) and reuse it many times. AsyncTask doesn't have to be an inner class.
You may need to modify your AsyncTask to take additional parameters if needed to make it reusable.
You can also create a constructor for your AsyncTask with parameters for the values you need to pass into it and use that constructor to instantiate your AsyncTask.
This approach makes sense if the way you use AsyncTasks in different places is the same or at least similar. If you use completely different code in each AsyncTask, you will be better off with separate AsyncTasks (though you may still extract them into separate classes from inner classes).
Related
private class CreateGridTask extends AsyncTask<Void, Void, Void> {
private CreateGridTask() {
}
protected Void doInBackground(Void... voidArr) {
GridView.this.grid.create(((WordSearchApplication) GridView.this.getContext().getApplicationContext()).getLexicon());
return null;
}
protected void onPostExecute(Void voidR) {
GridView.this.startTime.setToNow();
GridView.this.onGridReadyListener.onGridReady();
GridView.this.invalidate();
}
}
public interface OnGridReadyListener {
void onGridReady();
}
public interface OnWordFoundListener {
void onWordFound(Word word, int i);
}
Android Studio GridView error getting while doInBackground with AsyncTask method, where i done wrong in code pls and this
You should not create the grid this way.
Instead, you should implement BaseAdapter. If cells have a number of particularly heavy operations, you may use AsyncTask within the adapter. Keep in mind, AsynTask starts a thread that is not attached to the UIThread and should not manipulate the UI until onPostExecute is called (Even then, use caution. Especially with a GridView where views may have been recycled)
As it stands, AsyncTask is really cluttering my code. I need to use it for something, and the doInBackground piece is used in different pieces of code. However, the onPostExecute changes.
I don't want to feed everything into one method like:
function doThis(String tag) {
new AsyncTask<String, Void, String>() {
#Override
protected String doInBackground(Void... params) {
// Do that thing that needs to be done.
}
#Override
onPostExecute(String message) {
if (tag.equals("login")) {
// Do large segment of logging in code.
} else if (tag.equals("register")) {
// Do other large segment of registering code
} ... //and it goes on
}
}
Is there another way to do this? Or, is there a better way to wait to process things once the work done in the background is finished?
One approach: Inheritance.
abstract class BaseTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(Void... params) {
// Do that thing that needs to be done.
}
}
...
class LoginTask extends BaseTask {
#Override
onPostExecute(String message) {
// just the "login" part here
}
}
Similarly for other task types.
You can create a separate class which extends AsyncTask. Then create an interface which your activity can implement and its method can be called inside onPostExecute. However you need to pass your activity reference to this new class.
I have a login system consisting of the following elements:
LoginActivity uses LoginController uses RestClient to call a web service with Execute(). I want the call to the web service to be performed asynchronously but I also need a dialog box to notify the user of relevant information while the call is being made. Execute does not return anything.
How will I go about doing this ? Where do I use AsyncTask ?
AsyncTask has a few methods that will help you with this.
Extend the AsyncTask:
public class MyTask extends AsyncTask<Object, Void, Void>
#Override
protected void onPreExecute() {
// show progress dialog
}
#Overrride
protected Void doInBackground(Object... params) {
HttpUriRequest req = (HttpUriRequest) params[0];
String myString = (String) params[1];
// connect
return null;
}
#Override
protected void onPostExecute(Void result) {
// hide dialog
}
}
To execute this with parameters, try this:
myTask.execute(request, "aString");
Where request is an object of type HttpUriRequest. Remember the order of the parameters matter.
If you want to update the status while the service is connecting you can use this method as Rasel said:
onProgressUpdate() {
// Update view in progress dialog
}
Hi i am developing android application. I am calling web services to get the data from the Server. Now on one activity i am calling around 15 - 20 web services on onCreate method. Now i want to code it in such a way that after the response of 1st Service is received then only the other web service call. But i don't know how to maintain it. Any help or suggestions are appreciated.
Thank you.
its simple...
you have to use AsyncTask class.
extend this class
override the following methods
(i) doinBackground (this method will run when you first start the AsyncTask)
(ii) onPostExecute (When doInBackgroun completed its work, this method starts executing)
run the Async class.
explanation:
you just do your web service calling in doInBackground and execute another AsyncTask ,which has another service call in its doinBackground, in onPostExecute.
summary: execute AsyncTrask class from onPostExecute and call webservice in doInBackground.
here i am giving you some code snippet:
class ExecuteRest1 extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
//Call your first web service here
return null;
}
#Override
protected void onPostExecute(Void result) {
new ExecuteRest2.execute();
}
}
class ExecuteRest2 extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
//Call your second web service here
return null;
}
#Override
protected void onPostExecute(Void result) {
new ExecuteRest3.execute();
}
}
//And so on....
in onCreate():
new ExecuteRest1.execute();
I'm currently doing something like this in the AsyncTask's onPostExecute method, where NewTask is not the current task that's executing:
private class OlderTask extends AsyncTask<String, Void, Integer> {
//other functions (not important)
#Override
protected void onPostExecute(Integer result) {
new NewTask().execute(null, null);
}
}
I'm wondering if this is a bad idea. Will doing so cause GC for the OlderTask to wait for the NewTask? Are there any other possible problems with using such an approach?
And if this is a problem, how can I rectify it?
Unless NewTask is inner non static class in OlderTask it will not prevent GC from collecting OlderTask unless you store reference to it in some other way.
But even if GC will wait until NewTask is done it should not be a big deal unless you save lot of data in OlderTask or create lots of copies of OlderTask.
So if your design requires doing that, it's ok. But it surely cleaner not to have chained tasks.
I use a callback method, So when result comes to onPostExecute I call another AsynkTask from UI, I think it is good idea, Let me know what do you think.
public class PatientSearchController extends AsyncTask < String, Void, String > {
private PatientSearchResultHandler handler = null;
public void onResultHandler(PatientSearchResultHandler handler) {
this.handler = handler;
}
#Override
protected String doInBackground(String...params) {
}
#Override
protected void onPostExecute(String result) {
this.handler.onResultSuccessHandler(result);
}
}