I have two activities an "EventsList" which extends ListView and a "CreateEvent" Activity. The user can pick "Events" from the list and edit them in the CreateEvent activity. When the user clicks save CreateEvent than spawns an AsycTask to communicate the data to a webservice, gets a response and parses the response into the database.
My problem is I dont know how to communicate the result from the AsycTasks onPostExecute() to the EventsList activity. I tried refreshing the list on StartActivityForResult but the thread often hasn't completed itself by this point.
So, how do I communicate the result of the AsyncTask (spawned by CreateEvent) to the EventsList activity? I had no luck trying to use a custom callback.
Edit
I'm really not keen on using a global flag or adapter. I'm sure this is best done using a callback/Listener somehow. That way the list is only changed or notified when absolutely necessary.
from EventsList startActivityForResult "CreateEvent" .
inside async task put data as putExtra's in case large or complex dataType you want to transfer use application level data storage or static instance .
in onActivityResult of EventsList read data by putExtra or static intent .
I think if you fill data of list adapter of EventsList activity (As adapter has a global reference) in AsyncTask and onPostExecute() of AsyncTask just finish() the CreateEvent activity which lends you to EventsList's onActivityResult() now in this just call notifydatasetChanged() for adapter.
You could always use a BroadcastReceiver, and broadcast a completion action from your AsyncTask's onPostExecute() with whatever extras you want your activity to receive. If you need to pass an object in the result, create a model object that implements Parcelable, and send the Parcelable as an extra in your intent.
Related
1. here my Order of execution
SplashActivity : two AsyncTask (each have different result and I want to Intent to next Activity when each AsyncTask Parsing and putParcelableArrayList completed.
MainActivity : getParrcelableArrayList from SplashActivity
In addition
-already implemented parcelable in the model class.
-The values in the array are well stored.
2. my Answer
how to Intent and startActivity when each AsyncTask complated putParcelableArrayList
please, need your help!!
if you don't unberstand, write comment please!
There are two possible ways to achieve this,
one way, you can call second AsyncTask in onPostExecute of first one, and then call the intent from onPostExecute of second.
Another way is you can call some common method which will set two boolean global parameters, on completion of first AsyncTask make one boolean true on same way for another and once both values are true you can call intent from that method.
I have another one question about transfering data from Activity to Fragment.
In my activity I have next situation: one part of UI is situated in Activity, and another (more dynamic part) is situated in Fragment.
The data which I need to populate my UI elements in Activity and Fragment is on server. To get that data, I am sending request to
server in Acvitity's onCreate() method. In Activity's callback method: void onDataLoaded(List<MyObject> dataList) I get data from server.
And in this method I am creating my Fragment and setup data to it. I am passing data to it through the Bundle object duding creation. Everything
is ok with this. But the issue is in next: on network reconnect I need to load data from server to be sure that all data is up to date. And of course I
need to reinitialize data in Activity and Fragment. But I don't want to fully RE-CREATE fragment. I want just to setup new data to it's fields.
How can I do that properly? Is it a good way to to keep reference in my Activity to that Fragment and call some public method: myFragment.SetMyCustomData(List<MyObject> dataList) ?
I understand that the best way to load data from server in my fragments onCreate() method, but I can't split it into two API calls and I need that data in Activity as well.
Thanks.
Well this is not a transfering problem . Anyway you can use Event Bus for easier communication from Activity to Fragment and vice-versa. It is very easy to use . And as for your problem I belive you are not doing what you need in the right time .
https://github.com/greenrobot/EventBus
I have a viewpager fragment setup, and I have an AsyncTask run at the start of the activity to load some data from a JSON get (the data it pulls only needs to be done once, and all fragments will use it). The problem I'm having is I want to take this data from the AsyncTask, and have it be the data that all of the textviews pull from in the fragments.
What would be the best way to load data from an AsyncTask and then have the fragments reference that data. You cant just have the views reference the data from the get-go as it Nullpointers, and I'd really like to avoid having to reference every single textview in the OnPostExecute of the AsyncTask if I had it in the Parent Activity.
Just decouple the storage of the data from the view(s). In that way it will be easyer to handle the download of the data and to show it in the various fragments once the get is completed.
The basic idea is: launch the download in a background thread decoupled from the activity (service or intent service), then update the data a storage (sqllite if it is complex, shared preferences or even a singleton object, even though I don't like the latter approach).
Once the get is performed, inform the fragments that the data is available. Still, you have a lot of options here. If you decided to host the thread / asynctask inside a service, you can bind a callback to it and then notify all the fragments interested, you can use a (local) broadcast message that you can intercept using local broadcast receivers, or you can even use a message bus such as otto.
Finally, I really recommend to use an intent service to perform the async job. It's the easiest way to do any one shot operations without having to deal with service creation and/or with activity configuration changes.
Not sure if this is the "best" way, but what comes to my mind first is the famous Observer pattern.
Create an interface called Observer with a single method called
notify()
Implement this interface in all Fragments that want to be notified when the data is ready
Hold a List of Observer objects inside your AsyncTask
In onPostExecute(), traverse this List and call notify() on every Observer, passing the appropriate data
React on the notification inside your Fragments given the data
This a very rough description of this solution, but I hope you get the idea.
It might be an easy question but I have been working on it for hours and couldn't solve it. Sorry if it was asked before.
In my activity I have 2 Fragments. In one fragment I am getting JSON from server and putting in ArrayList. After putting in ArrayList I have to add another fragment passing first value in ArrayList.
Here is the problem, I want to add Fragment when my ArrayList is completed, after it got all values from server. I am making service call in my onActivityCreated() method, server call is happening in another class and I am getting Bundle in a method called onRequestFinished() and I am putting JSON to ArrayList in this Overridden method.
P.S. I tried to put AsyncTask but I couldn't make it since I have to wait the response from onRequestFinished() method.
How can I handle it and complete Fragment Transaction after filling my ArrayList?
Thanks
I suggest using startActivityForResult in the first fragment. When the parent activity receives the onActivityResult it can then start the second fragment. There are plenty of examples of how to do this on SO and elsewhere.
Even if you do not want to start an activity, you can use the same mechanism to communicate back to the activity when your first fragment has completed e.g.:
Is there a method that works like start fragment for result?
Alternatively you could of course just implement a callback mechanism from your first fragment - but personally, I like the onActivityResult approach.
My problem is follow (I know that selected structure of my classes looks like bizarre, but ...).
I have the MainActivity with inner class, that extends AsyncTask to parse HTML from internet.
This activity parses HTML-page and fills the ListView in AnotherActivity.
AnotherActivity must call the inner AsyncTask and PostExecute must fill the ListView by another data (the sense of this actions that AnotherActivity is results of search and another search means the going to new page of search's results of YouTube)
I wrote the next code in PostExecute of AsyncTask:
where I get Activity with ListView, create adapter and assign it to ListView.
ResultsQueryActivity resultsActivity = new ResultsQueryActivity();
ResourceDataAdapter resourceDataAdapter = new ResourceDataAdapter(resultsActivity,MainActivity.listVideosData);
resultsActivity.setListAdapter(resourceDataAdapter);
After execution of this I get the message
*02-01 07:40:56.784: E/AndroidRuntime(525): java.lang.IllegalStateException: System services not available to Activities before onCreate()*
I really have no idea how to resolve it. Thanks for help!
Why do you have two activities, when both of them seem need to be done on the same activity?
Just use one activity. When parsing is done, update the ListView with your data, then show the ListView. Initially the ListView would be hidden. Your other views (if any) would be hidden as well.
Or use a ListActivity, doesn't really make a difference.
I would guess it has something to do with the way you are creating ResultsQueryActivity... Typically you would start it via an Intent and pass all your video data to it by putting it into a Bundle. Try replacing your code in postExecute() with something like this (assuming your video data is a String array):
Intent intent = new Intent(MainActivity.this, ResultsQueryActivity.class);
intent.putExtra("videodata", MainActivity.listVideosData);
startActivity(intent);
Then in the ResultsQueryActivity class, you can retrieve the data in the onCreate(Bundle b) method:
Bundle extras = getIntent().getExtras();
String[] videodata = extras.getStringArray("videodata");
You cannot instantiate a activity, activities is managed by system.
The flow of the two activity is not very well.
If MainActivity is only used to parse html, then it should not exist. Put the the asynctask in AnotherActivity and fill the list in postExecute.
If MainActivity must exist, then you should not fill data in the task. Try to parse the data to AnotherActivity, and let it fill data by itself.