Office Hours — Today, June 13

Thursday, June 8

Jun 13
8:55 AM
Mark M.
has entered the room
Mark M.
turned on guest access
Dimitris K.
has entered the room
Dimitris K.
Hello Mark, good morning !
Mark M.
hello, Dimitris!
how can I help you today?
Dimitris K.
Today I'm kinda interested in well structured code
so basically I am reading some configuration files and in that files there are some set of rules
the rules define when updates should happen (intervals), what time should updates occur, what the minimum inactivity time is and so on
9:00 AM
Dimitris K.
what would be a proper structure to save the parsed data
and share it inside my apps components
Mark M.
presumably, some set of POJOs that mirrors your configuration file structure
with a singleton cache for those, based on how many possible configuration files your app needs to deal with at a time
Dimitris K.
should I use shared prefs to save them read data to the device ?
Mark M.
you already have a file; why create another?
Dimitris K.
good point though that file will be updated and in case it somehow gets corrupted I would like to have a backup plan
Mark M.
I'd back up the configuration file, rather than having two sets of disparate code for loading configurations
in terms of the POJO structures themselves, for typical configuration files (XML, JSON, properties, etc.), usually there is a fairly canonical mapping from the file format to Java objects
though that may be slightly different depending upon the parser that you choose to use
9:05 AM
Mark M.
(e.g., Jackson might want to populate POJOs slightly differently than does Gson)
Dimitris K.
regarding the parsing of the config file would you use some kind of library to create java objects from the xml data?
Mark M.
my default position is "yes"
if you are at risk of going over the 64K DEX method reference limit (and therefore need multidex), then I might hand-roll something
Dimitris K.
I wont get over the limit for sure
Mark M.
or, if the XML is just plain weird (e.g., everything is in CDATA stanzas), I might hand-roll something, if SimpleXML or similar libraries won't handle it well
or, if I am creating a library for somebody else to consume, I would hand-roll something (e.g., my work for the F-Droid "update channels" library)
and personally, those scenarios cover most of my own circumstances, so I haven't actually used SimpleXML or anything similar
Dimitris K.
should I show you a sample of what I have now ?
Mark M.
well, these chats get archived, so only post stuff in here that you do not mind showing up on the Interwebs
Dimitris K.
thats fine
9:10 AM
Dimitris K.
View paste (48 more lines)
public class XMLParser {

    private static final String TAG = "XMLParser";

