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
}
Related
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'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).
I'm trying to use doInBackground method of AsyncTask to send a message to a webserver. Then use the onPreExecute() and onPostExecute(String result) methods of AsyncTask to change a text control from sending data to Fineshed.
The issue is that Inside the AsyncTask String class I cannot access any of the variables declared in the outside class. Thus I cannot change my TextView inside these methods. I get, so mSEnd.setText("Sending data")gives me mSend undefined.
Is there a way to use the variables I declare in my outside class?
public class EndOfWorldActivity extends cBase implements OnClickListener {
TextView textCountDown;
TextView textPercent;
public void onClick(View v) {
Intent i;
switch(v.getId())
{
case R.id.butVote3:
// Start ASync Task
new SendTextOperation().execute("");
break;
case R.id.buGame:
// Start ASync Task
new SendTextOperation().execute("");
break;
}
}
private class SendTextOperation extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
//Update UI here
mSEnd undefined error
mSend.setText("Sending your vote to server");
mSend.invalidate();
}
#Override
protected String doInBackground(String... params) {
// Talk to server here to avoid Ui hanging
// talk to server method undefined
TalkToServer( mYes[mPes-1] );
return null;
}
#Override
protected void onPostExecute(String result) {
// Update screen here after talk to server end
UpdateScreen();
mSend .setText("");
}
}
} // end of class
use
new SendTextOperation().execute();
instead of this
new SendTextOperation().execute("");
There is a complete example given in the link below.
The application send HTTP query to a web server and get back the content of the query :
Example: Android bi-directional network socket using AsyncTask
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 have the following block of code based on an asynctask.
I'm trying to return a List variable via return LoadFeed()
and the return type of doInBackground is String.
If I change the return type of doInBackground from String to List
then I get an error
"The return type is incompatible with AsyncTask<String,Void,String>.doInBackground(String[])"
How do I fix this error?
Please help
Thanks,
private class DispData extends AsyncTask<String, Void, String> {
private final ProgressDialog dialog = new ProgressDialog(MessageList.this);
// can use UI thread here
protected void onPreExecute() {
dialog.setMessage("Fetching scores...");
dialog.show();
}
// automatically done on worker thread (separate from UI thread)
protected String doInBackground(final String... args) {
return loadFeed();
}
// can use UI thread here
protected void onPostExecute(final List<String> result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
adapter =
new ArrayAdapter<String>(MessageList.this,R.layout.row,result);
MessageList.this.setListAdapter(adapter);
}
}
Change your class definition to:
class DispData extends AsyncTask<String, Object, List<String>>
This will force the doInBackground declaration to become:
protected List<String> doInBackground(String... arg);
First, you really should add #Override annotations to your onPreExecute(), doInBackground(), and onPostExecute() methods. On an AsyncTask, this is critical to help you keep track of all the data types.
Then, if you want doInBackground() to return List<String>, you need to change it both in doInBackground() and in your AsyncTask declaration (the third data type will need to change from String to List<String>), to go along with your change that you already made to onPostExecute().