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
Related
I have this private class that is within my main activity, and I am using it pull a JSon object off of my server into my app. The code below works fine and will display the JSon object as a string.
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
return httpBuild(urls[0]);
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
Toast.makeText(getBaseContext(), "Received!", Toast.LENGTH_LONG).show();
etResponse.setText(result);
}
}
what I am trying to do is place change the onPostExecute() method so it acts like webResult = result where webResult is an instance variable of the class mainActivity The problem is once I do this when I try to put the below code into the onCreate() method after HTTpAsyncTask has been called the app fails to display the object and crashes.
public class MainActivity extends Activity {
private static final String mainSite = "http://mysitehere";
private String webResult;
// private JSONArray floorsInBuilding, roomsInGender;
// private JSONObject room;
// private JSONArray arrayOfFloors;
// private JSONObject room, arrayOfRooms;
EditText etResponse;
TextView tvIsConnected;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get reference to the views
etResponse = (EditText) findViewById(R.id.etResponse);
tvIsConnected = (TextView) findViewById(R.id.tvIsConnected);
// check if you are connected or not
if(isConnected()){
tvIsConnected.setBackgroundColor(0xFF00CC00);
tvIsConnected.setText("You are conncted");
}
else{
tvIsConnected.setText("You are NOT conncted");
}
// call AsynTask to perform network operation on separate thread
new HttpAsyncTask().execute(this.buildBuildingAddress(8));
Toast.makeText(getBaseContext(), "Received!", Toast.LENGTH_LONG).show();
etResponse.setText(WebResult);
}
I'm wondering what makes the part of the code that displays the result dependent on the HttpAsyncTask. I'm also wondering how I can get the result of the HttpAsyncTask and store it as a string in the main class.
A good chunk of my code is based of of this example.
http://hmkcode.com/android-parsing-json-data/
I'm sorry If my knowledge of android isn't so great but my experience lies in more in java.
If you want to wait till the task is over so that you can override the result with webResult then you may use the asyncTask method onProgressUpdate which runs on UI thread. You may refer android developer site to know how to use that method.
The answer to this is that the asynchronous task runs alongside onCreate(). So you have to create some piece of code that waits for the task to complete or you have to manipulate the result of the async task in the onPostExecute() method
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).
This question already has answers here:
How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
(17 answers)
Closed 6 years ago.
I have the following asynctask class which is not inside the activity. In the activity I'm initializing the asynctask, and I want the asynctask to report callbacks back to my activity.
Is it possible? Or does the asynctask must be in the same class file as the activity?
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
caller.sometextfield.setText("bla");
}
Something like this?
You can create an interface, pass it to AsyncTask (in constructor), and then call method in onPostExecute()
For example:
Your interface:
public interface OnTaskCompleted{
void onTaskCompleted();
}
Your Activity:
public class YourActivity implements OnTaskCompleted{
// your Activity
}
And your AsyncTask:
public class YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type
private OnTaskCompleted listener;
public YourTask(OnTaskCompleted listener){
this.listener=listener;
}
// required methods
protected void onPostExecute(Object o){
// your stuff
listener.onTaskCompleted();
}
}
EDIT
Since this answer got quite popular, I want to add some things.
If you're a new to Android development, AsyncTask is a fast way to make things work without blocking UI thread. It does solves some problems indeed, there is nothing wrong with how the class works itself. However, it brings some implications, such as:
Possibility of memory leaks. If you keep reference to your Activity, it will stay in memory even after user left the screen (or rotated the device).
AsyncTask is not delivering result to Activity if Activity was already destroyed. You have to add extra code to manage all this stuff or do you operations twice.
Convoluted code which does everything in Activity
When you feel that you matured enough to move on with Android, take a look at this article which, I think, is a better way to go for developing your Android apps with asynchronous operations.
I felt the below approach is very easy.
I have declared an interface for callback
public interface AsyncResponse {
void processFinish(Object output);
}
Then created asynchronous Task for responding all type of parallel requests
public class MyAsyncTask extends AsyncTask<Object, Object, Object> {
public AsyncResponse delegate = null;//Call back interface
public MyAsyncTask(AsyncResponse asyncResponse) {
delegate = asyncResponse;//Assigning call back interfacethrough constructor
}
#Override
protected Object doInBackground(Object... params) {
//My Background tasks are written here
return {resutl Object}
}
#Override
protected void onPostExecute(Object result) {
delegate.processFinish(result);
}
}
Then Called the asynchronous task when clicking a button in activity Class.
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
Button mbtnPress = (Button) findViewById(R.id.btnPress);
mbtnPress.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {
#Override
public void processFinish(Object output) {
Log.d("Response From Asynchronous task:", (String) output);
mbtnPress.setText((String) output);
}
});
asyncTask.execute(new Object[] { "Youe request to aynchronous task class is giving here.." });
}
});
}
}
Thanks
IN completion to above answers, you can also customize your fallbacks for each async call you do, so that each call to the generic ASYNC method will populate different data, depending on the onTaskDone stuff you put there.
Main.FragmentCallback FC= new Main.FragmentCallback(){
#Override
public void onTaskDone(String results) {
localText.setText(results); //example TextView
}
};
new API_CALL(this.getApplicationContext(), "GET",FC).execute("&Books=" + Main.Books + "&args=" + profile_id);
Remind: I used interface on the main activity thats where "Main" comes, like this:
public interface FragmentCallback {
public void onTaskDone(String results);
}
My API post execute looks like this:
#Override
protected void onPostExecute(String results) {
Log.i("TASK Result", results);
mFragmentCallback.onTaskDone(results);
}
The API constructor looks like this:
class API_CALL extends AsyncTask<String,Void,String> {
private Main.FragmentCallback mFragmentCallback;
private Context act;
private String method;
public API_CALL(Context ctx, String api_method,Main.FragmentCallback fragmentCallback) {
act=ctx;
method=api_method;
mFragmentCallback = fragmentCallback;
}
I will repeat what the others said, but will just try to make it simpler...
First, just create the Interface class
public interface PostTaskListener<K> {
// K is the type of the result object of the async task
void onPostTask(K result);
}
Second, create the AsyncTask (which can be an inner static class of your activity or fragment) that uses the Interface, by including a concrete class. In the example, the PostTaskListener is parameterized with String, which means it expects a String class as a result of the async task.
public static class LoadData extends AsyncTask<Void, Void, String> {
private PostTaskListener<String> postTaskListener;
protected LoadData(PostTaskListener<String> postTaskListener){
this.postTaskListener = postTaskListener;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result != null && postTaskListener != null)
postTaskListener.onPostTask(result);
}
}
Finally, the part where your combine your logic. In your activity / fragment, create the PostTaskListener and pass it to the async task. Here is an example:
...
PostTaskListener<String> postTaskListener = new PostTaskListener<String>() {
#Override
public void onPostTask(String result) {
//Your post execution task code
}
}
// Create the async task and pass it the post task listener.
new LoadData(postTaskListener);
Done!
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();