Return value from AsyncTask class onPostExecute method - android

Ok so now I have Class A that contains some spinners that values will be populated by Class B that extends AsnycTask which grabs the spinner values from a web service. In class B i manage to retrieve the values, showing in a Toast. The problem now is how do I pass those spinner values back to Class A?
I've tried
Can OnPostExcecute method in AsyncTask RETURN values?
by passing Class A to Class B and store the value in a public variable of Class A like below
#Override
protected void onPostExecute(String result)
{
classA.classAvariable = result;
}
However whenever I try to read the classAvariable i always get a NullPointer Exception.
Seems like the variable was never assigned with the result.
For readability purpose I needed to seperate Class B instead of using as an inline class.
Any ideas my fellow Java programmers?

Problem here is that when you execute your AsynchTask, its doInBackground() methode run in separate thread and the thread that have started this AsynchTask move forward, Thereby changes occur on your variable by AsynchTask does not reflect on parent thread (who stated this AsynchTask) immediately.
Example --
class MyAsynchTask
{
doInbackground()
{
a = 2;
}
}
int a = 5;
new MyAsynchTask().execute();
// here a still be 5

Create a interface like OnCompletRequest() then pass this to your ClassB constructor and simply call the method inside this interface such as complete(yourList list) in the method of onPostExecute(String result)

You can retrieve the return value of protected Boolean doInBackground() by calling the get() method of AsyncTask class :
E.g. you have AsyncTask class as dbClass like
dbClass bg = new dbClass(this);
String Order_id = bg.execute(constr,data).get();
Here I am passing constr as URL and data as string of inputs to make my class dynamic.
But be careful of the responsiveness of the UI, because get() waits for the computation to complete and will block the UI thread.

Related

How to compare the value from handler with the value in activity/fragment in Android

There are 3 handler in my fragment all those contain AsyncTask, and the fragment contains an int value, for example 50. Here what I wanted to do is to compare those 3 int value (which I am fetching in those 3 AsyncTask in handler) with the int value defined in fragment. For example if AsyncTask in handler-1 gets 80, AsyncTask in handler-2 gets 10, AsyncTask in handler-3 gets 46, then I want to compare these 3 ints with that fragment int.
I forgot to tell that after comparison, mFragmentValue needed to update with new value from onPostExecute().
My code is big to post here, so here is an example:
class MyFragment{
int mFragmentValue = 50;;
void onViewCreated(){
handler1.post(calling AsyncTask here using runnable); //Here I get 80 in onPostExecute in MyAsyncTask, now I need to compare this 80 with mFragmentValue. These AsyncTasks are sub class of my fragment.
handler2.post(calling AsyncTask here using runnable); //Here I get 10 in MyAsyncTask, now I need to compare this 10 with mFragmentValue;
handler3.post(calling AsyncTask here using runnable); //Here I get 46 in MyAsyncTask, now I need to compare this 46 with mFragmentValue;
}
static class MyAsyncTask extend AsyncTask{
void onPostExecute(){
// getting int here.
//need to compare fetched int with mFragmentValue;
}
}
}
If you only need the value of mFragmentValue in MyAsyncTask, then you can pass it in directly:
class MyFragment{
int mFragmentValue = 50;;
void onViewCreated(){
AsyncTask task = new MyAsyncTask();
task.execute(mFragmentValue);
}
static class MyAsyncTask extend AsyncTask{
int mTaskValue;
void doInBackground(Integer...values) {
mTaskValue = values[0];
}
void onPostExecute(){
// Now use mTaskValue
}
}
}
Note that there is no need to use a Handler nor a Runnable with an AsyncTask. The purpose of a Handler is to facilitate communication between threads, but AsyncTask already takes care of this for you. In addition, doInBackground() already runs on its own thread and onPostExecute() runs on the main thread, so there is no need to create a Runnable.
If you need to change the value of mFragmentValue, then MyAsyncTask must have a reference to the Fragment. You can do this by making MyAsyncTask non-static or add a constructor which accepts a Fragment as a parameter (or some interface which your fragment implements). Either way, you must find another way to address the memory leak warning. One solution here to add a method to MyAsyncTask that you can call from onPause(), onStop(), or onDestroy(). Calling this method tells the AsyncTask that the Fragment reference will is no longer valid. Then the AsyncTask acts accordingly, probably by aborting its work in doInBackground().

