I'm having a hell of time grasping the best way to "package" my Android app into logical components, my objective is to make an app that is easy to update and add new features to.
I believe a "modular" approach would work best, one where my data is represented as Data Classes, my DB has it's own DB Helper Class which handles all DB interaction and finally View "Controller" Activity Classes which interface the DB Helper, Data Classes and Views all together.
This being said, I need some high-level rules in order to structure my programming, I find if I don't have rules, I end up with sloppy code and massive rewrites as the code gets too complex.
All things considered, are these rules a good foundation for a SQL backed App?
My theoretical Android rules:
The DB Helper Class should contain all DB logic. This means, the DB Helper will contain the code to open and close the DB, as well as the code for inserting, updating and deleting all records. The DB Helper will return data not as cursors, but as Data Class objects that I create, each Data Class will have a constructor which takes the cursor and uses it to populate the values of the Class.
Data Classes will allow DB records to be represented as objects and not just cursors. As the DB Helper will only be returning objects I will have to create adapters for items such as ListView's to render my object's data as opposed to the cursor (I'm a bit fishy on this point, not sure if this is a good idea or not). All business logic, so all calculations to be done on the data contained in the Data Class, will be done in the Data Class itself. I envision my Data Classes having typical getters and setters as well as "calculate" methods, these calculate methods will take vars from the Data Class and do some meaningful business logic on them, returning the result (is this a good idea?).
View Controller Activity Classes will literally tie the DB Helper's methods to the Data Classes and update the Views with the resulting information. This Activity Class will be quite normal, it will initialize the layout and widgets, it will use the life-cycle methods to perform various queries on the DB through the DB Helper at the appropriate times, and it will have simple update methods which update widgets using the Data Class object they're fed.
I am finding I have no troubles with Android except for struggling with issues of design such as these. I am tired of my applications becoming too complex, and I need a simple system to ensure things stay manageable and extensible.
If you struggled like me, please, please, please, push me in the right direction for structuring an App. It's all that's holding me back from making what I hope are amazing apps for everyone's enjoyment.
The biggest thing you need to consider when designing your app is: who is going to maintain it? If you are going to be the only one who is doing maintanence on your app, then do whatever works best for you. However, if others are going to be maintaining this app, then yes, you will want to keep similar things together. It sounds like you have a pretty good plan. Make sure you use comments and if you like, you can include a "readme.txt" that will allow others to see what is going on and for you to explain your design logic. To keep things from becoming too complex, you can use packages to store similar classes.
Ultimately there is no single right answer to your question.
Related
I am reading up on Room and the way it handles relationships between entities is both understandable, but confusing. I cannot wrap my head around what a "proper" data model should be to make Room happy. The problem is that all the examples I have found show how to handle a simple relationship, but don't address nesting, or entities that contain references to multiple other entities.
Going back to the beginning, my question is how should I model my data to make using Room as easy as possible?
Is it possible to have the data model framework-agnostic? That's something that feels correct to me. A framework should not dictate the way entities are modeled. I want to be able to traverse the data model as I would if there was no database at all.
Assuming I have a deep-ish hierarchy, for example: a Game has multiple Players and multiple Rounds. A Round has multiple Turns. A Turn can have multiple Steps. How do I model this according to Room? Reading about #Relation, it would suggest there should be "wrapper" POJOs. But would that mean that here I would have to create classes TurnWithSteps, RoundWithTurnWithSteps, and GameWithRoundWithTurnWithSteps?
This also seems to imply that whenever working with the entities in code, I have to decide which "view" of that entity to use. So I cannot simply work with Game and use it as if it was a true, nicely modeled class?
I have a SQLite database which has a table (of course) named Object. In my application, I need to access that table and all of its fields. I am able to query the database and get all of the information I want from a cursor with no issues. The problem comes with deciding what to do with the cursor next. Right now I am thinking of creating a class called Object and it will have fields for every column in the table which will be set by the query. This just seems so... inefficient. I'm not sure how to do this without needing to write out every column that is in the table for the object to use, which seems to violate DRY. Are there any better ways to do this?
My end goal is to be able to access every row in the table and get whatever information I want for that row. For example I will be using this to populate a ListView. If this is too ambiguous let me know and I'll try to clarify.
Thanks!
Edit: I've found the library db40 and it seems to do what I want. The library seems to be kind of big though (40 mb) for a mobile application. Does anybody have experience with this? Everything I've read seems to indicate it is good. I'll post more if I find information.
Are there any better ways to do this?
This is very "wide" question and depends on personal requirements and what is for developer more comfortable. I'm using your idea that is for me the best one you can use.
Generally we can say you want to create ORM (object-relation mapping). It's very clean and efficient approach (my opinion). Of course sometimes is not the best solution to use ORM ( i never met with this case but heard about it). I almost always use my own defined ORM for sure it takes some time but results are significant against done frameworks.
Both have advantages and disadvantages. Own ORM has much more higher performance because it's designated and optimized for concrete solution (mainly queries etc.).
I suggest you to do what you mentioned -> create object that will represent table in database with properties equal to columns. I'm using this in work and we never had problems with performance or too much battery consumption with our applications.
It's also much more safe if you'll show user some data not directly from database but "copies" in objects. Users can do whatever want with dislayed results (they can add some dangerous symbols and hacks) but now you can easily check this before you'll want to update database(s) with changes.
Your source-code looks good, another developer won't be lost in your code, everything will be clear and easy to do updates for future.
I provided you "my opinion" on this thing so hope it'll help you with make a decision.
I want to share data across multiple applications, instead of having a ContentResolver->ContentProvider mechanism, I can just define a client library which talks to the process which does the SQLite DB operations right?
What does the ContentProvider brings in here which we cannot achieve by having a Process expose the data?
You can find answer Exact Difference between “Content-Provider” and “SQLite Database”.
But I like to explain this..
What does the ContentProvider brings in here which we cannot achieve by have a Process expose the data?
There is one particular SQLite limitation you should be aware of and that is that SQLite is single-user only. What this really means is that you will need to guard your database from being accessed from multiple threads at the same time. This is generally not a problem in a content provider, since they almost always have a single-threaded implementation.
Also It's good practice to provide the extra level of abstraction over your data to make it easier to change internally. What if you decide to change the underlying database structure at a later time? If you use a ContentProvider you can contain all the structural changes within it, where as if you don't use one, you are forced to change all areas of the code that are affected by the structural changes. Besides, it's nice to be able to re-use the same standard API for accessing data rather than littering your code with low-level access to the database.
You can check the thread below:
Exact Difference between "Content-Provider" and "SQLite Database"
I was doing my 1st steps with android writing a money manager. It stores data in SQLite database and my approach was mostly procedural, while I was creating it.
It means: when I'm creating a chart or a summary it's look like this:
I create a database cursor
I iterate over that cursor to collect neccessary data
I pass the data directly to the element I need (a chart or listview for example)
Well, that works, but I'm learning more oop now and I'd like to rebuild my app.
I'm not fully aware of memory restrictions on mobile devices, that's why I'm creating this thread.
I came up with two ideas. Please tell me, which one you think is better (or correct my approach somehow if it's completly wrong).
Lets use an example of creating a chart or a listview like before. Now I'd do this that way:
I create database cursor.
I create number of objects equal to number of records I need to present data.
I use created objects to pass the data to chart or a listview.
This will require more code than my procedural approach but use of it should be much simplier then, and the code would has more 'proffessional' look (correct me if I'm wrong).
However, I got this dilema. Let's say I'm creating a set of objects based on data from table 'expenses'. I use them to present a chart or a listview on one of my activity. After I close the activity I don't need them anymore. What should I do to let garbage collector toss them away. Anything particullar? (yes, I'm new to the garbage collector stuff).
There is also second oop approach but I'm aware it will require a lot of memory and I'm not sure if it's a good idea at all. So, back to the example again:
I create cursors for each table I got
I create a set of objects matching the tables - basically I pass all the tables into set of objects for further use (I do it in a thread with some progress bar if necessary)
I use the created objects anytime I need to present my data.
Sounds silly, huh? I'm not sure when the garbage collector would dispose all those objects, and if it's a good idea to spam memory with that amount of data in once.
Thanks for any comments on this.
Both solutions work, but the first one is better because the objects are marked for GC as soon as they go out of scope, which happens much earlier than if they are kept for later use. Once the objects are GCed, the memory they occupied becomes available.
I want to save my Android game state so the user can pick up and play from where he/she left off.
I have been reading about the serializable interface, but have some questions.
Aside from background rendering and a few other things my game is performed from one class.
Let me explain what that means. I have a class A, and all the different elements of the game are stored in various arraylists and such, in A. SO I have dozens of instances of classes B,C,D,E... all being called and updated (when the screen updates) from class A.
My problem is I am unsure what needs to be serializable. Every class B,C,D.. (i.e. every class? or just A? I don't see why serializing A and then saving the output in SQLite DB wouldnt store all the data.
Just as a suggestion, you may also want to look at Berkeley DB Java Edition, specifically at the DPL (Data Persistence Layer) API. Like SQLite, it's a transactionally protected, recoverable, fast, small footprint database library. However, the DPL allows you to directly persist your classes, making it a much easier choice for Java application developers.
Here's a technical white paper describing the API and how to use it.
if you want to serialize some object. then look at this link use other object in place of hashmmap object that has been specified in this link.