Office Hours — Today, March 31

Tuesday, March 29

Mar 31
7:25 PM
Mark M.
has entered the room
Mark M.
turned on guest access
Steve S.
has entered the room
Mark M.
hello, Steve!
how can I help you today?
Steve S.
Hi Mark!
I have a question regarding the activity lifecycle. I'll upload it.
View paste
. I have a question related to the activity lifecycle My understanding from prior chats is that a reasonable approach in a lot of cases is to set things up in onResume() and shut things down in onPause(). For instance, onResume() is often a good place to register BroadcastReceivers and onPause() to unregister them. However, I've seen examples where things like canceling  Bluetooth discovery, unregistering BroadcastReceivers, and canceling downloads is done in onDestroy(). (For instance, the BluetoothChat example in the samples in the Android SDK cancels Bluetooth discovery and unregisters a BroadcastReceiver in onDestroy().) 

My understanding is that onDestroy(), unlike onPause(), is not always called. So I'm wondering why these examples shut things down in onDestroy(). Is it correct to do so?
7:30 PM
Mark M.
well, I can't speak for those example authors
Steve S.
Sure
Mark M.
and, since I know both diddly and squat about the Bluetooth APIs, I cannot speak specifically about whether what they're doing makes sense for that
Steve S.
What would you recommend?
ok
Mark M.
the only scenarios that I know of when onDestroy() will not be called are:
1. if the process is terminated with extreme prejudice (e.g., Force Stop)
2. you crash with an unhandled exception
and, that's pretty much it
*usually*, onDestroy() gets called
*when* it gets called is another matter
Steve S.
ok
Mark M.
it might be quite some time, depending on a variety of environmental factors (amount of system RAM, how busy the other apps are, etc.)
and so anything you delay cleaning up until onDestroy() may be active for a while
that could be a good thing or a bad thing, depending on circumstances
usually, I consider it to be a bad thing
as probably either you should be cleaning it up sooner or you should be having a service manage whatever it is
but, there's no hard-and-fast rule for this
Moe
has entered the room
Steve S.
This is helpful.
Mark M.
OK, good, because I wasn't sure if it was useful or not for your inquiry
7:35 PM
Mark M.
let me take a question from Moe, and I'll be back with you shortly
Steve S.
So it sounds like if onDestroyed() isn't called, the system wold be messed up enough anyway that it wouldn't matter.
Mark M.
Moe: hi! do you have a question?
Moe
hi mark
Steve S.
sure, thanks
Moe
yeah, something to do with Android Studio
Hi Steve
o here is the error I'm getting
Steve S.
hi moe
Moe
View paste
Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/services/javax.annotation.processing.Processor
  	File1: /Applications/Android Studio.app/Contents/gradle/m2repository/com/tunnelvisionlabs/antlr4-annotations/4.5/antlr4-annotations-4.5.jar
  	File2: /Applications/Android Studio.app/Contents/gradle/m2repository/com/tunnelvisionlabs/antlr4-runtime/4.5/antlr4-runtime-4.5.jar
I removed one of these files, but then it complains that the file is needed
removed the other, same thing
this seems to be a question better suited for Stackoverflow
Mark M.
um, are these official ANTLR artifacts?
I haven't used ANTLR in years
Moe
but thought you've might faced something similar
honestly Mark I have no idea, but I suspect one of the libraries I've added
because things were going OK before I added few libraries
including Realm
Mark M.
oh, you're not requesting these as dependencies yourself directly?
Moe
no
Mark M.
you can use the Gradle dependency report to track down who is pulling those in: https://docs.gradle.org/current/userguide/tutor...
(fortunately, I had the direct link handy!)
Moe
Ok, thanks
I also see these warnings
View paste
Information:Gradle tasks [:app:clean, :app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:prepareDebugUnitTestDependencies, :app:mockableAndroidJar, :app:assembleDebug]
Warning:Dependency org.apache.httpcomponents:httpclient:4.1.1 is ignored for debug as it may be conflicting with the internal version provided by Android.
         In case of problem, please repackage it with jarjar to change the class packages