can use variables from doitbackground in onpostexecute

I have a inner class of asynctask in a class. I defined some variables arrays in that inner class. In doitbackground, i put some values into them.
When i go go onpostexecute, i can use them because they are all in same inner class.
So, i dont need to return something for pass? I am really confused. Is that a bad way, should i define all those inside doitbackground?
Because if i have to pass values, i need to define wrapper because i have to pass 4-5 arraylists. They are different types. But now i can use them and no need return or pass.
I am searching but there is no information about this. In all asyntask examples, they define variables outside of doitbackground.
I usually create a class with these fields in a doInBackground, and pass this class as a result.
This also allows you to pass null if an error happened.
class DataClass {
private int someIntData;
private String someStringData;
}
new AsyncTask<Void, Void, DataClass>() {
#Override
protected DataClass doInBackground(Void... params) {
DataClass data = new DataClass();
// doing some job
if (!errorHappened) {
data.someIntData = 5;
data.someStringData = "Just an example string";
return data;
}
return null;
}
#Override
protected void onPostExecute(DataClass result) {
if (result != null) {
// handle the result
} else {
// error happened
}
}
};
Technically you can do it, but think about encapsulation concept
as you know,
doitbackground happen in another thread than ui thread
onpostexecute happen in ui thread
so there is common pattern that send AsyncTask parameters in Constructor or Execute Argument, by this way, you can make your self sure that Async class can be reused maybe in another application and fully encapsulated.

How AsyncTask returns parameters to MainActivity

I am new to android. I have written a asynctask class which takes one string as parameter. Asynctask class has two functions doinbackground and onpostexecute. doinbackground is doing a httppost and if the post is successful it is returning a string "Success" to onpostexecute or pasing "Failed" to onpostexecute.
In Mainactivity I am calling the Asyncclass like below:
new MyAsyncTask().execute(xmlFile);
But I need to get the string that doinbackground returns in my mainactivity as based on this status I need to update a database filed. Can anyone help me on this issue.
Hypothetically I want to do the below in MainActivity
////////////////////////
Run the asyncclass by passing a string;;;
if doinbackground returns "Success" update database
else don't update
///////////////////////////
Thanks
You can use interface as a callback to the activity.
You can check blackbelts answer in the below link
How do I return a boolean from AsyncTask?
Or you can make AsyncTask an inner class of activity and get the result in onPostExecute.
You have several ways. One is using a Handler, to intercommunicate the Activity with your AsyncTask. This would involve passing the Handler object from the Activity to the AsyncTask and storing it there, so you can later use it. more on this here.
Another way is using a BroadcastReceiver. You declare it where you want to use it (i.e., where you want to receive the data, in this case in your Activity) and you use sendBroadcast from the AsyncTask to the Activity. More on this here.
There are more ways, but this ones are the most widely used.
You could probably just do your database update in the doInBackground instead of the onPostExecute that way you have your result and whether or not the http call passed.
Or you could have the AsyncTask return a class with whether or not it succeeded and the result then deal with it in onPostExecute, but you're back on the UI thread at that point and might not want to block with a db update.
private class PostResult {
boolean succeeded;
String response;
}
private class PostAsync extends AsyncTask<String, String, PostResult> {
protected PostResult doInBackground(String... xmlToPost) {
PostResult result = new PostResult();
try {
//do you httpPost... with xmlToPost[0];
result.response = "your data back from the post...";
result.succeeded = true;
//get your string result
}catch (Exception ex){
result.succeeded = false;
}
// I would update the db right here,
// since it's still on the background thread
return result;
}
protected void onPostExecute(PostResult result) {
//you're back on the ui thread...
if (result.succeeded){
}
}
}

Android: How to retrieve values from an AsyncTask?

