Office Hours — Today, March 18

Tuesday, March 11

Mar 18
9:50 AM
Mark M.
has entered the room
Mark M.
turned on guest access
9:55 AM
Andrey
has entered the room
Mark M.
hello, Andrey!
Andrey
Hello Mark
Mark M.
how can I help you today?
Andrey
I'm back with the same question as a week ago. Now I know a little but more
First activity of my app hosts a ListFragment that contains an EditText. When its text is changed, I load suggestions the Listview using AsyncTask. When a ListView item is tapped, I open another activity.
When I go back, I need to restore the EditText contents
You told me it should be saved and restored automatically.
Turns out it does
but only if I "commit" the text by tapping inside the textbox or tapping "Done"
I need to
oh , hut the entersorry
I can save the EditText contents in onSaveInstanceState
10:00 AM
Andrey
when I go to the second activity
but when fragment's onCreate is called upon returning
there is no bundle
Mark M.
how are you "returning"?
Andrey
BACK button
Mark M.
are you just letting the user press BACK and go through normal activity flows?
Andrey
yes
if I "commit" the text I can see it restored
Mark M.
are you doing anything in onBackPressed() of the second activity, or otherwise trying to control what happens on a BACK press?
Andrey
no
Mark M.
well, then, onCreate() of the fragment should not be happening
because the fragment should not be recreated
because the first activity should not be recreated
because the first activity didn't go anywhere, except on the task stack
are you changing orientations or something while in the 2nd activity?
Andrey
oh yes, I have heard something about it
No, I have the orientation fixed
on both activities
Mark M.
that does not matter, from the standpoint of configuration changes
android:orientation only controls visual output
if the user rotates the screen, the configuration still changes
even if visually there is no difference in the result
Andrey
are android:orientation and android:screenOrientation the same?
Mark M.
oh, yes, sorry, I meant android:screenOrientation
10:05 AM
Mark M.
I rarely use that attribute and forgot its name
so, I would focus on *why* the fragment is being called with onCreate()
there should be no need to restore the EditText, because the EditText did not go anywhere
it feels like something is forcing your activity to be recreated
which should not be needed
and depending upon how that happens, it could wipe out your saved instance state
I cannot explain the difference between tapping "Done" or not, though
Andrey
Here's now I associate the fragment with its activity
View paste
if (savedInstanceState == null) {
		getSupportFragmentManager().beginTransaction()
				.add(R.id.container, new DictionaryFragment()).commit();
	}