Warning:Dependency commons-logging:commons-logging:1.1.1 is ignored for debug as it may be conflicting with the internal version provided by Android.
         In case of problem, please repackage it with jarjar to change the class packages
Warning:Dependency org.apache.httpcomponents:httpclient:4.1.1 is ignored for release as it may be conflicting with the internal version provided by Android.
         In case of problem, please repackage it with jarjar to change the class packages
Warning:Dependency commons-logging:commons-logging:1.1.1 is ignored for release as it may be conflicting with the internal version provided by Android.
         In case of problem, please repackage it with jarjar to change the class packages
:app:clean
:app:preBuild UP-TO-DATE
:ap
...
But they don't seem to prevent the build
7:40 PM
Mark M.
no, but they may cause other problems
make sure that whatever is pulling this stuff in is set up to work on Android
Moe
mostly are everyday stuff
Mark M.
it may be that you're pulling in some library that was designed for ordinary Java, that may or may not be working on Android
Moe
Retrofit, OKHttp and the likes
will look again into them
Mark M.
I'm sure Square isn't pulling that stuff in, though I can't rule out Realm
Moe
yeah, things started with Realm
here is what I'm using
View paste
apply plugin: 'realm-android'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:support-v4:23.1.1'
    compile 'com.android.support:recyclerview-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.android.support:cardview-v7:23.1.1'
    compile "io.realm:realm-gradle-plugin:0.88.2"
}
Mark M.
wait
realm-gradle-plugin probably doesn't go there
Gradle plugins go in the dependencies closure inside the buildscript closure, in the top-level build.gradle file
Moe
I moved it from there for some reason, but this seems like a good start
Mark M.
double-check the Realm docs to see where that goes
Moe
will start investigating here first
Ok, thanks Mark
Mark M.
everything else, as you say, seems fairly normal
let me take a question from Steve, and I'll be back with you in a bit
Steve: your turn! do you have another question?
Moe
I try to keep this way
Ok, thanks
7:45 PM
Moe
that's it for me today, have a great evening guys
Steve S.
Getting back to my earlier question: it sounds like if onDestroyed() isn't called, that would be because things are so messed up that it wouldn't matter. Is that right?
Mark M.
well, either the process is gone (in which case, you probably don't care about whatever didn't get cleaned up), or you crashed (in which case, you have bigger problems)
Steve S.
Great, that helps.
Here's another question:
View paste
I have another question regarding what kind of cleanup needs to be after setting an adapter for a ListView. I've seen some code that uses a ListFragment for which an adapter is set in onViewCreated(). Then, in onDestroyView(), setListAdapter(null) is called. The adapter is a member variable of the fragment.

 Is setListAdapter(null) called to avoid memory leaks since the adapter holds a reference to the activity and is a member variable of the fragment? If the adapter were a local variable instead, would setListAdapter(null) still need to be called in onDestroyView()? Would this need to be done if the class were an activity rather than a fragment?
Mark M.
I haven't seen code use setListAdapter(null)
it might be part of a "hey, let's help the GC engine out" effort
Steve S.
I see. So there's no reason to do that.
Mark M.
none that I am aware of
if the ListView gets destroyed, its reference to the adapter should be let go
Steve S.
Thank you. That's very helpful.
Mark M.
now, it could be that there's something goofy with ListFragment that I'm not aware of, where calling setListAdapter(null) has benefit
Steve S.
ok
Mark M.
but I haven't encountered it
it's also a cheap call, so if you want to do it, for a "belt-and-suspenders" sort of thing, go right ahead
Steve S.
Great. I won't worry about doing that.
Mark M.
personally, I'd wait until I had concrete evidence of a memory leak, like a LeakCanary singing
7:50 PM
Mark M.
let me take another question from Moe, and I'll be with you again shortly
Steve S.
I don't have any more questions today. Thank you so much for your help! Have a great evening, Mark.
Mark M.
Moe: your turn! do you have another question?
(Steve: you too!)
Steve S.
has left the room
8:00 PM
Moe
has left the room
8:25 PM
Mark M.
turned off guest access

Tuesday, March 29

 

Office Hours

People in this transcript

  • Mark Murphy
  • Moe
  • Steve S.