I've been researching all day trying to find out how to retrieve the values computed in the doInBackground async task. No luck at all.
I'm doing a basic HttpURLConnection request and parsing some XML data from a webpage using the DOM. I successfully store the data in two different arrays
///////////inside doInBackground:
for(int x=0; x<10; x++)
{
username[x] = element.getFirstChild().getNodeValue();
score[x] = anotherElement.getFirstChild().getNodeValue();
}
Now, all I want to do is simply output the values onto a textView.
Among many other things, I have attempted:
protected void onPostExecute(String result)
{
for (int xx = 0; xx<10; xx++)
{
theMainTextView.append(username[xx] + " scored " + score[xx] +"\n");
}
}
Nothing I have attempted works. A recurring error I'm receiving is the NullPointerException. Am I doing something dramatically incorrect? Know of any other (even obscure) methods I could try? Ignore the for loops if that helps...I've omitted a lot of code. Just assume I want to retrieve two values...a username and a score.
Edit: I should probably mention that the AsyncTask ends with return null;
Edit: apparently the code is not faulty but I had a globally declared button which was causing a null Pointer Exception. Sorry about that.
If you get a NullPointerException as stated in the question and this is all of your onPostExecute() code than the field theMainTextView must be null.
You must initialize it before starting the AsyncTask - best place to do so is in onCreate() for Activities or onCreateView() for Fragments.
Although it's not the best practice, your code should work. I think the problem comes from another part. Can you please specify what line is throwing the NullPointerException?
To retrieve values from an AsyncTask you can use listener.
First create interface listner (new file):
public interface AsyncListener {
void onAsyncFinishMethod(String params);
}
Second, use implement for your main class where you call async task (example)
public class MainActivity implements AsyncListener {
Third, create full body for listener method in your main class. You are overriding method from interface. So if you change params you will have to change too in interface. Here you will get all results after task finish and call onPostExecute.
#Override
public void onAsyncFinishMethod(String params) {
Log.d("xxx", params);
}
Fourth, set listener for your async task. It means: In your async task class create this method
public void setOnAsyncFinishedMethod(AsyncListener listener) {
this.listener = listener;
}
Make sure, your async task has private param with type that listener
private AsyncListener listener;
In onPostExecute in async task class call listener method as a last (if you don't have this method, please create it)
#Override
protected void onPostExecute(String params) {
listener.onAsyncFinishMethod(param);
}
Last step, during calling async task in your main class don't forget bind setOnAsyncFinishedMethod method to it
My Example:
private void runMyAsyncTask() {
CustomAsync async = new CustomAsync();
async.setOnAsyncFinishedMethod(this);//<<< before execute use setOnAsyncFinishedMethod
thread.execute();
}
Of course, params used in onAsyncFinishedMethod could be different than you, also onPostExecute.

Can OnPostExcecute method in AsyncTask RETURN values?

I am developing an Android application which requires the use of AsyncTask for Network connection. I called it from the main thread. So the doInBackground method runs and then returns to the onPostExecute method. After the onPostExecute method is executed, I want to return a value back to the activity from where it was called, as I have to some operation in that particular activity which requires the value returned from onPostExecute method.
How do I solve this? How do I return a value from onPostExecute ?
Thanks in Advance
AsyncTask, as its name stated, is running asynchronously with UI thread, the onPostExecute method will be called at some point in the future, when doInBackground finished. We don't care when onPostExecute method will be called (actually there is no way to tell at project build time), the only thing we care is onPostExecute method is guaranteed to be called properly by underlying framework at some point in the future. So the purpose of onPostExecute method is for processing result returned from worker thread, this is also why the only argument of onPostExecute method is the result returned from doInBackground method.
I have to some operation in that particular activity which requires the value returned from onPostExecute method. How do I solve this?
Of cause, you can create some instance variables (or use listerner pattern) in the Activity class store the result when returned and ready in onPostExecute method. The problem is you never know when this result is ready outside onPostExecute method at project build time, as it is actually determined at app runtime. Unless you write some waiting mechanism continuously polling the result, which resulting sacrifice the benefit of AsyncTask, for instance, the built-in API AsyncTask.get() which makes AsyncTask running synchronously with UI thread and return the result to the Activity.
The best practice is change your design and move the operation code which requires the result returned from AsyncTask into onPostExecute method. hope this helps.
you can use getter and setter for getting value back from AsyncTask
public class MainActivity extends Activity {
public String retunnumfromAsyncTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layouttest);
new Asyntask(this).execute();
}
public class Asyntask extends AsyncTask<Void, Void, String> {
private final Context Asyntaskcontext;
public Asyntask(Context context){
Asyntaskcontext = context;
}
#Override
protected void onPostExecute(String result) {
MainActivity mainactivity = (MainActivity) Asyntaskcontext;
mainactivity.retunnumfromAsyncTask = result;
super.onPostExecute(result);
}
}
}
Just write the AsyncTask class as inner class to your activity then, declare whatever the value you want to return as global. Was it helpful to you?

Categories

Resources