I have built a simple system that allows the user to update views throughout the application whenever a linked image file on disk has changed (the App has a bunch of drawing operations that let you change the images).
It works by maintaining a list of FileUpdateListeners which contain a File and a View. Whenever a SaveTask is created for a File, it will run through all the listeners and call any listeners hooked to that File.
Now it appears the Views are constantly dropped and remade as you move forward and backward through Activities. However, the listeners all stick around. I´m guessing because their reference to the View prevents it from being garbage collected. I´m pretty sure this is going to wreck the performance and eventually cause the app to run out of memory.
So my question: Is it possible to detect when a View is unhooked from the Activity, so that I can remove the Listener that it belongs to? Or is there another way to make sure the Listeners are removed when the Views are removed?
Ideally, the Listener should not be inside the View. I'd want the system to work with any kind of View.
Related
List data is to be displayed in a RecyclerView, and a graphical view at the same time. It is my understanding that separate adapters would be required for each.
My issue is
I've been struggling with where to load persistent data and hold it at runtime.
Loading and holding the data in separate adapters means loading the same data twice from persistent storage. Although some might be cached, it is still effectively loaded twice.
How to trigger update of both views when the data is changed, say from an activity launched from click on the list view?
The views should not need to know about the existence of each other.
Maybe the simple(?) solution is to wrap the list in a class, which handles the data loading, giving it an interface for listeners (the adapters) to subscribe to, and add the necessary listener interface, implementation, etc.
I don't mean this to be an opinion oriented question. There should be a common or best practice method. I'm new to android development.
I'm building my first app based on material from http://javatechig.com/video/json-feed-reader-in-android.
Everything goes quite ok so far, but there is a bug in thumbnails. When I scroll list, random thumb images quick "refresh" with random different thumb and back to original one. Any suggestion why it behaves like that?
You should take a look at the following page:
http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
The part Handle Concurrency explains everything:
Common view components such as ListView and GridView introduce another
issue when used in conjunction with the AsyncTask as demonstrated in
the previous section. In order to be efficient with memory, these
components recycle child views as the user scrolls. If each child view
triggers an AsyncTask, there is no guarantee that when it completes,
the associated view has not already been recycled for use in another
child view. Furthermore, there is no guarantee that the order in which
asynchronous tasks are started is the order that they complete.
So you are right. This is actually a bug of this sample which hasn't got a proper load/display logic.
For the development of my app, I realized I needed a complicated view (let's call it foo), it contains three ImageButtons, a progress bar, and three TextViews, all of which are dynamically changed by interacting with the same view's elements. To make this work, I extended foo from RelativeLayout, dynamically created the sub-views then added them to foo (this.addView(...)).
What I planned to do next was add them dynamically to a ScrollView. I did this and put three foos for testing. The result was extreme lag. I'd press an ImageView (which should change its image on press), and it would take 2 seconds to do so.
My final aim would be to support 50 of these foos at a time and have them work smoothly, with the user having the option of loading more (without overwriting the previous ones) if he/she so chooses. All interactions will use the internet (I dunno if that's relevant), but the testing was done with all the network tasks commented out.
My questions are thus:
Is the strategy I was using (ScrollView & add foos to them) viable, and the lag is from some other issue (the specific code in question, in which case I'll provide some code)? Or is it really a bad idea to do that?
What would be the best way to reach my goal here (assuming 1 is bad)?
What I already know:
I've researched my problem a bit, and most online sources recommend using a ListView. I didn't read much into it but from what I got:
I'd have to redo the design using xml rather than dynamically
The different components and their values will be stored each on it's own array which is extremely unacceptable in my situation (changing the sub-view's values should be done very simply and should not appear in the main activity)
I can't (or it's difficult to) set OnClickListener's for the different sub-views (as only the main foo view will get one)
I also tried this method (ScrollView and add to Views) with another View and had 20 of them run at the same time seamlessly, but that one had been extended from View and only used canvas to draw text with no sub-views.
Thanks in advance.
I am trying to implement my own Android view recycling. My question is, is there a simple way to "reset" an Android View object (more specifically, a FrameLayout) to the state in which it would come out of a constructor. In other words, it knows about its context, but it's forgotten about things like calls to SetWillNotDraw, touch handlers, visibility, or anything else I may have set on it.
The alternative would be to write my own "reset" method. I'm concerned that if I go that route, I will end up with bugs relating to failing to reset some portion of the state.
No, there isn't. If you weren't trying to do recycling I'd suggest just creating a new one is the easiest way to ensure it. Its also not a very efficient thing to do in general- there's a lot of pieces of state that can be changed, if you try to set all of them you'll end up wasting a lot of cycles. Generally you have the code that sets these things have a reset method of some sort called when you unbind a view from its model, and it will clear the subset of things it changed.
So I have an activity that will display a list of options and when you click an option it should move to a list that displays the choices for that option, but I'd like both lists to be in the same activity.
I'm debating between the two options of using a single listview and changing the contents (maybe by swapping the adapter if that works, not sure) whenever a user navigates between the two lists, or using something like a viewswitcher where both lists exist independently, but only one is visible at a time.
I would definitely think the viewswitcher option would be the cleaner option, but how will it perform especially if I need to scale it to more than two lists? Is there much overhead to creating a listview that's not rendered?
Keeping one listview and switching out its backend would be a pain, especially considering all the re-initialization every single time you click an option.
-Use two ListFragments, have one control the other. Using Fragments instead of two separate ListActivities would mean that when you build a tablet interface, it would be minimal work to have one Activity with both on the same screen.
-Use an ExpandableListView
I did have a choice like that. I was using a list view to navigate to a remote webdav server.
At the beginning I was using one view for each folder. It was cool: using back was allowing me not to worry about navigation history.
But after a while, there was some cases where I needed to manage all the views at once, or kill them all or implement a communication between views (for parameters). And it was a nightmare to achieve. Also my list were beginning to be heavy and a lot of list in memory is never a good thing. I finally gave up and managed all the navigation in a unique list view. I should have do it at first.