Office Hours — Today, September 10

Tuesday, September 8

Sep 10
7:25 PM
Mark M.
has entered the room
Mark M.
turned on guest access
Abhishek K.
has entered the room
Mark M.
hello, Abhishek!
how can I help you today?
Abhishek K.
Hello
Hey Mark, actually I'm stuck with my implementation of ListenableWorker
Mark M.
OK, I have not used that directly, only via Worker, but perhaps I can still help
7:30 PM
Abhishek K.
I've to use a library to download a file over the internet and this thing I have to do even if app is in background, hence I started using WOrkManager. Now, I started with CorotuineWorker, but as the library has its own thread of execution, I got into a situation where CoRoutineWorker completes its execution before the library completes in completion callback
First question is - is there any way we can block the CorotuineWOrker's thread and complete it only in completion callback of the library?
Mark M.
are you using suspendCoroutine() or suspendCancellableCoroutine()? or how are you setting up bridging between the callback API and coroutines?
7:35 PM
Abhishek K.
no, I was not aware of of either of it at the time of implementation. And hence I read about ListenableWorker, where google says that if we want to have our own thread execution, we can go for it. Now when I used ListenableWorker, setProgressAsync is not updating the Livedata in my activity
Mark M.
*Elements of Kotlin Coroutines* has material on suspendCoroutine() and suspendCancellableCoroutine(): https://wares.commonsware.com/app/internal/book...
Abhishek K.
So you're saying, using one of these 2, we can suspend the CoroutineWorker's execution and completes it in one of our callback from the library?
Mark M.
correct
Abhishek K.
that sounds great.
Mark, one more thing
in any case if I have to use ListenableWorker in my situation, why would setProgressAsync not update the LiveData?
Mark M.
I have no idea, sorry
Abhishek K.
didn't find much over the internet about ListenableWorker
7:40 PM
Mark M.
I assume that the LiveData that you are referring to is a workinfo one?
Abhishek K.
Yeah
Mark M.
such as from getWorkInfoByIdLiveData()?
Abhishek K.
yeah, exactly that one
Tad F.
has entered the room
Mark M.
OK, then, yeah, I don't know why that is not working for you
Tad F.
Hi Mark!
Mark M.
you might try peeking at the source code to Worker or RxWorker to see if you see anything there that might give you some clues
(hi, Tad! I'll be with you shortly!)
or, try the coroutine options that we discussed
Abhishek K.
Okay mark.
Mark M.
if you're already into coroutines, that would be the direction that I would go
let me take a question from Tad, and I will come back to you in a bit
Abhishek K.
CoroutineWorker sounds better
Mark M.
Tad: your turn! how can I help you today?
Tad F.
I am struggling a little bit trying to properly do type definition with Generics
I have an Abstract "Chooser" class, which defines a RecyclerView adapter and holder, in a generic way like this;
abstract class ChooserAdapter<T extends CardListable, VH extends ChooserHolder<T>> extends RecyclerView.Adapter<VH> {
View paste
 abstract class ChooserHolder<T extends CardListable> extends RecyclerView.ViewHolder
                                    implements View.OnClickListener,
                                    View.OnLongClickListener {
This class also needs access to a member variable which it expects subclasses will provide to it.
7:45 PM
Tad F.
The variable is: ChooserAdapter<CardListable,ChooserHolder<CardListable>> mChooserAdapter;
The method this class calls its subclasses to get the proper implementation is:
protected abstract ChooserAdapter<CardListable,ChooserHolder<CardListable>> getAdapterForRecyclerView();
This is all well and good, and all this compiles cleanly.
On my implementation class, I also have this working
A class that choose "Contact" objects for example:
class ContactChooserAdapter extends ChooserAdapter<Contact, ContactChooserViewHolder> {
class ContactChooserViewHolder extends ChooserHolder<Contact>
The PROBLEM is trying to implement the abstract method that the parent class expects
It seems that this non-typed example:
View paste
    @Override
    protected ChooserAdapter getAdapterForRecyclerView() {
        return new ContactChooserAdapter(InTouchDataMgr.get().getContacts(realm));
    }
Works fine, but of course Lint complains
"Raw use of paramaterized class", which it should
But I can't seem to get the typed parameters correct
Mark M.
how is Chooser itself declared? it feels like you need generics there and in the abstract function definition
protected abstract ChooserAdapter<T,ChooserHolder<T>> getAdapterForRecyclerView();
or: protected abstract ChooserAdapter<T,VH> getAdapterForRecyclerView();
7:50 PM
Tad F.
I can do that, and it compiles, but one of the behaviors I need from the implementing classes is that I know that "T" has implemented this interface called "CardListable", because I used methods on it in the abstract class.
I tried:
View paste
    @Override
    protected ChooserAdapter<CardListable,ChooserHolder<CardListable>> getAdapterForRecyclerView() {
        return new ContactChooserAdapter(InTouchDataMgr.get().getContacts(realm));
    }
But that fails compilation
For example - I have this line in the abstract class:
mSelectedPositions.putBoolean(mChooserAdapter.getData().get(0).getId(), true);
that "getId()" method is in CardListable interface
So if I do: protected abstract ChooserAdapter<T,ChooserHolder<T>> getAdapterForRecyclerView();
I don't get that, and I have to cast that call to CardListable
Which kind of foils the whole point of what I'm trying to do with the generics
Mark M.
declare it as T extends CardListable in your Chooser declaration
Tad F.
I think I tried that actually
But I'll check
Mark M.
I would expect your declaration of Chooser to look a lot like the ChooserAdapter one you pasted in earlier
insofar as it uses T extends CardListable
Tad F.
Are you talking about the declaration of the method that returns the adapter?
Mark M.
then your getAdapterForRecyclerView() abstract declaration can return stuff based on T
Tad F.
When you say "Chooser", what are you referring to?
Mark M.
In my "I would expect" sentence, I was referring to the class
Tad F.
OK so you mean my implementation of the abstract ChooserAdapter?
ContactChooserAdapter?
Sorry, I'm confused
Mark M.
I am going back to: "I have an Abstract "Chooser" class, which defines a RecyclerView adapter and holder, in a generic way like this"
7:55 PM
Mark M.
that class, called Chooser, needs generics in its declaration
(at least, I think -- it's tough to keep all this straight)
Tad F.
OK sorry - let me be more precise. I have an AbstractChooserActivity. Inside that I have a ChooserAdapter and a ChooserHolder.
Both of the latter are abstract
that's what I posted above
Mark M.
so is AbstractChooserActivity, if the name is accurate
Tad F.
Yes - I have a series of activities in my app, all of which "choose something", so I've tried to abstract out common behavior to this base class
All of them have a recyclerview.
Mark M.
I think AbstractChooserActivity's declaration needs its own generics for T and VH
that is basically the "root" of your tree of related classes that are using generics
(activity using the adapter that uses the viewholder)
Tad F.
Hmmmm.... ok. I have not implemented any constructors in any activities. Just overloaded onCreate(), etc.
This class extends AppCompatActivity
Mark M.
you don't need a constructor
Tad F.
Where do the generics go?
Mark M.
abstract class AbstractChooserActivity<T extends CardListable, VH extends ChooserHolder<T>>
protected abstract ChooserAdapter<T, VH> getAdapterForRecyclerView();
Tad F.
Oh ok - you mean at the scope of the entire class, etc.
ok
Mark M.
right
Tad F.
ok I'll play with that.
8:00 PM
Mark M.
let me take another question from Abhishek, and I'll come back to you in a bit
Abhishek K.
Hey Mark, can I come in?
Tad F.
Sure - that's it for me anyway, thanks!
Mark M.
yes! do you have another question?
Abhishek K.
I just tried suspendCoroutine while you guys were having the discussion, it seems like suspendCoroutine is already deprecated
and one more thing, when I use resumeWithException or resume, it says, "Method are absent in corotuine class since 1.3"
Mark M.
suspendCancellableCoroutine() isn't according to the docs: https://kotlin.github.io/kotlinx.coroutines/kot...
but, yeah, something is up with suspendCoroutine() -- it's outright missing from the docs
what version of Kotlin are you using?
Abhishek K.
1.3.72
Mark M.
and what version of coroutines?
8:05 PM
Abhishek K.
lemme check
Mark M.
OK, here is suspendCoroutine() in docs: https://kotlinlang.org/api/latest/jvm/stdlib/ko...
Abhishek K.
So, if I use both koltin and coroutine with the latest version, it should work well?
is it?
Mark M.
well, I have only used suspendCancellableCoroutine() personally, as usually the APIs that I use have some sort of "cancel" semantics
Abhishek K.
Okay.
Mark M.
I am trying to make sense of the coroutines GitHub repo to try to determine if they removed it
Abhishek K.
It seems, suspendCancellableCoroutine would work anyway, even if coroutineWorker is removed
8:10 PM
Mark M.
what do you mean by "removed"?
Abhishek K.
suspendCoroutine is removed**
sorry
Mark M.
ah, right
yeah, it feels like they may have gotten rid of suspendCoroutine somewhere along the line
Abhishek K.
Okay.
suspendCancellableCoroutine then
Mark M.
I'll have to figure out what is going on with suspendCoroutine()
Abhishek K.
one last thing from my side
Mark M.
OK, go ahead
Abhishek K.
while using suspendCancellableCoroutine, in completion callback, we can anyway resume the coroutine, what can we do in download progress callback/
can we still use the same resume with progress values
Mark M.
um, nothing
a suspending function only returns one thing
this isn't a Flow or Channel
Abhishek K.
we can use setProgress(Data()) right?
Mark M.
in your CoroutineWorker? it is worth a try, but I have not tried that
Abhishek K.
Okay.
8:15 PM
Abhishek K.
I'm done from my side Mark. It was really great having the discussion with you.
Thank You so much.
Mark M.
you're welcome!
Tad: do you have another question?
Abhishek K.
has left the room
8:30 PM
Tad F.
has left the room
Mark M.
turned off guest access

Tuesday, September 8

 

Office Hours

People in this transcript

  • Abhishek Kumar
  • Mark Murphy
  • Tad Frysinger