Is it correct?
Mark M.
there is nothing obviously wrong with that
assuming that you are calling it in onCreate() of the activity
however, onCreate() of the first activity should not be called when returning to it from the second activity
Andrey
yes
10:10 AM
Andrey
and all I do in the fragment is add TextChangedListener in OnCreateView
no other lifecycle methods
other that onCreateView and onActivityCreated
Actually
I don't know about the first activity's onCreate
it's fragment's onCreate where I expect to find a state bundle
that's the one I log
Mark M.
then you need to determine what is triggering onCreate() of your fragment
I would expect that to be called due to the FragmentTransaction
Andrey
The one I posted before?
Mark M.
yes
10:15 AM
Andrey
Assuming I can get "uncommitted" text in onSaveInstanceState()
can I save it somewhere
even in SharesPreferences
Mark M.
sure, but all you are doing is avoiding debugging the real problem
the real problem appears to be that your fragment is being re-created, when it should not be
that, in turn, may cause you difficulty employing workarounds like the ones you describe
10:20 AM
Andrey
but when my first activity is getting on top again, isn't its onCreate() called?
Mark M.
no
onStart() and onResume() will
but the activity should already exist
Andrey
according to the scheme in developer's guide
Mark M.
and hence is already created
Andrey
sorry
I see it now
10:25 AM
Andrey
Stripped my app to the bare minimum and still can't see what's wrong
But I have noticed something
So I start the first activity. There is a focus in an edittext
Drasko
has entered the room
Andrey
And there's a hint
Drasko
Hi, guys!
Mark M.
(hello, Drasko: I will be with you shortly!)
Andrey
I start typing and the text I entered is still styled as a hint
this text is not getting saved for some reason
When I tap inside, it turns black as it should be
Mark M.
Andrey: what are you testing this on? emulator? device?
Andrey
and it is persisted afterwards
device
Mark M.
try with an x86 emulator, or another device if you have a second one
to rule out any manufacturer-created EditText bugs
as manufacturers have this annoying tendency to mess with EditText behavior
and that could be part of your problem
Andrey
I'll try with the emulator
Drasko
genymotion is perfect solution. :)
10:30 AM
Mark M.
Andrey: I will swing back to you in a bit
Drasko: do you have a question?
Drasko
yes, but it's conceptual one.
I just wanted to ask, what are your thoughts on using ContentProvider for database access in scenario where you want to use data from it just for your app?
Mark M.
personally, I'
personally, I'm not a big fan
I'd rather hit the database directly
Drasko
why?
Mark M.
as you cannot do JOINs, use aggregate functions, etc. very conveniently via a ContentProvider
ContentProvider works a lot like a REST interface
the consumer can only consume readily what the publisher publishes
so, if you want to do a JOIN, you have to implement that in the ContentProvider, using some distinct Uri structure
that's certainly doable
but the only particular advantage I see for using a ContentProvider internally is to be able to use ContentObserver
and I'd rather use my own event bus
Drasko
so, actually, you are using loaders in your own AsyncTasks, right?
Mark M.
no
I use AsyncTasks (or something else asynchronous)
but not loaders
as CursorLoader only works with ContentProviders
and the Loader abstraction sucks for anything else
I even tried making my own loaders for SQLite (see CWAC-LoaderEx), and while it works, it's clunky
10:35 AM
Drasko
Yes, I saw it.
So you just basically just do direct queries in your AsyncTasks?
Mark M.
more or less
Drasko
That means that you have another piece of code to maintain, right?
Mark M.
the entire program is "another piece of code to maintain"
Drasko
:)
Mark M.
a ContentProvider does not spring forth from the brow of Zeus
somebody writes it
if that somebody is me, then I have to maintain it
if I choose to organize my code differently, to avoid the ContentProvider, then I have to maintain that code
Drasko
yes, of course, I was just bringing pros for using CPs...
Mark M.
a CP is not going to reduce code
10:40 AM
Mark M.
or, to the extent it does, you could accomplish the same reduction in other ways
(e.g., consolidate query implementation in a data access layer)
where it *does* reduce code is in cross-process communication
Drasko
I understand.
Mark M.
for communication within a process, you're welcome to use a CP if you want
but, you asked me what *I* do, and I wouldn't use a CP in that case
there are Android experts who love CP for internal use
so my opinion is just that: my opinion
Drasko
Of course, that's why I asked you, since I appreaciate your opinion.
:)
Mark M.
Drasko: I will be back with you in a bit
Andrey: do you have another question?
Andrey
My database initialization is painfully slow on the emulator. I wouldn't know about the EditText behaviour for a few more minutes.
No more questions yet
Mark M.
the x86 emulator should not be that bad
Andrey
But I was wondering about ContentProviders thing too :)
Mark M.
and if it is, and your problem is in database initialization, you may run into similar problems on some hardward
10:45 AM
Mark M.
er, hardware
if anything, disk access on an emulator is faster than on production hardware, because most Android devices' on-board flash is cheap (and, hence, slow)
Drasko: do you have another question?
Andrey
yes, I was thinking about it too
Drasko
no, thanks.
Andrey
my phone is fast
if anything, it's just one-time initialization
Mark M.
OK, if either of you come up with another question, just chime in
Andrey
maybe user will be willing to wait
So, I shouldn't count on emulators when performance testing, should I?
Mark M.
no
at least in terms of measuring real-world performance
in terms of measuring performance differences (i.e., is Implementation B better than Implementation A), it can still be useful
what are you doing in this one-time initialization?
10:50 AM
Andrey
populating the database
10:50 AM
Mark M.
how are you populating it?
Andrey
19000 rows
reading from the text file and doing some normalization
Mark M.
gadzooks
I wouldn't do that
unless the only source of the text file is via some Internet operation
Andrey
no, it's in the raw resources
Mark M.
if you are packaging the text file with the app, I'd use SQLiteAssetHelper and ship the database already populated
much, much faster
Andrey
It would weight 3 times more
Mark M.
so?
Andrey
I thought it might scare some users
maybe I'm just being silly here :)
Mark M.
versus scaring all of them by importing 19,000 rows on first run?
I mean, 19,000 insert statements, even with max optimizations (transactions, etc.) is going to be slow
Andrey
yes Mark
you are right, I should try SQLiteAssetHelper
Mark M.
it's at least worth an experiment
Andrey
I've come across it before, but decided to do it my way
10:55 AM
Mark M.
if you are going to start bumping up against hard size limits (e.g., Play Store 50MB), then SQLiteAssetHelper may not be an option
Andrey
no, just about 15
I'm having some problems with Eclipse, so I'll be back with the EditText question the next time, if you wouldn't mind :)
Is it tomorrow?
Mark M.
no, the next chat is Thursday at 4pm US Eastern Time
Drasko
what could be solution when SQliteAssetHelper is not an option.
Mark M.
Drasko: you could download the SQLite database, or package it in an APK expansion file
Andrey
Okay see you Thursday
Drasko
Bye.
Andrey
Thanks a lot for your help Mark
Mark M.
you are very welcome
note that the chat transcript will appear on http://commonsware.com/office-hours/ in a few minutes
Andrey
has left the room
Drasko
has left the room
Mark M.
turned off guest access

Tuesday, March 11

 

Office Hours

People in this transcript

  • Andrey
  • Drasko
  • Mark Murphy