Currently I am implementing MVP pattern for one of my module which has multiple loaders but I am facing problems in updating the Notification from the second loader call
Scenario:
Fragment invokes Presenter.loadMethod() initially to load the data in gridview and once the user clicks on individual item Presenter invokes Presenter.Download() method to download the file(not using download manager)
And I need to update the progress indication like whether the file is in download state or progress state but when the orientation is changed I am not able to update the notification bar when I use InitLoader().
I tried with restartLoader() too but still facing the same problem.
Can anyone please explain what is the best approach to solve this problem?
You need to keep list of items being downloaded, save the list in onSaveInstanceState(). Start a separate loader for every download item.
In onCreate() method, you restore the items being downloaded and reconnect to loaders by calling getLoaderManager().initLoader(itemId, null, this).
In onLoadFinished(), you should check if an item is downloaded successfully and change its state to "downloaded", then remove the item from the list.
Related
If I need to display data coming from an API in a Fragment (using an AsyncTask), let's say a list of items in a RecyclerView, I believe it shouldn't be done in onCreate() or onCreateView() since theoretically the view elements are being initialized and may not be ready to use if the call to the API is faster. Am I correct?
(I assume it's kind of impossible to get a response from an API in less time than it takes for Android to create the view though).
There is onActivityCreated() and onStart() but I am still confused about when the parent Activity calls them.
The thing I want to avoid is reloading data (making a call to the API) if it's not necessary, for instance because of an orientation change or going back to this Activity after a click on the back button from a possible "next" Activity.
Thanks.
If it is your first "window" (Activity or whatever) the only way I know is showing a loading text, image, etc.
If it isn't your first view you can load your data in another window and store it to later usage when the user reaches the View to show the info.
You can load it right in your onCreate, onStart or so, but as you said probably you won't have time to download the info, so again, show a loading page or whatever you want while your data comes.
To avoid initialization errors call your AsyncTask after initializing the elements. And to avoid calling the API multiple times save your data locally while the app is opened, it depends on your app requirements
I am working on a project that lists items that users can click on any of them and see its detail in detailsActivity and if they like it so the can download it! i am using asynctask to list all the items from server in the doBackgournd method and display the result in onPostExecute method. The problem is when users start a download and go back to the list and click on another item the detail of the item is displayed only when the first download finishes!
I want the users be able to choose any item and go the detailsActivity while the download is running for other items they previously started.
please help
You should try and place your download to a Service.
A Service is an application component that can perform long-running operations in the background and does not provide a user interface.
AsyncTask in (earlier versions after android 3.0 I think) android works sequentialy by default
if you want to change this behavior you can use executeOnExcuter instead of execute
for example
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
I have an array adapter which is used in my listview. The adapter is periodically updated by fetching or removing contents from a server. I have used a scheduledthreadpoolexecutor to periodically update the adapter and then use adapter.notifydatasetchange();
The list view gets refreshed and removes any items etc, but for example if two items where removed from the list when I scroll the listview on android and get close to the end of the listview the application crashes. I guess something does not get updated in the listview and it things that the size of the list is the initial size.
Do you have something to recommend?
Regards,
Aris
Hi all,
I actually found a solution to my problem and forgot to check here for any replies.
Thank you all for your suggestions.
Basically scheduledthreadpoolexecutor called a runnable (lets call it updateRunnable) to do the updates.
What I did was the following:
In the updateRunnable, when it gets the new data and stores them in the array adapter, it then calls another runnable (lets call it updateListView) using runOnUiThread and in updateListView I set the adapter of the listview.
This solved my problem
If your data is at all database-like, which I assume, given your use of a ListView, then you'll want to refactor your background service into a model that uses a ContentProvider and SyncAdapter to stay in sync with the server, and then automatically notify the ListView through binding it with a CursorAdapter which uses its implementation of ContentObserver to automatically update the list when the underlying DB changes.
Why does ContentResolver.requestSync not trigger a sync? tells you how to set up the ContentProvider.
How to handle REST calls, data persistence, syncing and observing ContentProvider tells you a little more about how list update notification operates once the ContentProvider is syncing.
It's a lot of infrastructure work to get set up, but once you do, there's so much that's wonderfully automatic about the SyncAdapter model.
I had a similar problem once. Since the ListView keeps updating you can
1) display the Listview just as the activity starts in OnCreate, and
2) call this SAME activity so as to display refreshed data in the listview.
but after calling the same activity again, finish() the current instance first immediately since you can get multiple instances of it one over the other.
I have question regarding my previous ListView activity.
I have my ListView which is continue updating using socket connection, now when I click on any of the list row i can go to my next screen now when i come back to my previous ListView screen my ListView is start updating again but i want to keep updating my ListView in a background when i am on my nextscreen.
Something like i want to keep my previous screen alive when i am on my nextscreen.
Sounds to me like your the code you are using to load the data for your ListView is tied to your Activity.
For instance you have an AsyncTask or Thread in your Activity that cointains your ListView and you use it to download data, or do whatever is needed to get the data to populate the list. I also assume you start it in one of the Activity lifecycle methods e.g. onCreate().
If that is the case then you should consider seperating the code used for getting the data for the list from your activity code.
One way to do this is to use a Service which will be able to run independantly of the rest of your application and do all the heavy lifting involed with fetching the data for your list. You can communicate with the service from anywhere in your application. The Service can save the data to a database. Then all you have to do in your Activity is query the database and populate the adapter to get the latest data without much delay.
You can read more about services here:
http://developer.android.com/reference/android/app/Service.html
You could (and probably should) do what Paul suggested or you could change to way you switch your screens by using Fragments or a ViewFlipper. This way you still run your AsyncTask or Thread while doing something else on a different page.
I will start with what I am trying to accomplish.
I have a ListFragment, with LoaderCallbacks associated to retrieve data from a DB. The data is downloaded using an AsyncTask, and inserted into the DB. When the user gets to the bottom of the list, using the CWAC-Endless widget the AsyncTask is kicked off and downloads more data.
I am facing a couple of issues here, and I have tried to sort this out over many a night, and I have decided to come here to ask for help.
The first issue is configChanges. When the user rotates the device, the Activity is destroyed, and then recreates all of the Fragments. I know I can use setRetainInstance to true, but this does not help as the AsyncTask is still running when the Activity gets torn down!
The second issue is to do with the Loader. If data is downloaded, and the AsyncTask completes fine, then the items appears in the List fine. Lets say there are 20 items in the DB. When the user rotates the device, and the Fragment is recreated, the Loader needs to be associated again. When this happens, the data is not loaded into the list straight away, and instead the AsyncTask for the download is kicked off because the CWAC-Endless adapter thinks its at the last item in the list!
Both of these issues have exhausted me. I need a fresh look on this, as im getting no where.
Any suggestions will do, and I can post up source code if needed.
EDIT
Ok here are a few more details to help with some suggestions.
I am downloading data from the internet, which will only return a set number of items at a time. I then have to request more data when I want it (pagination).
I decided to use a database, as the new Loader functionality makes it so simple to make sure the data is loaded efficiently and consistant, without any threading issues.
If it would make sense to ditch the Loader approach, and use a standard Adapter to render the data, I am more than happy to ditch this approach and use that. I just wanted to see if someone could offer an insight into why this solution is so difficult.
Thanks,
Adam
When the user gets to the bottom of the list, using the CWAC-Endless widget the AsyncTask is kicked off and downloads more data.
FWIW, I have not tried EndlessAdapter with this combination of stuff (cursors, loaders, and AsyncTask). In particular, quoting the docs:
Note that this has been tested with ArrayAdapter extensively but may not work with other adapter types
I am not even quite certain what the use case would be for an EndlessAdapter applied to a local database. If you have a crazy long list (e.g., thousands of rows), the answer isn't "load it progressively" but "provide a different UX to avoid the long list". For shorter lists, just load the whole thing and be done with it. EndlessAdapter is for cases where the loading is expensive (e.g., Internet access).
That being said, I will add "play with EndlessAdapter and Loader" to my to-do list.
I know I can use setRetainInstance to true, but this does not help as the AsyncTask is still running when the Activity gets torn down!
So? onPostExecute() will not be invoked until the new activity has gotten through onCreate(). Moreover, in a fragment-based model, your task should be talking to the fragment, and if that fragment is retained via setRetainInstance(true), it's the same fragment instance in both the old and the new activity.
When this happens, the data is not loaded into the list straight away
It should be loaded in fairly quickly, though asynchronously. Moreover, I don't see why this is any different from when the activity is created in the first place.
and instead the AsyncTask for the download is kicked off because the CWAC-Endless adapter thinks its at the last item in the list
You should not be creating the EndlessAdapter until after you have data.