Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have the following task to do, I need to build a live search from an endpoint.
Now, the thing is I know how to do it but, what I don't know, is how to do it efficient. The small app should do the following:
Live search from a specific endpoint - a list of over 2000 objects in a json request.
While loading, the app should display a spinner.
Refresh the autocomplete list view.
The only solution I know is the following:
I add a menu to the action bar where I add the search view.
Inside the activity I will have a fragment with a list view (better when I want to add some clicking on the items), and when the user searches for something (e.g, "around, "a" first, then "ar", etc) then a new request to the server will be made and all the objects that start with "a" will be loaded to the listview and from then on autocomplete will do its work.
In this way I need to load all the data that contain "a" and filter from there.
Now the problem for me is that I need to parse every time the json file, and it is possible I only need 3 records.
As an improvement, I thought of somehow filtering the json big file and retrieving only the json file that I need, but I am not sure if this is possible and if so at what cost.
Does anyone know a better solution?
Since you can't change the server-side component, you'll have to make your client smarter.
The way to go here is (as #pskink suggested) to store the data locally. If you make a single request for every entered/deleted character in the search-view, you're practically DOSing their server. Also, this will be slow.
The challenge is to cache the data locally but keep it "fresh" enough so that it doesn't divert to much from the data on the server. Implementing this is harder than it sounds.
I would suggest loading the entire JSON from the Backend as soon as the activity opens. Depending on how big each individual entry in this list is, you might get away with keeping them all in-memory and filtering on that (i'm thinking a Tree might be a good starting point).
If you get any performance or memory problems with this solution, I'd suggest moving the data into some kind of database (it doesn't need to be SQLite, Realm might also be interesting). The same challenge applies for keeping that data up-to-date, of course.
Since you said they told you, I guess you're working with the people behind the server-component. In that case, I have found the best approach is to implement a solution that works (any of the ones above) and show it to them. If it's not fast enough for them, make suggestions:
They could give you an API to get only the new/changed entries since a given date (so you can just update the database).
It might also be possible to make a hybrid model: Filter on your offline-data first, but also make a request to the server (with a filter-parameter or something) and mix the resulting data. Indicate to the user that you're in the process of fetching more "up-to-date" data, but show them the results you already know. This might not work well if entries are removed frequently.
Related
I am currently learning android programming and creating an app that will store some integers representing user choices (values inserted several times a day, must be displayed in the results activity) and steps data collected Google Fit HISTORY Android APIs, also displayed in the results activity. I am looking for the most efficient way to store this data. I know that it might be possible to insert the custom data types in the GOOGLE fit database. However, I am not sure if it is a good idea if the app mostly works offline, and it needs to immediately represent only a small set of results, for example, the values inserted in the last 2 weeks, with step counts. On the other hand, I am not sure if it is ok to have two databases storing the data.
My apologies if the question sounds a bit too amateur, I am doing my best to find an optimal solution in terms of performance.
Thank you for your answers.
So, to give you my opinion and answer (mainly opinion)
Android has 3 ways (mainly) for storing data:
Files
Online database/API
Local database
for this specific scenario you have listed, wanting the data to be available offline, you should probably be looking at using Room: https://developer.android.com/training/data-storage/room, as it supports storing primitive types without having to write any type converters, you can store models and custom data as well, it uses very basic SQL (because it's a wrapper for the older Sqlite database methods) and is part of android (not an external 3rd party library). Room also requires most operations to be done off of threads, instead of main threads and this will improve your performance as well (also has support for livedata/rxjava to observe straight onto any changes as they happen)
However, as I told this user here:
Should i store one arrayList per file or should i store all my arrayList in the same file?
When starting out, don't worry about the best way for doing something, instead, try something out and learn from it, worrying about the best solution now is rather pointless, either way, happy learning and coding :P
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm seeking assistance on a APP I need to create. I don't have no experience with android app development but, I'm studying and practicing.
I'm trying to build an app to record payments from a list of customers and print a receipt when paid. I download a list of customers with pending balance, using json array into android. Now, I'm confused, don't know if I should use arrays or a database to store the list, since I need to update (upload) later to the server. SQLite seems like an option but, I have to download the list every time user is connected to WiFi.
I guess I have to store the payments on an array and flush it once uploaded.
Can you please tell me what would be the best option for the tasks I'm trying to accomplish.
It depends on your use case. Arrays and sqlite can work independently or together.
If you are going to upload the data instantly after downloading within the same session, then you can keep it in the Array and upload it after what ever you need to do with it. Keep in mind that Arrays will be kept in memory and depending on where you are keeping the array object, they might not persist through the life cycle of an activity or the life cycle of your application.
SQLite on the hand writes data to disk, so you will be able to persist it even after user has backed out of your application.
...since I need to update (upload) later to the server
Based on the above, it seems like you should persist your data on disk. SQLite is one of the options for persisting data. Have a look here to see what else is available for persisting data.
You can load up any persisted data into your array and upload it after you have processed it.
Hope this helps.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I am currently creating an app that is a guide for a game which involves the user navigating through categories and a large amount of information being displayed. For instance, if I wanted to review information regarding a specific weapon, I may navigate through Items > Weapons > Ranged > Bow. What would be the best to to set this up so the app would run smoothly? I may have up to 100 of these different items the user can view.
The two current approaches I am considering is either making a local SQL database of all of these items, and then having one activity that pulls from the database based on what the user selects. The other being to just make string resources and then load those resources depending on what item the user selects. Any opinions or insight would be much appreciated.
I am not sure about string resources but if you are doing "read only" operations on the data and not saving any user input I would suggest NOT using SQLite. The problem with SQLite for this use is that you will have to create the tables and populate the database programmatically the first time that the app is run. (someone correct me if there is another way to do this) Basically you will end up writing all of your information as strings or reading it from a file on the device anyway, it will just get inserted into the database and be accessed from there every time after. Another drawback is that every time you want to update the information in the app you will have to add rules in the "onUpgrade" method of the database handler. Accessing the data from SQLite will be faster than reading files but IMHO it is a way bigger pain than it is worth for just read operations (unless you have massive amounts of data.. "massive" in the computer world happens to be pretty darn big).
I would probably store the data in your own files (XML, JSON, or just plain text) and put it in the assets folder. Using a nice folder structure and good file naming in there would allow you to add new information without having to change your program.
Another option is to build a web database, pull the information from there, and save it to the local SQLite database when there is an update to the information that you saved online. This makes it easy for you to make revisions to the content without having to send out an app update but takes quite a bit more work
The Content Provider is the prefered way to store big data on the android platform and fortunately many tools are available to do the hard work for you. With that said I would hardly consider 100 a large amount of data even on a mobile device. Will the data change? In other words is it static or dynamic? I recommend the Content provider but you could use shared preferences, a resource file or even hard code your values.
I'm making an adapter that it underline data loads from a web service and each time the user scrolls down it loads more data and adds it to the ArrayList behind that adapter. The data contains image URLs which I then lazy load in my getView method.
Is there a better solution for that?
And how do I properly cache those images?
And can I retain the data of the adapter when the user rotates the device? So no need to load them again from the beginning?
I use fragment to display that list?
I'll try to answer all three questions one by one.
is there a beter solution for that? (other then lazy-loading)
That depends. The nice part about lazy-loading is, that you don't need to have all data right at the start when you display the component. The problem often is, how to get new data, as it is needed.
So, when loading the new data from the network, it is really a question of how big the chunks of loaded data are. I would not load one new entry after the next one, but load e.g. 20 new ones, when the end of the list has been reached.
Of course this is just a random idea for a number, you'll need to find the perfect point between speed and usability for your case.
So when you are loading chunks of data from your web-service, which are delivered fast enough, it really is a cool concept. But if you're just reading one entry after another (and therefore, the user almost always waits for new data), this is really just annoying.
And how to proper cache the images?
There are multiple possible solutions available, some of those are:
Using the system-cache, like the browser (seems to be the
finest).
Implementing your own system which uses device-storage (e.g. the
SD-Card or the internal application storage (the first one is
preferred)).
You might also like the contents of this question (and it's accepted answer), giving you some general advises on memory-management.
can i retain the data of the adapter when the user rotates the device?
Old, deprecated anser:
Yes, you can use the "instance state" of the Activity to do this.
Basically, the onSaveInstanceState()-method from the Activity
allows you to populate a given Bundle with state-information, which
is then passed to the onCreate()-method.
The data you would save in the Bundle would be (for example) the
current position of the list or maybe even the list itself (depending
on the size).
Yes, use the Loaders API. It is also available in the compatibility library.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 months ago.
Improve this question
I'm making an ecommerce application on Android and, as it is my first serious project, I'm trying to figure out beforehand the best approach to do this.
The application talks to a web service (magento api, meaning soap or xml rpc unfortunately) and gets all the content on the phone (product categories, product details, user credentials etc.). I think it should do lazy loading or something like that.
So, I was thinking to keep the user credentials in a custom Object which will be kept in a SharedPreferences so that every Activity can easily access it. I'll use a couple of ListViews to show the content and AsyncTask to fetch the data needed. Should I keep all the data in memory in objects or should I use some sort of cache or a local database? Also, I'm planning to use a HashMap with SoftReferences to hold the bitmaps I am downloading. But wouldn't this eat a lot of memory?
How can all the activities have access to all these objects (ecommerce basket etc.)? I'm thinking of passing them using Intents but this doesn't seem right to me. Can SharedPreferences be used for a lot of objects and are there any concurrency issues?
Any pointers would be really appreciated. What are some good guidelines? What classes should I look into? Do you know of any resources on the Internet for me to check out?
A very detailed question I will do my best to answer it.
I used the following approach in my application:
I save the user credentials in the shared preferences. The preferences can only hold custom objects if they are serializable and writing and reading from flash memory takes a lot of time. Therefore I load the preferences on startup and store them in memory.
I try to keep all the data in memory that is needed in many places and in a consistent state, all the other memory is passed via serializing to json and passing through an intent or i pass only ids and I re fetch it from the net. (There is definitively a possibility for cashing in a local database but the effort to keep it up to date is to much work at the moment.) To store objects that take to long to reload from internal memory or network and re parse it I use a custom application that holds the reference to some controller objects which manage the caching. The application will stay in memory until your app is closed. This is convenient but can result in needing way to much memory if you are not careful.
The bitmaps that are downloaded by my program are cached on two layers. At the first time I want to access an image I create a image manager object inside my activity scope. That object will try to find the bitmap in an internal map. If it is not there it will try to load it from phone memory if it is not in the phone memory it will download it from the net, store it in the cache folder of my app and put it in the map. In this way the bitmap is accessible as long as the activity runs and is cleaned up at the moment the user changes to another screen. Until now this is sufficient for me.
At the end just begin programming and come back if you encounter other questions or errors and post some more specific questions.
Many useful techniques that you will need to use: ContentProviders, AsyncTasks, Bitmap Caching, ... are used in Romain Guys 'Shelvs' (http://www.curious-creature.org/2009/01/19/shelves-an-open-source-android-application/) app. It's a great start point to get the into a recommend Android flow.