Office Hours — Today, February 19

Friday, February 15

Feb 19
9:55 AM
Mark M.
has entered the room
Mark M.
turned on guest access
10:30 AM
Oliver
has entered the room
Mark M.
howdy, Oliver!
how can I help you today?
10:35 AM
Oliver
Hi - sorry I am a bit late...I owed you $$$ ;)
right...couple of questions
Mark M.
you are welcome to join whenever you want within the hour
and thanks for renewing! :-)
Oliver
boring question first
I am using nested fragments
special map fragment
and I need to configure that fragment a little
either to monitor the current GPS position
_OR_ just to show data (several tracks)
I have working code...so just a thumbs up would be great
I was originally sending arguments
partly because I am using a tabs adapter (just using a ViewPager) and args are easy to send with that
something like: mTabsAdapter.addTab(mTabHost.newTabSpec("map").setIndicator(res.getString(R.string.map)), MapFragment.class, args);
now...the problem with that...I found was that in other cases I Load the data
and swapping the fragment requires commitAllowingStateLoss()
so what I ended up doing was two code paths
(In the MapFragment)
View paste
    public void displayActiveSession() {
        mPresenter.setOnLastPointAction(MapPresenterImpl.LastPointAction.ZOOM);
        getLoaderManager().initLoader(LOADER_ACTIVE_SESSION, null, mActiveSessionCallback);
    }

    public void displaySessions(ArrayList<Uri> sessions) {
        mPresenter.setOnLastPointAction(MapPresenterImpl.LastPointAction.FULL_EXTENT);
10:40 AM
Oliver
and onActivityCreated(...)
View paste
        // Collect configuration
        Bundle args = getArguments();
        boolean monitor = args.getBoolean(MONITOR_ACTIVE_SESSION, false);
        boolean show = args != null && args.containsKey(SESSIONS) ? true : false;

        if (monitor) {
            displayActiveSession();
        }
        if (show) {
            ArrayList<Uri> sessions = getArguments().getParcelableArrayList(SESSIONS);
            displaySessions(sessions);
        }
that means I use the first block with loaders (by keeping a reference to the MapFragment in the parent)
and the second block I use with TabAdapters and the like
sorry
does that make sense?
Mark M.
um, not especially, to be honest
this is kinda complicated for a chat
what are your specific concerns with your implementation?
Oliver
that I am communicating the setup via two means
a) arguments
b) fragment methods
Mark M.
the problem with "fragment methods" is that there is no automatic onSaveInstanceState() support, as there is with arguments
so long as you are handling configuration changes properly for the data supplied by "fragment methods", that's OK
the beauty of the arguments Bundle is that it is saved for you without further work
Oliver
umm...I haven't
Mark M.
sounds like another item for your to-do list... :-)
Oliver
but the problem with loading (in my case) sessions with a loader is sending them to the Fragment as an argument - I have to do a transactions...and that requires a commit with state loss...which I am not too happy about - because I am not too sure on the consequences (great book topic ;)
10:45 AM
Oliver
(sorry typos)
Mark M.
I have yet to run into a valid use case for commitAllowingStateLoss()
there may be one
but I usually find that it is a (sometimes flawed) workaround to some other problem
Loaders also should be configuration-change-aware, though
but I am not sure why you think that "transactions" (fragment? database? other?) require "commit with state loss"
Oliver
so the book topic - Load the tracks and then pass them to the MapFragment using arguments
View paste (7 more lines)
            @Override
            public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
                ArrayList<Uri> sessions = new ArrayList<Uri>();

                if (data.moveToFirst()) {
                    do {
                        long id = data.getLong(data.getColumnIndex(SessionsContract.Surveys._ID));
                        sessions.add(Uri.withAppendedPath(SessionsContract.Sessions.CONTENT_URI, Long.toString(id)));
                    } while (data.moveToNext());
                }

                // Pass sessions to map fragment
                MapFragment mapFragment = new MapFragment();

                Bundle args = new Bundle();
...
Mark M.
other than the commitAllowingStateLoss() call, nothing leaps out at me as being necessarily a problem with what you have there
Oliver
I have seen some folk use handlers but my _feeling_ is that does not address the problem
and you are with me that I cannot use commit()
?
IllegalStateException etc.
10:50 AM
Mark M.
again, I find that such an exception indicates some other problem
10:50 AM
Mark M.
but without a stack trace and details, I cannot help much with that problem
Oliver
well it is because you cannot do fragment transactions within a loader call
Mark M.
that seems awfully specific
Oliver
Mark M.
oh, I know what that method JavaDocs says
again, usually I find that you can solve the underlying problem in some other way
Oliver
ok
I think we can leave it there - I will deal with restoring the fragment
Mark M.
if you can create a sample project that demonstrates your claim about "cannot do fragment transactions within a loader call", I'll be happy to look at it
Oliver
sure...I can easily do that
So the next question..I might have to catch you on Thursday
Mark M.
send the sample to mmurphy@commonsware.com and reference this chat, so I know the context
Oliver
I am not sure if setIntent works as I expected with a singleTop flag
Mark M.
I avoid setIntent() too
I have not run into a situation where it was needed
Oliver
search activity
Mark M.
just hold onto the Intent somewhere else (e.g., data member, parameter to methods)
again, hold onto the Intent somewhere else
the issue is your reliance on getIntent() as being the "one-stop shopping" way to get the launching Intent
10:55 AM
Mark M.
check some other spot first (for what you got in onNewIntent()), and if that's null, fall back to getIntent()
this avoids setIntent() and any oddities that it may have
(and I get the sense that setIntent() is odd, given some questions that have come up over the years)
Oliver
I am with you...it is not normally a problem...only if the activity is killed off
this case comes up from search
search (query comes in from intent)
Mark M.
"killed off"?
Oliver
new query comes in...you can see the new search results...you click on a search result...and lots more...then navigate back....and for end up going to the search results from the first query
running out of time...maybe best if I e-mail you...I can put it out on SO _but_ I think it is a bug
Mark M.
it's entirely possible that it's a bug, but, again, I don't use setIntent()
Oliver
ha! the documentation says use it with onNewIntent ;)
Mark M.
it may be worth asking on SO, in case somebody else has a solution
Oliver
awesome...I'll put those samples up and catch you on Thursday...cheers for you help.
*your
Mark M.
OK
note that Thursday's chat is at 4pm Eastern
11:00 AM
Oliver
ok...will do...I had a funny feeling it is 21:00 UK...but I'll check...all the best
Mark M.
that sounds about right
the transcript of today's chat will be posted to http://commonsware.com/office-hours/ shortly
have a pleasant day!
Oliver
has left the room
Mark M.
turned off guest access

Friday, February 15

 

Office Hours

People in this transcript

  • Mark Murphy
  • Oliver