Office Hours — Today, January 29

Yesterday, January 28

Jan 29
8:55 AM
Mark M.
has entered the room
Mark M.
turned on guest access
Mat
has entered the room
Mark M.
hello, Mat!
how can I help you today?
Mat
Hi there Mark
I have a quick question that i'd like your feedback on
Mark M.
go right ahead
Mat
I have a custom ApplicationSession where i store various app data. All my activities inherit from a common superclass
9:00 AM
Mat
In that superclass, in the oncreate, i take out the applicationobject and cast it into a parameter that i then can use in the activity, like so appSession = (ApplicationSession) getApplication();
then, in my fragments etc. i use main.getSession since i need it in lots of different places
(main) being the activity where ive added a public accessor for my application object
you with me so far?
Mark M.
yes
Mat
then. in my ondestroy() i set it to null. I did this years ago, but as far as i can remember i think its because i've read that sometimes activity objects are recycled and i wanted to make sure that the appsession wasn't lingering
Mark M.
activity objects are not recycled
that being said, setting fields to null is not harmful
Mat
however, i have started having some threaded tasks that sometimes can take 10-15 seconds to complete. these tasks need that sessionobject. Therefor if the user exits while a task is running, the object is null and the app crashes currently. I'm thinking about how to fix it
9:05 AM
Mark M.
the task should hold onto a reference to the session
Application objects live for the duration of the process
Mat
yeah i guess. But do you think its risk-free to not set that variable to null on app exit?
Mark M.
it's more that what you are describing is indicative of larger code issues
a background thread should not have *any* reference to an activity
at most, maybe some sort of WeakReference, but that's usually not all that useful
so long as that thread is running, the activity cannot be GC'd, even though it is destroyed
worse, various things that you might want to do with the activity will crash, because the activity is destroyed
Mat
youre right ofc
Mark M.
so, while not clearing that field is not itself an issue, the fact that you're thinking in terms of accessing that field *is* an issue, IMHO
Mat
its basically a thread that does a network call, and i want to update applicationsession json structures when it is done
Mark M.
the thread should have a reference to the session, not the activity that perhaps kicked off that thread
Mat
what you are saying is that i should try and get rid of the need for the thread to even have a reference to the activity, and just have the appsession.
:)
Mark M.
right
Mat
i have some debt that i havent had the time to address, basically
9:10 AM
Mat
one thing that i find mystifying - how about contexts? you know where you have to do activity.getcontext to look up strings etc. Are those context obects affected by activity lifecycle?
Mark M.
um, well, that depends on what "affected" means
Mat
let me elaborate
i have a networkhandler object, which is a way of centralizing network requests. In my activity oncreate, i create that object and keep it around for as long as the activity is alive
right now, i pass in the activity to the network handler. This is bad as we just discussed, but i did it way in the beginning, and haven't had the time to look at it... i code our ios and server side code as well.
in the networkhandler i use the activity reference to look up strings, show dialogs etc.
9:15 AM
Mat
i guess i could keep a reference to a context instead and use that everywhere, right, and i would still be able to use it (i.e. at least not have the app crash) if the activity has been destroyed
Mark M.
I would recommend an event bus
the networkhandler should not be showing dialogs
the networkhandler should be raising a ThisThingHappenedEvent
if that is of relevance to the foreground activity, it subscribes to receive such events, and it raises the dialog
Mat
yeah, i've done it that way in ios. i take it you mean that the thread should to broadcasts. i have that in some instances.
Mark M.
LocalBroadcastManager is an event bus, though I personally use greenrobot's instead
Mat
but it was so convenient to start and stop progressdialogs in the tasks preexecute and postexecute...
Mark M.
an AsyncTask, managed by a retained fragment, might show dialogs in those places
and, actually, I was misunderstanding -- I was thinking your networkhandler was of global scope, not per-activity
Mat
here's basically what happens:
1. user clicks on a button to do something in say one of my tabbed fragments.
2. it knows about main (the parent activity), does getNetworkHandler().doThenetworkFetch();
9:20 AM
Jamshaid A.
has entered the room
Mat
3. The network handler is basically a centralized class to have the network logic in one place. It created an asynctask (i have lots, logintask, fetchlocationsfetch etc)
Mark M.
(BTW, hello, Jamshaid -- I will be with you shortly!)
Jamshaid A.
thanks
Mat
3. the tasks create progressdialogs on start, removes after. all tasks have some sort of delegate interface thats supposed to deal with the outcome (success/failure)
4. the fragment itself could implement that delegate, evaluate and perhaps throw up a new dialog ("unable to fetch locations, network error" or something)
Mark M.
well, it's tough to really give you much advice, as your scenario is rather complex, with lots of moving parts
Mat
thats how it works now basically. and the problem is that main.getappsession sometimes is null when the locationfetch asynctask wants to update the appsession via main.getAppsession.updateLocations()
Mark M.
the general rule is: never touch the activity from doInBackground() or other stuff on a background thread
so, for this, you would want to have direct access to your session inside the task, not delegate to the activity
Mat
yeah well :) you gave good advice. I should make sure that all just use a context and the appsession everywhere
exactly. great stuff, i'll do that
Mark M.
you can't show a dialog using an Application object
anything involving the UI needs to work with the Activity via its retained fragment
conversely, anything on the background thread should not be referencing the activity, as you do not know what state that activity might be in at the time
and with that, let me take a question from Jamshaid, and I'll be back with you in a bit
Mat
no worries
Mark M.
Jamshaid: your turn! do you have a question?
9:25 AM
Jamshaid A.
View paste
i am working on an android based project.in the start we wanted a system where we just used our app as a launcher app.
Then as one cannot update the app without going through the google play store it was a broken experience
now instead i got system licenses so can create a system app
i was wondering to have a structure where this system app always stays around if the system app crashes in this scenario as all other apps are deleted
the system should just restart this single app
Mark M.
um, that's not really an application development question
Jamshaid A.
i hope i make sense was wondering if u coudl give me some advice on the subject
Mark M.
that's an Android OS/firmware question
hence, I cannot help you directly
Jamshaid A.
true
Mark M.
you would need to discuss this with whoever is responsible for building the ROM on which your app is installed
or, learn more about Android internals than I personally know
Jamshaid A.
is it possible to declare an app manifest somethign that if it crashes that it just restarts
Mark M.
no
Jamshaid A.
another thing is it possible to not display the exception message
incase if there is one
Mark M.
that you can handle yourself, by setting up a top-level uncaught exception handler
Jamshaid A.
i am able to install uninstall apps n already thought of a system where one app acts as a launcher n other services communicate using an event bus
can u elaborate a bit further how i might be able to have a top level uncaught exception handler
9:30 AM
Mark M.
well, since you really still need to collect crash data, the best solution IMHO is for you to use a library like ACRA, and set it up to not show any UI for the exception
I have a chapter on ACRA in the book
under the covers, ACRA (and all crash-logging libraries) use setDefaultUncaughtExceptionHandler() on Thread
that registers an UncaughtExceptionHandler, which is notified about all unhandled exceptions
ramsey
has entered the room
Jamshaid A.
thanks i will keep that in mind n get to it then ...
Mark M.
let me take a question from ramsey, and I will be back with you shortly
ramsey: your turn! do you have a question?
ramsey
If I have a class A { protected x; } and a subclass B of A. Is there a way of defining what x is outside of a lifecycle method?
Mark M.
well, B can access x whenever B wants to, in terms of Java access rules
ramsey
I want to define x to be a stub that I then implement in the subclasses
But I suppose I have to do it inside a method rather than as part of the definition of class B right?
Mark M.
well, it depends a lot on what x is
ramsey
(In this case A and B are activities)
x is a callback that I have defined
9:35 AM
Mark M.
if the declaration of the subclass/implementation of your stub require access to methods implemented on Activity or superclasses (e.g., Context), then you should not assign a value to x until onCreate()
9:35 AM
ramsey
* x is an implemenation of an interface
Mark M.
if, however, x is largely independent of that sort of thing when an instance is created, you could assign a value as part of initializing the field
for example, pretend that x is an int, not some interface of your design
ramsey
sure
Mark M.
x=0 is fine
x=getInt(R....) is not
because getInt() won't work until we get to onCreate()
ramsey
But would you have to define x=0 inside a method of B
Mark M.
from a Java syntax standpoint, I don't think B can assign a value to x via an initializer
ramsey
or can you write class A{ protected int x;}, class B extends A { x = 2;}
Mark M.
it could in a constructor, but usually we do not implement constructors on activities
ramsey
OK gotcha. It seemed a silly question but I was having a mind blank
Mark M.
I doubt that your proposed syntax works, though I do not recall actually trying it
ramsey
no I never have but I was confusing protected methods with fields. Silly me
Thanks mark
Mark M.
no worries
let me take questions from the others, and I'll come back to you in a bit
Mat: your turn! do you have another question?
9:40 AM
Mark M.
Mat: if you come up with another question, let me know
Jamshaid: back to you! do you have another question?
Jamshaid A.
no thanks i just got the book n learned that u have a chat sesson.i will for now follow up on the acra crash reporting thing.but i join next week
thanks
Mark M.
OK
ramsey: back to you! do you have another question?
OK, if anyone has a question, just chime in
9:50 AM
ramsey
has left the room
Mat
hey mate had clients calling...
Mark M.
no worries
Mat
i guess i don't have more questions, but here's my action plan:
ramsey
has entered the room
Mat
1. i will not set the appsession to null in ondestroy. that will take care of the crash in the short run
2. go through all my code and remove references to the activity in tasks etc.
3. medium-term take a look at greenrobot, it looked really neat
sound ok to you?
Mark M.
sounds fine
Mat
cheers. have a nice weekend!
Mark M.
you too!
ramsey
If I want to call a method every time the app opens from a terminated state is the place to do that in the Application subclass? (This is for syncing data with a server - I've found a SyncAdapter a bit ridic to use in the past)
9:55 AM
Mark M.
what is "a terminated state"?
ramsey
yeah good question. This is the brief from an iOS dev. So I imagine we'd have to say not in Recents
Mark M.
um
onCreate() on Application will be called when the process is created
so if "a terminated state" means "the process was terminated", then onCreate() on Application is one candidate
ramsey
Right. Actually I have a BaseActivity and the callback for the sync call probably needs to be defined in an activity subclass
So maybe my solution is to set a static boolean in Application and in onResume(), say, use that boolean to decide whether to call the download method?
Mark M.
um, I guess
I don't really know enough about your app to say whether that would meet your needs or not
10:00 AM
Jamshaid A.
has left the room
ramsey
Yeah fair. Sometimes a rubber duck is just useful
Thanks Mark
Have a fab weekend. So appreciate all you do
Mark M.
you are very welcome, even if you did just compare me to a children's toy, I think... :-)
anyway, that's a wrap for today's chat
ramsey
haha. affectionately though
Mark M.
the next one is Tuesday at 7:30pm US Eastern
(I bet you say that to *all* the ducks...)
this chat's transcript will be posted to https://commonsware.com/office-hours/ shortly
have a pleasant day!
Mat
has left the room
ramsey
has left the room
Mark M.
turned off guest access

Yesterday, January 28

 

Office Hours

People in this transcript

  • Jamshaid Ali
  • Mark Murphy
  • Mat
  • ramsey