    public static LanguageConfigXML parseLanguageConfigXML(String filePath) {
        String styleId = null, suiteId = null, defaultLanguage = null;
        boolean showCursor = false, touchMode = false, showMemory = false;
        Language language = null;
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(new File(filePath));
            NodeList nList = doc.getElementsByTagName("v");
            for (int i = 0; i < nList.getLength(); i++) {
                Node node = nList.item(i);
...
something like that
Mark M.
you are using the DOM; I would use an event-driven parser if the XML might be large
Dimitris K.
what is considered large ?
Mark M.
that depends a bit on your deployment environment
1MB would certainly be large
10KB would be not large
rather than iterating over nodes, I'd retrieve them by name, for the names that you know about, but that's just a coding style issue
and in your situation, I'm not sure that you just want to crash out on a parsing error (e.g., if Boolean.parseBoolean() does not like a value of "you betcha!")
Dimitris K.
A friend suggested that it should also be somehow convenient to use annotations since the structure that I expect is known
Mark M.
otherwise, what you have there seems reasonable
only if you are using some XML parser that uses annotations
otherwise, those would be akin to code comments, at best
9:15 AM
Dimitris K.
I guess this can be always changed later and as long as it works fine now maybe I should stick with it
Mark M.
if there might be 10K lines of this code, you might worry about it more in the short term
if it's only going to be a few short methods of the variety that you have here, "if it ain't broke, don't fix it"
Dimitris K.
its going to be that short just different classes for different files
and the files are probably always shorter than 1k lines
Mark M.
you might consider a base parser class, to hold common utility code
Dimitris K.
plus I am only parsing them once per session so performance doesnt really matter
9:20 AM
Mark M.
if there are dozens of different files, you might try to more aggressively implement some common rules-based engine, just to limit the amount of code that you need to maintain
but otherwise, I wouldn't worry about it too much
Dimitris K.
its something like 8 files
not much
Mark M.
in that case, just a base class to give you a spot to hang common code should suffice
Dimitris K.
by the way I feel like we all have to really thank you for the wakelock, alarm manager and jobscheduler chapters of the book :D
Mark M.
yeah, that stuff started confusing and has just gotten worse over the past couple of years
Dimitris K.
that concentrated knowledge makes it so easy to work
Mark M.
in your case, you have it somewhat easier, in that you always have power on a digital sign (right?)
Dimitris K.
yes
I will just use the wake lock and only reboot the device when I want to
Mark M.
if and when you start supporting Android 6.0+, Doze mode and app standby should not be issues
(as opposed to us poor schlubs having to write for phones and tablets, which have only intermittent power)
Dimitris K.
the only mysterious parts left (and they really are mysterious) are regarding app monitoring and silent background installations
9:25 AM
Mark M.
silent background installations either requires root or a custom ROM
and I'm not certain what "app monitoring" means in this context
Dimitris K.
and ofc implementing my own nice kiosk mode
All the devices I will work with have root access
Mark M.
(silent installs might also be possible via device owner APIs -- I haven't checked there recently)
Dimitris K.
I will have 2-3 apps installed
Mark M.
I do not know the mechanics of doing silent installs on rooted devices; I'm just fairly certain that it is possible
Dimitris K.
and the "controller" app should take care of the others
I also need to gather some usage statistics
sadly that will add some more logic to the presenter app since I dont think I can get much from a background app easily
so probably my presenter app will have to send the data to the app that controls it and actually is connected to the server
Mark M.
can you be more specific about what "usage statistics" means? also, what version of Android are the signs running?
Dimitris K.
5.1
and I will need to know when the device was used, for how long, what was clicked more often and general things like that
9:30 AM
Mark M.
well, you can use UsageStatsManager to get some of this
Dimitris K.
I also followed your advice on the downloader and I am now using a class extending runnable in a thread from my service
Mark M.
I have not covered UsageStatsManager in the book; I need to do that one of these days...
Dimitris K.
nice ! I had no idea this existed
im lucky my devices are running 5.1
Mark M.
having a reasonably modern Android version is a double-edged sword
on the one hand, you get APIs like this one
on the other hand, older hacks for getting this stuff are partially gone, for privacy and security reasons
while those concerns are less important in your deployment scenario, Android is Android, and so you are stuck with limits imposed for phones and tablets, to a large extent
Dimitris K.
indeed !
9:35 AM
Mark M.
but I'd start with UsageStatsManager, then identify what you still need that is not covered by it, to see what else you might need to employ
Dimitris K.
This is actually my first project that wont run on regular phones
the most magical part in the digital signage part is that you know exactly the screen size and resolution you need to support so you can just use pixels
and hardcode everything to perfection
Mark M.
until the firm decides to switch to a different screen
Dimitris K.
hehehe exactly
but you only need to support a batch of devices each time
so its fine for maybe even 2 years
later the OS version for the devices will also change
have you tried to use certificate pinning with okhttp ?
Mark M.
only by way of my backport of network security configuration: https://github.com/commonsguy/cwac-netsecurity
with that, it works fine back to Android 4.2
9:40 AM
Dimitris K.
awesome I guess I can use that
Mark M.
your pin information goes into XML resources (e.g., res/xml/network_security.xml)
and you tell the library to apply that configuration to your OkHttpClient via your Builder
Google's and my code take care of the rest
in the case of standard pinning, it's Google's code
for soft pins/trust-on-first-use scenarios, it's my code
Dimitris K.
sounds like that project is exactly what I need
so it seems that the last complications I will have with the project is creating my own custom layout inflater
and thats just cause I dont have enough experience on the matter
plus there are is not much data online
Mark M.
well, the basics are not that different than what you showed above for populating POJOs
instead of creating instances of a Language, you are creating instances of a LinearLayout
if you are trying to handle "real" layout XML syntax, with all the android: and app: attributes, *that's* going to be a pain
9:45 AM
Dimitris K.
will I be able to avoid that ?
Mark M.
well, do you control the XML?
if you want simpler XML, and you control the XML, create simpler XML
Dimitris K.
thats already defined
Mark M.
is it the same as Android's layout XML resources?
Dimitris K.
its supported in another platform so as a new platform I should keep compatibility
no the configuration files are custom structured
they basically work like this
main page has 3 things inside
then explains what the 3 things are
but each thing has a defined size
Mark M.
OK, so, we're back to it being akin to your existing configuration XML parsing
Dimitris K.
yep
Mark M.
you have two ways of going about it:
1. the XML parser is directly creating your view hierarchy
2. the XML parser is building up a set of POJOs, akin to your configuration objects, and they create the view hierarchy
personally, I'd lean towards the latter approach
Dimitris K.
it will allow from some code to be reused so 2) makes more sense to me too
Mark M.
to create the view hierarchy, you either are creating the views/viewgroups purely in Java, or you are inflating small focused layout resources for each and tailoring them in Java
9:50 AM
Dimitris K.
can I give you a small example
Mark M.
go right ahead
...bearing in mind that we only have a few minutes left in the chat...
Dimitris K.
so I read from the config file that there is a main screen separated into 3 parts (half of the screen vertically separated and one part of it separated horizontally)
sure no problem
and it says that there is an image gallery on the top corner
and a list next to it
(ignore the 3rd window)
how do you approach it
Mark M.
have POJOs that mirror the XML
have them implement some common interface with some common method for building the view hierarchy (e.g., assemble())
tell the root POJO to build the view hierarchy
whatever is in the XML for the rules (e.g., "there is an image gallery") maps to layout resources
and, where needed, also applies some Java code to tailor non-static bits of those layout resources
Dimitris K.
I see !
Mark M.
the root POJO also tells its children to assemble(), passing along the partially-assembled view hierarchy, for them to chain on their own views/viewgroups
Dimitris K.
this way I can add functionality slowly and step by step
Mark M.
right
9:55 AM
Mark M.
testing the XML->POJO logic is very straightforward
testing the POJO->view hierarchy is a bit more complicated but shouldn't be all that bad
Dimitris K.
yep this sounds very realistic :D
thank you once again for being the team member I need :D
Mark M.
happy to be useful
Dimitris K.
useful is an understatement !
Mark M.
BTW, back on the certificate pinning... OkHttp 3 has its own certificate pinning code
so, if all you need is certificate pinning, you could just use that
use CWAC-NetSecurity if you need more of the power of the network security configuration stuff
otherwise, it may be overkill
Dimitris K.
I will check it out today !!
So enjoy the rest of the day and thanks again !! :D
Mark M.
you are very welcome
10:00 AM
Mark M.
the transcript will be posted to https://commonsware.com/office-hours/ shortly
the next chat is tomorrow at 7:30pm US Eastern
the next chat in this time slot is 24 June
have a pleasant day!
Dimitris K.
:D
Dimitris K.
has left the room
Mark M.
turned off guest access

Thursday, June 8

 

Office Hours

People in this transcript

  • Dimitris Kirakosian
  • Mark Murphy