Office Hours — Today, September 11

Sunday, September 9

Mark M.
has entered the room
Mark M.
turned on guest access
Sep 11
8:55 AM
RepslyDevs
has entered the room
Mark M.
hello, RepslyDevs!
how can I help you today?
RepslyDevs
Hi Mark :)
9:00 AM
RepslyDevs
I must say that the book is fantastic and you're doing a really great job :)
Mark M.
thanks for the kind words!
Mathias
has entered the room
Mark M.
unfortunately, lots of it needs to be rewritten: Kotlin, Jetpack, AndroidX, etc.
RepslyDevs
Before I start with really question, I'm curious. Do you have a team of people or you're doing it all by yourself? :Ož
Mark M.
(BTW, hello, Mathias!)
RepslyDevs
real questions* :)
Mathias
:)
Mark M.
it's just little old me
RepslyDevs
Wau. Nice :)
So, just a little introduction to what we do (already written the introduction before the "office hours"):
View paste
In our company, we have an Android application that is 8+ years old. Lots of legacy code.
We have taken an initiative to refactore/rewrite the code as much as possible and whenever we have the time.

We've taken the MVP (Model-View-Presenter) approach. Writing the tests for Presenters only.

Can you please let me know is that the right way to do it?
Mark M.
when it comes to GUI architecture, there is no single "right way to do it"
choosing an architecture is as much art as it is science
Ed T.
has entered the room
Mark M.
MVP is reasonably popular... though people may disagree on the definition of "MVP"
Ed T.
Happy Tuesday!
Mark M.
that's one of the reasons why I try to stay out of architecture discussions -- the definitions are a bit fluid
(hello, Ed! I'll be with you after RepslyDevs and Mathias!)
RepslyDevs
Yea, I bet. Tons of courses and literature on the subject and can't make sure, what's good or wrong.
9:05 AM
RepslyDevs
Android navigation from the Google seems like a good way, but with so much legacy, it's impossible to do it.
Mark M.
legacy code can be a pain to work with... even if the legacy is only six months old :-)
"what's good or wrong" varies annually
sometimes, there are good reasons for the changes in opinion; sometimes, it is merely changes in fashions
which is another reason why I try to stay out of architecture discussions
RepslyDevs
Yea, true. Ok, cool, thanks. Have 3 more questions if you don't mind :)
Mark M.
let me take questions from the others, and I'll return to you in a bit
Mathias: your turn! do you have a question?
RepslyDevs
Ok, sure :)
Mathias
great
I'm still doing geofences...
We've tried various approaches but none are 100% as of yet. Summary:
View paste
1. if we let the receiver schedule a jobintentservice with enqueueWork, it can sometimes take 5, 10, even 30 mins until the actual job being executed. Too long.

2. We therefor have everything in broadcastreceiver, but goasync for the network call.

However, the network stuff only works intermittently. Sometimes the connection does not work. No error just "socket was closed". which apparently means someone closed it explicitly. Makes me think doze mode or something like that. Never happens anywhere else.
But how can phone be in doze mode when geofence is triggered??
(the actual geofence is triggered with an explicit broadcastreceiver, as per google I/o talk and their example on GitHub)
Mark M.
with regards to #1, on Android 8.0+, JobIntentService uses JobScheduler, and jobs can be deferred, though I am surprised that you are seeing that long of a delay
9:10 AM
Mathias
Exactly! It's on a google pixel
Mark M.
with regards to your second problem, while the device may not have been in Doze mode when the geofence was triggered, it might have fallen back into Doze mode before your network I/O completes
I forget our previous discussion -- is a foreground service not an option for you?
Mathias
I guess, but wouldn't it be weird with notifications just popping up all of a sudden? can I just start a foreground service from my broadcast?
Mark M.
you can start a foreground service using startForegroundService() on ContextCompat
that will use the real startForegroundService() on Android 8.0+ and startService() on older devices
Mathias
And that will make a notification pop up right?
Mark M.
in terms of the notification displaying, it is unlikely that the user will be looking at the screen at the time of crossing the geofence border
startForegroundService() will not, but you are obligated to call startForeground() from the Service, otherwise you will crash
Mathias
right. I guess I could try it.
so, I call startservice from broadcastreceiver, then startforegrouund directly in the service itself??
Mark M.
call startForegroundService() from the receiver, then in the service call startForeground()
Mathias
ok. I will try
Mark M.
it's a confusing set of methods they have now
Mathias
its unbelievable!!! android is driving me crazy mate
Mark M.
welcome to my world
let me take questions from the others, and I'll return to you in a little while
9:15 AM
Mark M.
Ed: your turn! do you have a question?
9:15 AM
Mathias
sure
Ed T.
Yes sir.
I need to write a doc viewer app that sits on the mime type PDF
they get an e-mail and my app is registered as a viewer for that app
if I registered my app as a viewer it will work with all e-mail apps regardless right?
it is system level
Mark M.
that depends entirely on what is in your <intent-filter> and what the various email apps use for Intent structures
there are no guarantees
but, if you support file: and content: schemes, you should be OK
Ed T.
sounds like life... lol
thanks!
Mark M.
thank me after you get content: support working, as that can be a pain :-)
9:20 AM
Mark M.
but, that's definitely required, as at least Gmail uses it, and probably many others
let me take questions from the others, and I will be back with you soonish
RepslyDevs: your turn! do you have another question?
RepslyDevs
Hi, sry. This chat keeps logging me out for some unknown reason :/
I have another one. Pasting it in a second.
Mark M.
sorry about that -- it's a hosted service, so I do not have much control
RepslyDevs
View paste
We're really struggling to show the code coverage numbers to the management department? How to present those?
Currently, we're running unit tests with Coverage in Android studio and it's reporting really small number of coverage:
	-Line percentage 3% (2093/53815) 
	-Method 5% 410/6965
	-Class 9% 103/1097

