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
|
Mark M. |
how can I help you today?
|
Jul 23 | 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
|
Mark M. |
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.
|
EGHDK |
Okay, so what is this guy talking about when he says "grab the pixel data"?
|
Mark M. |
I'm sorry, but you lost me
|
Mark M. |
who is "this guy"?
|
EGHDK |
Forgot to post the link. Sorry. http://stackoverflow.com/questions/17768145/wha...
|
Jul 23 | 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:
|
Mark M. |
but that code is awful
|
Mark M. |
it assumes that the image you want is the one with the highest ID value, and that's ridiculous
|
Mark M. |
for starters, the image might not even be indexed by the MediaStore yet
|
Mark M. |
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
|
Mark M. |
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
|
Mark M. |
let me take a question from Yurii, and I'll be back with you in a bit
|
Mark M. |
Yurii: do you have a question?
|
Yurii L. |
sure a sec
|
Yurii L. |
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
|
Yurii L. |
?
|
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?
|
Jul 23 | 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
|
Mark M. |
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?
|
Jul 23 | 7:40 PM |
Mark M. |
I have not tried that scenario
|
Mark M. |
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
|
Mark M. |
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?
|
Jul 23 | 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
|
Mark M. |
that way, the background updating will be done before it processes the delete command
|
Mark M. |
since an IntentService itself is single-threaded
|
Yurii L. |
but in can have a queue of 100 files
|
Yurii L. |
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
|
Mark M. |
the delete-the-database command would be high priority, to jump the queue
|
Mark M. |
and it would then flush the rest of the commands that deal with that database
|
Mark M. |
in terms of the 10MB file, personally I'd just let that run to completion
|
Mark M. |
otherwise, you're welcome to use some static AtomicBoolean as a "stop! stop!" flag
|
Mark M. |
EGHDK: do you have another question?
|
EGHDK |
I've got 3 more questions loaded up, so just ask me when, and I'll shoot.
|
Jul 23 | 7:50 PM |
Mark M. |
fire the first one
|
EGHDK |
Here's my first.
|
EGHDK |
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
|
EGHDK |
Hahaha. Misunderstood
|
EGHDK |
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()
|
Mark M. |
and that just has a Uri in it
|
Mark M. |
which is pretty small
|
EGHDK |
As seen here: http://stackoverflow.com/questions/17765265/dif...
|
EGHDK |
View paste
|
EGHDK |
Gives me a URI? I thought it actually gave me the data (image)
|
Mark M. |
hang on
|
Mark M. | |
Mark M. |
"Output: The URI of the item that was picked. This must be a content: URI so that any receiver can access it."
|
Mark M. |
you are getting a Uri to the image, not the image
|
Jul 23 | 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
|
Mark M. |
other than bugs in the app or device
|
Mark M. |
(app here meaning the gallery)
|
EGHDK |
Exactly, but the gallery app works fine with every other app I've tried.
|
EGHDK |
Facebook, instagram, wallpaper app
|
Mark M. |
comment out onActivityResult() and see what happens
|
Mark M. |
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.
|
EGHDK |
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.
|
Mark M. |
Yurii: do you have another question?
|
Jul 23 | 8:00 PM |
EGHDK |
Yep... it works fine. =/
|
Mark M. |
meaning you commented out onActivityResult(), and things behave normally now?
|
EGHDK |
Yes.
|
EGHDK |
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.
|
EGHDK |
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
|
Mark M. |
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.
|
EGHDK |
And it still hangs on that part.
|
EGHDK |
Which was my overly complex of basically doing what you recomendded. (Commenting out the onACtivityResult code)
|
EGHDK |
I just thought an AsyncTask would have solved that.
|
Mark M. |
done properly, it can help
|
Mark M. |
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
|
Mark M. |
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
|
Mark M. |
my point was that on a single-core device, there is only one core
|
EGHDK |
Got it.
|
EGHDK |
True.
|
Mark M. |
and so CPU cycles you steal for "background" work aren't exactly free
|
Jul 23 | 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.
|
EGHDK |
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
|
Mark M. |
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
|
Mark M. |
:-)
|
EGHDK |
Hahah
|
EGHDK |
Okay, next question, if I'm using the navigation Drawer, it uses fragments.
|
Mark M. |
not necessarily
|
Mark M. |
DrawerLayout does not imply fragments
|
Mark M. |
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)
|
EGHDK |
I thought I have to use fragments with the drawerNavigation?
|
Mark M. |
nope
|
Jul 23 | 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.
|
EGHDK |
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?
|
EGHDK |
dialogFragment?
|
Mark M. |
um
|
Mark M. |
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.
|
EGHDK |
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?
|
Mark M. |
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
|
Mark M. |
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.
|
EGHDK |
Yes
|
Mark M. |
then IMHO you have serious flow problems
|
Jul 23 | 8:15 PM |
Mark M. |
but, be that as it may
|
Mark M. |
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"
|
Mark M. |
then a DialogFragment is a reasonably slick solution
|
Mark M. |
C and C' would be the same thing
|
Mark M. |
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
|
Mark M. |
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
|
Mark M. |
then C' is a separate instance of the common fragment class, one you use with show() instead of a regular FragmentTransaction
|
EGHDK |
View paste
|
EGHDK |
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?
|
Jul 23 | 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)
|
Mark M. |
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.
|
EGHDK |
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.
|
EGHDK |
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:
|
EGHDK |
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
|
Mark M. |
Android Studio is late this year on my timetable
|
Mark M. |
EGHDK: no clue, sorry
|
Jul 23 | 8:25 PM |
EGHDK |
Hrm... yeah I need to figure out how the other apps do it.
|
EGHDK |
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.
|
EGHDK |
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?
|
EGHDK |
This is the video I was referiing to.
|
EGHDK | |
Mark M. |
um, your question is a bit too abstract
|
Mark M. |
bitmaps are images
|
Mark M. |
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.
|
Jul 23 | 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
|
Mark M. |
as graphics hardware has no ability to work with JPEG, PNG, etc. dirctly
|
EGHDK |
So a bitmap is uncompressed?
|
Mark M. |
er, directly
|
Mark M. |
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
|
EGHDK |
Okay, so that really helps.
|
Mark M. |
and, that's a wrap for today's chat
|
Mark M. |
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?
|
EGHDK |
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
|
EGHDK |
Okay, thanks for the reminder.
|
EGHDK |
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
|
Mark M. |
have a pleasant day!
|
EGHDK | has left the room |
Yurii L. | has left the room |
Mark M. | turned off guest access |