AsyncTask Save Variables from doInBackground - android

I have two AsyncTasks as inner classes in my Activity. One returns an ArrayList in doInBackground and asigns a ListAdapter to it on postExecute. The other AsyncTask returns a StringArray and sets some TextViews.
On Rotation everything is gone, also the layout changes on Rotation.
I'd like to have access to the results of the doInBackground-Methods. If I had access I could just simply save the variables in onSaveInstanceState and reasign the values manually.

You can access the results of doInBackground in onPostExecute.
Simply change your class to:
public class YourTask extends AsyncTask<Void, Void, ObjectYouWantToReturn> {
#Override
protected ObjectYouWantToReturn doInBackground(Beneficiary... params) {
ObjectYouWantToReturn obj = new ObjectYouWantToReturn();
//... do your stuff
return obj;
}
#Override
protected void onPostExecute(ObjectYouWantToReturn result) {
//there you go, here you have the results from doInBackground
}
}

Shared preferences is solution of your problem i think.
revise the link given below.
http://developer.android.com/guide/topics/data/data-storage.html#pref
http://thedevelopersinfo.com/2009/11/25/getting-sharedpreferences-from-other-application-in-android/

Related

Android Fragment + AsyncTask

In a fragment I'm using an 'AsyncTask' to retrieve data from a URL. The main purpose of my code is to access the data (via AsyncTask) and to pass a 'JSONArray' to the fragment.
Problem is, on the fragment side, that when I check the variable that should have the result i get an error saying that the variable is null.
Here is the code:
public class MyFragment extends ListFragment {
//this is the variable that should have the result from the AsyncTask
JSONArray myResult = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
(...)
//execute the asyncTask
new GetResult().execute(email, password);
(...)
}
//The AsyncTask
private class GetResult extends AsyncTask<String, Void, JSONArray> {
#Override
protected JSONArray doInBackground(String... params) {
(...)
JSONArray jsonArray = (JSONArray) json.get("customer");
return jsonArray;
}
protected void onPostExecute(JSONArray result){
(...)
//this is where I try to pass the data to the fragment
MyFragment.this.myResult = result;
}
}
}
Can someone can help me with that? Thank you in advance.
Are you using the value after postExecute method. You should know that after calling execute, your code on the main thread still runs and only after postExecute has completed, will you have the value.
Try to use this code, and make sure that your jsonstring is not null, because you won't post your complete code and I can't see if myResult variable was changed:
try {
JSONArray json = new JSONArray(jsonstring);
JSONObject json_customer = json.getJSONObject("customer");
return json_customer;
} catch (JSONException e) {
return null
}
For me it looks like problem with deserialization from String data to json's. We are lack of information what exactly data you are parsing. Consider using for this some more advanced json processing library lika Gson or Jackson. Usually its easier with them.
It sounds like you are trying to read from myResult variable before the AsyncTask finishes retrieving it. To make sure it populates properly, put this into your onPostExecute function, after this line MyFragment.this.myResult = result;:
Log.i("my result value is: ", MyFragment.this.myResult.toString())
It should print it out in the LogCat if you are retrieving it correctly, and you should be able to access that variable after that.
On a separate note, consider using Volley or Retrofit or another networking plugin to make your life easier.
Maybe you can use a clear way to transfer data back from the task to the fragment.
1) define an interface as the event listener to be called in the AsyncTask, like
public interface TaskEventListener(){
public void onTaskStarted(int messageId);
public void onTaskStopped(int messageId, int resultCode);
public void onDataReady(Object parameter);
}
2) let the fragment implement this EventListener, put the processing code in the onDataReady() function.
3) pass the fragment instance as the EventListener instance.
4) in the class extended from the AsyncTask, call the onTaskStarted() in the onPreExecute() function, call the onDataReady() and onTaskStopped() in the onPostExecute() function, and call the onTaskStopped() only in the onCancelled() function.
5) please use the weak references in the background task class to prevent crashing for referring the invalid UI component.

how check doinbackground(Void.. ar) method is completed in android

I am creating a program that fetch the value from online . I have use AsynTask class for background process. i am fetching the some values from web and set value in class variables.My problem is that values are setting in variables in very late. and my execution processed further and find variables values null. How can i check that doInBackground() method is processed completely and values are sets in variable. so that i can use these variables values.
One of the best method is to use a kind of observer design pattern.
So first create an Interface with contain a method (depend on your return value, etc) :
public interface OnTaskCompleted{
void onTaskCompleted(String xml);
}
Then you need to implement this interface to your activity wich instantiate your asynctack, see:
public class MainActivity extends SherlockFragmentActivity implements OnTaskCompleted
Then to finish, you gonna pass the instance of MainActivity (wich by polymorphisme is also OnTaskCompleted) to your asyntask. Here my asyntask class handler is named XMLParser
public class XMLParser {
private OnTaskCompleted listener;
public XMLParser(OnTaskCompleted mainActivity, String url){
getXMLFromURL(mainActivity,url);
}
[......]
//here when the work is done you call the OnTaskComplete Method
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//CALL HERE
listener.onTaskCompleted(result);
}
}
I hope it'll help you. Works like a charm for me.

Call different callback from AsyncTask onPostExecute()

