Return value from AsyncTask class onPostExecute method
I guess you are trying to read class A variable before it is being set..
Try to do it using callbacks..in the callback function pass the values and refresh your spinners..
You can create interface
, pass it to AsyncTask
(in constructor), and then call method in onPostExecute
For example:
Your interface:
public interface OnTaskCompleted{
void onTaskCompleted(values);
}
Your Activity:
public YourActivity implements OnTaskCompleted{
//your Activity
YourTask task = new YourTask(this); // here is the initalization code for your asyncTask
}
And your AsyncTask:
public 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(values);
}
}
return value after run another AsyncTask in onPostExecute()
Problem: You want to pass the array list from the second AsyncTask back to MainActivity.
Solution: Passing activity instance to the first AsyncTask, then forward the instance to the second AsyncTask.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Pass `this` as activity instance to the first AsyncTask.
DownloaderGet downloaderGet = new DownloaderGet(this, "http://xxxxx.php");
downloaderGet.execute();
}
public void onDataAvailable(List<String> arrauList) {
// Process array list here.
}
}
// The first AsyncTask.
class DownloaderGet extends AsyncTask<Void, Void, String> {
private WeakReference<MainActivity> activity;
private String url;
DownloaderGet(MainActivity activity, String url) {
this.activity = new WeakReference<>(activity);
this.url = url;
}
@Override
protected String doInBackground(Void... voids) {
// Your code here
// ...
return null;
}
@Override
protected void onPostExecute(String jsonData) {
// Forward the instance to the second AsyncTask.
new DataParserGet(activity.get(), jsonData).execute();
}
}
class DataParserGet extends AsyncTask<Void, Void, Boolean> {
private WeakReference<MainActivity> activity;
private String jsonData;
DataParserGet(MainActivity activity, String jsonData) {
this.activity = new WeakReference<>(activity);
this.jsonData = jsonData;
}
@Override
protected Boolean doInBackground(Void... voids) {
// Your code here
// ...
return null;
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
myNewArrayList = spacecrafts;
if (activity.get() != null) {
// Pass the array list back to main activity.
activity.get().onDataAvailable(myNewArrayList);
}
}
}
}
Return a value from AsyncTask in Android
Why not call a method that handles the value?
public class MyClass extends Activity {
private class myTask extends AsyncTask<Void, Void, Void> {
//initiate vars
public myTask() {
super();
//my params here
}
protected Void doInBackground(Void... params) {
//do stuff
return null;
}
@Override
protected void onPostExecute(Void result) {
//do stuff
myMethod(myValue);
}
}
private myHandledValueType myMethod(Value myValue) {
//handle value
return myHandledValueType;
}
}
How do I return value from AsyncTask class to another class?
AsyncTask
is called async for a reason.
In the following code you execute your AsyncTask
and then immediately try to access one of its fields:
FetchZipTask fzt = new FetchZipTask();
fzt.execute(location);
loc = fzt.locale;
That won't work because FetchZipTask
may still be running when you're trying to access its locale
variable.
onPostExecute()
is called when the task is finished, so you should pass your result from there.
You could define an interface in FetchZipTask
, pass an instance of it as a constructor param and call the appropriate method on that instance in onPostExecute()
:
public class FetchZipTask extends AsyncTask<String, Void, String> {
// declaring a listener instance
private OnFetchFinishedListener listener;
// the listener interface
public interface OnFetchFinishedListener {
void onFetchFinished(String result);
}
// getting a listener instance from the constructor
public FetchZipTask(OnFetchFinishedListener listener) {
this.listener = listener;
}
// ...
// calling a method of the listener with the result
@Override protected void onPostExecute(String result) {
listener.onFetchFinished(result);
}
}
In your Activity
, pass an OnFetchFinishedListener
when instantiating your AsyncTask
:
new FetchZipTask(new FetchZipTask.OnFetchFinishedListener() {
@Override
public void onFetchFinished(String result) {
// do whatever you want with the result
Uri geoLocation = Uri.parse("geo:"+ result);
Log.d("Debug", geoLocation.toString());
Intent in = new Intent(Intent.ACTION_VIEW);
in.setData(geoLocation);
if (in.resolveActivity(getPackageManager()) != null) {
startActivity(in);
}
}
}).execute();
And that's it. Orientation change may still be a problem, so you could move your AsyncTask
in a headless Fragment
, or consider using a Service
instead.
Returning a string onPostExecute() in Async class
I had the exact same problem a few months back now. Found this back then and it worked for me. Hope it helps!
Return value from AsyncTask class onPostExecute method
How to handle return value from AsyncTask
You can get the result by calling AsyhncTask's get() method on the returned AsyncTask, but it will turn it from an asynchronous task into a synchronous task as it waits to get the result.
String serverResponse = apiObj.execute(nameValuePairs).get();
Since you have your AsyncTask in a seperate class, you can create an interface class and declare it in the AsyncTask and implement your new interface class as delegate in the class you wish to access the results from. A good guide is here: How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?.
I will attempt to apply the above link to your context.
(IApiAccessResponse)
public interface IApiAccessResponse {
void postResult(String asyncresult);
}
(ApiAccess)
public class ApiAccess extends AsyncTask<List<NameValuePair>, Integer, String> {
...
public IApiAccessResponse delegate=null;
protected String doInBackground(List<NameValuePair>... nameValuePairs) {
//do all your background manipulation and return a String response
return response
}
@Override
protected void onPostExecute(String result) {
if(delegate!=null)
{
delegate.postResult(result);
}
else
{
Log.e("ApiAccess", "You have not assigned IApiAccessResponse delegate");
}
}
}
(Your main class, which implements IApiAccessResponse)
ApiAccess apiObj = new ApiAccess (0, "/User");
//Assign the AsyncTask's delegate to your class's context (this links your asynctask and this class together)
apiObj.delegate = this;
apiObj.execute(nameValuePairs); //ERROR
//this method has to be implement so that the results can be called to this class
void postResult(String asyncresult){
//This method will get call as soon as your AsyncTask is complete. asyncresult will be your result.
}
Related Topics
Overriding Referenced Style Attributes
Android Device Gps On/Off Programmatically
Rotating Phone Quickly 180 Degrees, Camera Preview Turns Upside Down
Is Ondestroy Not Always Called
Upload Video to Facebook in Android
Findclass from Any Thread in Android Jni
How to Automatically Restart a Service Even If User Force Close It
Webview Showing Err_Cleartext_Not_Permitted Although Site Is Https
Android N Requires the Ide to Be Running with Java 1.8 or Later
What Is the Meaning of Addtobackstack with Null Parameter
Cannot Launch Avd in Emulator:Qt Library Not Found
Avoid Button Multiple Rapid Clicks
Android SQLite: Update Statement
How to Show Shadow Around the Linearlayout in Android
How to Auto-Start an Android Application
How to Get Release Build APK File Using Proguard
Adb Connection by Wifi Getting Killed When a New Usb Attached/Detached