We've written for some Presenters even to 100% coverage, but what bothers us it the fact that the Model and View parts aren't in the statistics! The line coverage of them are 0%, even though they are called from the Presenter. Do you know where is the issue?
Mark M.
instrumented tests and unit tests each have separate coverage logs
RepslyDevs
No problem, will manage. Sorry for popping in and out of the chat.
Mark M.
so, if you have both types of tests, if you want a comprehensive look at coverage, you need to merge those logs
I recently used the techniques outlined in https://proandroiddev.com/unified-code-coverage... on a project
and, after some tweaking, it worked
9:25 AM
Mark M.
(though we ran into a Kotlin + coverage + Android Studio problem that wasn't fixed until AS 3.2)
RepslyDevs
Yea, we're using jacoco test report for that. It works fine, for most of the times.
Now the issue is with Unit test reporting and only Unit tests.
Mark M.
there's not much I can tell you in the abstract
it would be nice if Android Studio or the Android Gradle Plugin offered a more cohesive look at the combined test results
similarly, it would be nice if I had hair
:-)
RepslyDevs
Haha, that would be cool yes.
Do you know any literature about the unit testing on Android and how to report the numbers?
By literature, I mean links on the web, books or anything.
Mark M.
there is the blog post that I linked to above
which covers both instrumented and unit tests
Ed T.
has left the room
Mark M.
I'm sure that there are other materials out there, but I do not have links handy
RepslyDevs
Because it's really hard to write test, making sure that presenter is covered with 100% tests, but the models and views aren't covered at all :/
9:30 AM
Mark M.
I have a chapter in "The Busy Coder's Guide" on coverage, though it needs to be updated sometime
without knowing your code base and your tests, I cannot really comment on why you are getting the coverage results that you are, sorry
RepslyDevs
Ok, I see. When you write tests, do you get the full code coverage for models and views?
Mark M.
well, that depends a lot on the tests and on your definition of "models" and "views" :-)
but yes, I can often achieve fairly good coverage, bearing in mind that some code is outside the scope of coverage (e.g., data binding expressions)
similarly, I don't worry about coverage of code that is code-generated (e.g., Room)
RepslyDevs
From the view, some screen is starting and needs some data loaded. With Presenter, we're calling the model, which fetches the data and returning that data to the view, via Presenter.
Tests are written for the Presenter. Coverage of that code is 100%. But the model method we directly call from Presenter has 0% coverage.
Model method is standard call to the Sqlite database and returning one field back.
Mark M.
that sounds like there is some issue in either the coverage data collection or the coverage report generation
9:35 AM
Mark M.
I have not seen that behavior personally
RepslyDevs
Using the Android Studio 3.1.3
Mark M.
I tend to run my coverage reports from the command line
RepslyDevs
Ok, I guess I ask too much :D
Mark M.
let me take another question from Mathias, and I'll return to you in a bit
Mathias: back to you! do you have another question?
RepslyDevs
Ok, thanks.
Mathias
hey
well just some follow-up on the discussion
Regarding the unreliability of broadcast network operations. How can i figure out what makes the sockets being closed sometimes? Can i "check" if i am in doze mode? It feels super strange to me that i could be in doze mode when i am the one being called from the system.
Mark M.
you could try methods on PowerManager like isPowerSaveMode(), though I have not tried them
Mathias
I mean, if I try to do the network synchronously in onRecieve() I get "network stuff not allowed on main thread", but if I do it in a thread after goasync, I'm suddenly in doze mode??
Mark M.
it might not be "suddenly", depending on the duration of the I/O
Mathias
io *never* takes more than 1-2 secs
Mark M.
Doze mode has "maintenance windows" in which you can do work
AFAIK, those should be more than 1-2 seconds
Mathias
I have debug notifications I sprout out all the time, I measure start-end of the whole operation
9:40 AM
Mathias
well, ok. seems like my best bet right now is to try foreground.
mind-boggling to me how this is so complex to realize
Mark M.
as I think I noted in our previous discussions, I have never used goAsync() for much, as the rules around it are ill-defined
Mathias
Ah, ok.
Final thing - I have a thread on SO I wrote yesterday. Perhaps you could just take a peek and see if you have any additional ideas?
Mark M.
background work has gotten increasingly painful for developers, though admittedly it has greatly helped Android's battery life
Mathias
sure, but doing a network operation in a timely manner when a geofence Is triggered should not be this hard... :)
Mark M.
I have not worked with geofences much either
ideally what you want would be easy
it is not an ideal world
Mathias
absolutely
well, I'll get cracking on the foreground stuff. Do you have any example code about kicking off a foreground service from a receiver like I'm to do?
Mark M.
probably -- hold on
hmmm... I guess not
that's disappointing
Mathias
ok, was just trying to save some time... :)
Mark M.
sorry!
let me take a question from ResplyDevs, and I'll be back with you shortly
ResplyDevs: back to you! do you have another question?
Mathias
I think we're all set! so have a good one everyone
RepslyDevs
Yep. So, do you have any public project where that code coverage is done the right way?
9:45 AM
Mark M.
probably not
Mathias
has left the room
Mark M.
I have coverage in a book example or two, but they are small samples
most of my bigger projects are for consulting clients, and they are not open source
RepslyDevs
In those bigger projects, you had to have 100% unit test coverage?
Mark M.
no
for starters, lots of things cannot be tested using unit tests, only via instrumented tests
RepslyDevs
Yea, that's clear to me. I'm curious about how to track the numbers?
Mark M.
however, there is a significant difference between "100% unit test coverage" and "code that I see my tests calling is not getting reported by the coverage tools"
you seem to be experiencing the latter
I have not seen that
the code coverage gaps that I have seen are due to lack of tests
is there anything unusual about your project structure, such as having the presenters and the models in separate Android Studio modules?
RepslyDevs
Yea, can see the difference in those two. The first one is being from the management side of my work, which has to report the numbers and it already made clear that 100% code coverage is not the goal and it can't be achieved.
9:50 AM
RepslyDevs
For the second problem can't seem to see a clear solution right now. Run the unit test for thousand times now, and can't seem to get them right to include models and views.
No, the presenters, views and models are in the same package of the main project.
Mark M.
then I really can't explain those coverage results
RepslyDevs
Ok, that's ok. Will investigate further and write to you on some other meeting.
Have one more question. In all of the Android projects you had done for the clients, have you had to implement 100% unit test coverage?
Mark M.
no
usually, the projects were in "hurry hurry hurry!" mode at the outset
RepslyDevs
How do you approach when writing "tests" for a project, go fully on unit tests or combine unit with instrumentation?
Mark M.
oh, it is always a combined thing
9:55 AM
Mark M.
personally, I tend more towards instrumented tests, as our users are not running our code on a JVM, but on Android
so, for example, I avoid Robolectric, and prefer to write those tests as instrumented tests
RepslyDevs
Did you ever had to present the code coverage numbers to some clients or to you Project manager?
Mark M.
I'm not sure how formal you mean by "present", but management knew the figures
RepslyDevs
Sry, for just pumping questions, have lots of them and we have little time :)
Yea, for instrumentation, I must agree. But those tests are slow.
By present, I mean presenting the numbers in a way where they are the measure of how successful we are in our refactoring/re-writings.
Mark M.
I have never presented them in that fashion
it's more been a manager asking "hey, what are the current coverage numbers?" on occasion
RepslyDevs
We would love to have statistics behind our infrastructure work we do in the code by increasing the unit tests.
Oh, I see.
One last question. Any infrastructure work you had to do on the project?
Mark M.
I am not certain what you mean
10:00 AM
RepslyDevs
In a way, you would love to try new technology but you're stuck with some old framework, in an Android project.
Mark M.
oh, that is common enough
RepslyDevs
You would love to rewrite it or refactor it. How to go to management with it?
Mark M.
I can't really answer that without getting into specifics that I cannot disclose (NDAs)
plus, it's time to wrap up the chat for today
the transcript will be posted on https://commonsware.com/office-hours/ shortly
the next chat is Thursday at 7:30pm US Eastern
have a pleasant day!
RepslyDevs
Ok, thanks.
RepslyDevs
has left the room
Mark M.
turned off guest access

Sunday, September 9

 

Office Hours

People in this transcript

  • Ed Tidwell
  • Mark Murphy
  • Mathias
  • RepslyDevs