I have implemented an internal AsyncTask for my class that does initial setup data query from server and stores into device cache. The setup data in split between 2 JSON files. The first JSON is read/cached and if certain conditions are on then second JSON file will be downloaded and stored into cache. I want to use same AsyncTask from both operations.
In doInBackground(), I perform JSON download operation independent of JSON type. But in onPostExecute() I want to call different callbacks depending if its 1st JSON file or second, since they require different handling. Is that possible?
EDIT: Pls note I do not want to use booleans, enum to decide which callback to call as in future I will have more files to process. From my calling class I want to set the callback and rest should happen automatically.
Below implementation should solve your problem:
private class MyCustomAsyncTask extends AsyncTask<Void, Void, Void>{
private boolean mShouldCallMethod1;
public MyCustomAsyncTask(boolean shouldCallMethod1){
mShouldCallMethod1 = shouldCallMethod1;
}
#Override
protected Void doInBackground(Void... params) {
//code goes here..
return null;
}
#Override
protected void onPostExecute(Void result) {
if(mShouldCallMethod1){
method1();
}else{
method2();
}
}
}
i.e have a customized AsyncTask as innerclass.
If you use the same interface which contains the two callbacks this is no problem. Simply declare an interface with 2 callback methods (json1, json2) and pass an instance of the interface to the AsyncTask.
In your onPostExecute() you can call the callback(s).
As android does not support setListner Methods for onPostExccute so there is two ways:
Extend AsychTask and imlement setOnPostExcuteListner
Or just call "your method" from onPostExcute simple!

Android asynctask with no input or output

I have set up an async task that will get a list of countries from a wsdl and from the result i create a bunch of country objects and add the objects to an arraylist in the country class file.
I want to be able to run this async task that will populate the array list then from another view be able to call specific indexes from the array list based on what the user has selected.
i have tried creating a class that extends AsyncTask and i have inserted the same code from the gingerbread version of the app i created which worked fine because network actions could be ran from the main thread
The type getWSDL2 must implement the inherited abstract method AsyncTask.doInBackground(Object...)
i dont have any objects to pass to this i all variables and stuff to get the wsdl data is within the async task and all the data i need from it is assigned to the arraylist from within the async task.
public class getWSDL2 extends AsyncTask {
protected void doInBackground()
{
........
}
Pass Void... as a parameter for doInBackground
protected void doInBackground(Void... params)
{
........
}
The way I understand your question you're not sure how to implement the AsyncTask because you have no need to pass values into it. All of the variables and data you need are included within the code that will execute the transaction with your server to download whatever it is you intend to display.
public class getWSDL2 extends AsyncTask {
protected Void doInBackground(Void... params) {
//All I/O code here
}
protected Void onPostExecute(){
//Anything that needs to run on the UI thread here
}
}
The general structure of the AsyncTask is listed above. The doInBackground method must contain any I/O functions while any thing you do tha touches a view, i.e. displaying the results of you're query as saved in a array list, must be called from onPostExecute, which runs on the UI thread.
From what I gather the solution is simple. Put all the code that is required for your server transaction within the doInBackground method. If you need to display the results of that transaction in a view just add a return statment to doInBackground and include the type of object/variable you will return in the varargs listed for the AsyncTask. For example if you were going to display the result of an ArrayList generated in your doInBackground method
public class getWSDL2 extends AsyncTask {
protected ArrayList<String> doInBackground(Void... params) {
//All I/O code here
return nameOfArrayListYouBuild
}
protected Void onPostExecute(ArrayList<String> whatever){
//use ArraList whatever to display your stuff
}
}
In the alternative if you don't need to display anything or run any functions on the UI thread then don't use the onPostExecute method at all.
public class getWSDL2 extends AsyncTask {
protected Void doInBackground(Void... params) {
//All I/O code here
return null
}
}
You can structure you're task so that it just uses doInBackground

Android setText of multiple TextView from AsyncTask

I've used the AsyncTask example from vogella website, I've created a class file with it.
I'm calling it from Activity A to update the postalcode's TextView, it's working.
I'm wondering how can I call the same AsyncTask from Activity B to update another postal code TextView.
So one AsyncTask, 2 calls from different Activities to update different TextViews.
I've to do something onPostExecute(), right?
Some example code, is much appreciated.
Thanks in advance
You can (I guess) pass the TextView to the AsyncTask when you instantiate it.
All without the IDE open so apologies if the syntax is off...
public class ExampleTask extends AsyncTask<Void, Void, Void> {
private TextView targetTextView;
public ExampleTask(TextView target) {
targetTextView = target;
}
#Override
protected String doInBackground(Void... orSomething) {
//do work and get a value I guess
}
#Override
protected void onPostExecute(String result) {
targetTextView.setText(result);
}
}
Then you'd call this:
ExampleTask task = new ExampleTask(theTextViewToUpdate);
task.execute();
You'd want to be careful about the scope of the task objects you instantiate as that reference to a TextView could end up leaking memory from your activities.
Here I am not good, but you can try
It is possible to reuse AsyncTask for different Activities.
For this you must take different parameter from different Activities.
In AsyncTask Class initiate a constructor with a case parameter (which is described in other activities) which will decide ,it is called by Activity A or B or C.
Now use switch case statement and move ahead.

Categories

Resources