Office Hours — Today, July 23

Thursday, July 18

Jul 23
7:20 PM
Mark M.
has entered the room
Mark M.
turned on guest access
EGHDK
has entered the room
Mark M.
hello, EGHDK
how can I help you today?
7:25 PM
EGHDK
Okay, first question. I really do not understand images in Android. I don’t understand bitmaps, and I don’t understand why my bitmaps are crashing on older devices. It just doesn’t make any sense to me. Anyway, now that I have vented. All I need to do is send an intent to open up the camera application and bring that image back into my application. I would rather it not be saved on the device if possible. So I don’t want to set a location for it. But I get really bad quality image. Any ideas?
Mark M.
if you want a full-resolution image, you have no choice but to have it saved to external storage
bear in mind that there's a 1MB limitation on most forms of IPC in Android
EGHDK
IPC?
Mark M.
inter-process communication
EGHDK
Activity to Activity?
Mark M.
that too
EGHDK
Okay, so any interprocess. Makes sense.
Okay, so what is this guy talking about when he says "grab the pixel data"?
Mark M.
I'm sorry, but you lost me
who is "this guy"?
EGHDK
7:30 PM
Mark M.
well, here, "grab the pixel data" means "attempt to read the photo as an InputStream out of the MediaStore provider:
but that code is awful
it assumes that the image you want is the one with the highest ID value, and that's ridiculous
for starters, the image might not even be indexed by the MediaStore yet
moreover, the image is still on external storage somewhere
EGHDK
Hmm... so I shouldn't do that?
Mark M.
absolutely not
EGHDK
Okay, IT IS on external storage somewhere.
Mark M.
sure
just about every ContentProvider is backed by storage somewhere
EGHDK
Awesome. This is a breath of fresh air.
Yurii L.
has entered the room
Mark M.
MediaStore, in particular, is mostly for indexed content on external storage
let me take a question from Yurii, and I'll be back with you in a bit
Yurii: do you have a question?
Yurii L.
sure a sec
Is it ok in your opinion to do db calls from UI thread such as update one field of get one entry or delete smth
?
Mark M.
I would avoid disk I/O on the main application thread
EGHDK
Erm. Lost me though. When I'm doing my regular camera intent and not specifying a storage location, does that use a ContentProvider?
7:35 PM
Mark M.
Yurii: it's less of an issue on Android 3.0+, but it can still cause you to drop frames
Yurii L.
I'm working on 14+
Mark M.
I still wouldn't do it
Yurii L.
thanks, I think it is EGHDK turn.
Mark M.
but you are welcome to do the performance testing and determine how much of an issue it will be for your users
EGHDK: if you are getting the image back in an extra, that is just a low-res "thumbnail" image, and the camera probably did not capture a full-res one
EGHDK
Gotcha. So that's just an extra being passed back to me, and not doing some secret kind of ContentProvider stuff I've read about.
Mark M.
correct
EGHDK
Cool.
Mark M.
Yurii: do you have another question?
Yurii L.
In your, ThreePaneLayout if I press back during animation all layout moved to the right on about 1/4 of width of the screen?
7:40 PM
Mark M.
I have not tried that scenario
I will make a point to do some testing on that for the next book update
Yurii L.
thanks. Another one is what is the best way to delete DB if other threads still write to it? Global state boolean and check in those threads?
Mark M.
um, IMHO, you should not be deleting the database if there is a chance of anything else going on in parallel
Yurii L.
should I just delete everything from all tables?
Mark M.
it's more that if you have background threads that are working with the database, you should avoid doing major destructive acts until those threads are done
while the thread safety is handled for you if you are using the same SQLiteDatabase, the business logic could get seriously messed up
Yurii L.
I have next scenario, IntentService loading files in background updating states of files in DB, user decide to logout so I need to delete all data
EGHDK
Isn't the point of a database to keep the data so it's there when the user logs back in?
7:45 PM
EGHDK
But I guess every scenario is possible.
Mark M.
I would send a command to the IntentService to delete the database
that way, the background updating will be done before it processes the delete command
since an IntentService itself is single-threaded
Yurii L.
but in can have a queue of 100 files
or it can be in process of loading 10MB file
Mark M.
for the 100 files part, roll your own IntentService replacement that uses a PriorityQueue and a ThreadPoolExecutor
the delete-the-database command would be high priority, to jump the queue
and it would then flush the rest of the commands that deal with that database
in terms of the 10MB file, personally I'd just let that run to completion
otherwise, you're welcome to use some static AtomicBoolean as a "stop! stop!" flag
EGHDK: do you have another question?
EGHDK
I've got 3 more questions loaded up, so just ask me when, and I'll shoot.
7:50 PM
Mark M.
fire the first one
EGHDK
Here's my first.
I had a problem last week with my gallery. It’s the stock gallery application, but when I am trying to select a picture from my “Camera” folder, it seemingly freezes/doesn’t work. I did some debugging, and it seems that the slow down is from my app, but I still can’t obtain the photo. I believe it is because it is too high res. Does this count as an IPC and I simply cant pass in a large image? I don’t believe this is the case because I have a wallpaper application, that allows you to choose from the gallery app, and it retrieves the photo without a problem.
Mark M.
"Does this count as an IPC" -- this is ACTION_GET_CONTENT?
EGHDK
Nope! Inter process communication
Hahaha. Misunderstood
Sorry
Mark M.
how are you integrating with the gallery from your app? ACTION_GET_CONTENT? something else?
EGHDK
It's an ACTION_GET_CONTENT
Mark M.
then the only immediate IPC is to deliver the return Intent to onActivityResult()
and that just has a Uri in it
which is pretty small
EGHDK
View paste
So you're saying: Intent myIntent = new Intent(Intent.ACTION_GET_CONTENT, null);
myIntent.setType("image/*");
startActivityForResult(i, 100);
Gives me a URI? I thought it actually gave me the data (image)
Mark M.
hang on
"Output: The URI of the item that was picked. This must be a content: URI so that any receiver can access it."
you are getting a Uri to the image, not the image
7:55 PM
EGHDK
Hrm... could that be a reason why certain folders with images load fine (Google Plus Folder), vs something like the Camera Folder?
Mark M.
I have no explanation for the behavior you were describing last time
other than bugs in the app or device
(app here meaning the gallery)
EGHDK
Exactly, but the gallery app works fine with every other app I've tried.
Facebook, instagram, wallpaper app
Mark M.
comment out onActivityResult() and see what happens
if it now works properly, your issue is in onActivityResult()
EGHDK
I guess I'm doing something wrong. Though I thought I was on the right track.
Good point. I'll do that now.
Mark M.
basically, if the problem is in your code, you should be able to prove that via breakpoints, Log statements, Traceview, etc.
Yurii: do you have another question?
8:00 PM
EGHDK
Yep... it works fine. =/
Mark M.
meaning you commented out onActivityResult(), and things behave normally now?
EGHDK
Yes.
Well that's way more of a lead than last week. I thought I was getting the data, I'm actually getting the URI, so I have to do something different.
It might just be that the image is too big when I'm loading it from the URI
Mark M.
yes, there's something in how you are processing that response that is an issue, perhaps for high-resolution images
usually that'll get you an OutOfMemoryError than bogging down the device
EGHDK
Yeah, it's just weird because I shoved all of the activity result code into an asyncTask.
And it still hangs on that part.
Which was my overly complex of basically doing what you recomendded. (Commenting out the onACtivityResult code)
I just thought an AsyncTask would have solved that.
Mark M.
done properly, it can help
but there are buggy ways to use an AsyncTask
EGHDK
Gotcha.
Mark M.
and, particularly on single-core devices, it's not a magic bullet
Yurii: if you have another question, please chime in
EGHDK
AsyncTask would've tried to run in another core if it was dual core?
Mark M.
possibly -- that's out of our hands
my point was that on a single-core device, there is only one core
EGHDK
Got it.
True.
Mark M.
and so CPU cycles you steal for "background" work aren't exactly free
8:05 PM
EGHDK
Okay, so on to my next questions. Yurri chime in at any time!
Yurii L.
ok
EGHDK
So I had a layout, and I added a split action bar, but it seemed to cut off my last button in that layout. My layout should have adapted itself to fit.
Does that mean that the aplitActionBar sits on top of your content?
Mark M.
not normally
EGHDK
I thought it just made the layout "window" smaller.
Mark M.
there are ways that you can have it float over top of content
if your layout is fluid (e.g., overall height is match_parent), it should just shrink that
EGHDK
Okay, that's what I was looking for.
Mark M.
if your layout is rigid (e.g., overall height is some number of dip), then you should be slapped with a trout
:-)
EGHDK
Hahah
Okay, next question, if I'm using the navigation Drawer, it uses fragments.
Mark M.
not necessarily
DrawerLayout does not imply fragments
you *can* use fragments with DrawerLayout, but it is not required
EGHDK
Also I mean navigationDrawer as in the way of navigation (As added in the new guidelines)
I thought I have to use fragments with the drawerNavigation?
Mark M.
nope
8:10 PM
EGHDK
Hrm... okay... Well, I followed the guide on d.android.com, so I'm using fragments.
Mark M.
no problem
EGHDK
One of those fragments is a opens up to a list of items.
Now, picture I'm in a totally different part of my application, and I want a button to send off an intent to open up that fragment, so I can "select" an item, and it'll return to my current activity. If you stayed with me with that description. How do you suggest I implement that?
dialogFragment?
Mark M.
um
let's back up a couple of steps
EGHDK
I'm not sure if I can use a dialogFragment to display a fragment that I normally use as an "activity" basically.
Okay.
Mark M.
when you say, "I'm using fragments", do you mean that your entire application is one activity, with fragments coming and going?
or do you mean that you have several activities, that happen to use fragments?
EGHDK
The most upper level of the heirachical navigation... yes.
Mark M.
OK
is the fragment showing the "list of items" one that is part of your hierarchical navigation?
EGHDK
So I'm using a navigation drawer, with fragments. I have three main fragments. A, B, and C. I have now travlled deep into navigation of fragment A, and I would like to display C and retireve something from it.
Yes
Mark M.
then IMHO you have serious flow problems
8:15 PM
Mark M.
but, be that as it may
if you want to say that there is C and C'
EGHDK
It seems like it. But I promise you I don't. It's just that I rather re-use that code/layout already since I have it.
Mark M.
where C' looks a lot like C, but is popped up on demand to "retrieve something from it"
then a DialogFragment is a reasonably slick solution
C and C' would be the same thing
just shown inline (C) or as a dialog (C')
EGHDK
Yeah, but would i have to make another fragment? Or can I just say. Hey fragment C! Show up in this dialog.
Mark M.
at the class level, it would be a single class
I think you may need separate instances
EGHDK
Yeah, definitely seperate instances.
Mark M.
I know you need separate instances for a Presentation used in a DialogFragment
then C' is a separate instance of the common fragment class, one you use with show() instead of a regular FragmentTransaction
EGHDK
View paste
Okay, I see that we are coming down to a close soon. Two quickish question.

I was working on a class today thats extended from another one of my classes. I needed it to do something in particular on that current class when a button was clicked. That button click is set up in the parent class. What would be the best way to add in a method in my case?
the button onClickListener was set up*
Yurii L.
Mark what is your vision on MVC in Android, are Activity and Fragments Controller or mix-of-View-Controller?
8:20 PM
Mark M.
have the base class implement View.OnClickListener, tie the object in as the OnClickListener, and have the subclass override onClick(), chaining to the superclass if approrpiate
EGHDK
I just put in an extra method that was empty in the parent class, specifically so I can override it in the child class. Was that the "wrong" thing to do?
Mark M.
Yurii: if I had to shove Android in an MVC pattern, widgets are views, fragments are controller, activity is an orchestration layer (or second-level controller)
but Android is not designed with MVC/MVP/MVVM/etc. in mind
EGHDK
Because the parent class onCLick does like 10 things. And I need my child to do 10 things + 1.
Mark M.
EGHDK: no particular problem there, if it works for you, just not how I'd do it based on the limited description
EGHDK
So again, I just created an empty method, and I overrode it. I just feel like that breaks some rule.
Okay, I'll take your word for it.
Mark M.
it's not awesome OO, but to some extent, if it works, it's at least a starting point
EGHDK
I'm not sure what "implement" does. So I'll have to read up on that.
I've never done Myclass implements *whatever
Yurii L.
Mark do you use Android Studio?
Mark M.
Yurii: no, I won't be touching that for some time
EGHDK
One of my last-ish questions:
If I want to go into the “People” app on my phone, there seems to be a possibility of adding a entry for my application in there. So my twitter app, can have an entry so I can lookup my boyfriend, click his name and it’ll show me an icon that I can click that will open up my app. Is this possible?
Mark M.
I started spinning back up again on IDEA this past weekend and was ready to take a crowbar to my notebook
Android Studio is late this year on my timetable
EGHDK: no clue, sorry
8:25 PM
EGHDK
Hrm... yeah I need to figure out how the other apps do it.
Like voxer and such.
Yurii L.
Thank you for session Mark, have a good night.
Mark M.
you too!
EGHDK
Okay, last question of the session. Kind of going back to the first question.
I've been having a tough time with bitmaps, and this dev byte video that came out yesterday is a big help, but it's not the MOST helpful. Any quick resources on learning what bitmaps are, and hwo to handle them in android?
This is the video I was referiing to.
0
Mark M.
um, your question is a bit too abstract
bitmaps are images
Bitmaps are Java objects representing those decoded images
EGHDK
Okay that now makes sense. I thought they were some magical object that somehow "weren't" images.
8:30 PM
EGHDK
"decoded" images?
Mark M.
images are usually stored in a compressed format: JPEG, PNG, etc.
EGHDK
Gotcha
Mark M.
to display them, you need to read those in and decompress them
as graphics hardware has no ability to work with JPEG, PNG, etc. dirctly
EGHDK
So a bitmap is uncompressed?
Mark M.
er, directly
yes, a Bitmap represents an uncompressed image
EGHDK
Oh!
Mark M.
each pixel takes up 4 bytes
EGHDK
So that's why they take up so much space.
Mark M.
(red, green, blue, and alpha channel)
EGHDK
Why is there no blog post enlightening me about this. Hahaha
Okay, so that really helps.
Mark M.
and, that's a wrap for today's chat
transcript will appear on http://commonsware.com/office-hours/ shortly
EGHDK
If I'm working with bitmaps, there's a lot to be done to not kill my app because of memory.
Mark M.
next chat is tomorrow at 4pm
EGHDK
Tomorrow?
I thought thursday?
Mark M.
yes, I don't have any chats next week, so I added a third one this week
EGHDK
Thursday 10am?
Mark M.
there is one Thursday at 10am as well
EGHDK
Hmm... my google calendar hasn't update.d
Okay, thanks for the reminder.
See you tomorrow at 4. I will be up studying bitmaps!
Mark M.
I updated the calendar earlier today to add it, and I have no idea how quickly that filters through the Googleverse
have a pleasant day!
EGHDK
has left the room
Yurii L.
has left the room
Mark M.
turned off guest access

Thursday, July 18

 

Office Hours

People in this transcript

  • EGHDK
  • Mark Murphy
  • Yurii Laguta