Office Hours — Today, April 11

Yesterday, April 10

Apr 11
8:55 AM
Mark M.
has entered the room
Mark M.
turned on guest access
Anurag S.
has entered the room
Anurag S.
View paste
Hi Mark,

Hope yare doing well.
Mark M.
hello, Anurag!
how can I help you today?
Anurag S.
View paste
In my application n number of IntentService are created and launched in parallelly. 
Any IntenetService is used to perform either db(sqlite) operation or network(retrofit) operation or both.

There is a situation when I need to stop or cancle all the IntenetService's if running and let any one of them running on choice.
Or stop, cancle all the IntenetService's if running and start the other service of choice.

I will also be uing the JobIntentService to defer the jobs if application is not in foreground for syncing all the data which will be implemented in phase two.

Should I replcae all IntenetService with JobIntentService and use Evernote android job. Although, all the jobs in queue will only be cancled.
But what about alreay running jobs? They won't be cancled in between?

minSdkVersion 22

Could you think of any possible soultion with current existing implementation or propose a new design approach without freezing the UI?
Mark M.
I do not recommend your "n number of IntentService" approach
use one service, that has a thread pool (e.g., ThreadPoolExecutor)
where you stop that service when the thread pool is empty, or after the thread pool has been empty for some period of time
9:00 AM
Mark M.
I am not certain whether JobIntentService supports multiple parallel jobs or not
OK, it looks like it only does one job at a time
onHandleWork() has "Called serially for each work dispatched to and processed by the service"
Anurag S.
Yes, exactly.
Then how to approach
?
Inside IntentService create ThreadPoolExecutor and try submitting the jobs?
Mark M.
no
first: why are you using services for any of this?
if this work is largely started by the UI, you would not seem to need a service for simple database I/O or REST calls
if the trigger for this work is something other than the UI, "if application is not in foreground", what is the trigger?
Anurag S.
I am using because if I move away from activity the also the work should continue.
Mark M.
but the work should take milliseconds
9:05 AM
Mark M.
right?
Anurag S.
My application works in offline mode too/
It has to sync all data with file upload and keeping in mind the old dat should be synced in last and newer operation first.
Basically the submitted work should continue in background and the UI should be notified accordingly.
Mark M.
OK, but, even so, this would seem to require one service to do one bit of work (that might take seconds)
Anurag S.
Even if application is closed or user navigates away from UI.
Mark M.
so, why do you need N services? and why are you worried about cancelling something that will take very little time to execute?
Anurag S.
So, suppose user captures a few picture and add some caption to it. User navigates to another screen and performs pull to refresh. User has to wait before all files are uploaded.
9:10 AM
Mark M.
pull-to-refresh would not involve a service, most likely
Anurag S.
If I am using one service then all the further requests will be queued.
Mark M.
based on your previous comment, IMHO they have to be queued ("It has to sync all data with file upload and keeping in mind the old dat should be synced in last and newer operation first.")
at least, for any data modification operations
whether you can do pull-to-refresh in a background thread while the service is doing a sync operation depends as much on the server as it does in your app
Anurag S.
I will ponder what you wrote (as usual you have given me MUCH to think about).
What about "use one service, that has a thread pool (e.g., ThreadPoolExecutor)" that you mentioned earlier.
I miss markdown support :-(
Mark M.
I was just commenting on Markdown in the chats yesterday with somebody else :-)
unfortunately, while Campfire works really well in general for my use case, it doesn't offer Markdown
Anurag S.
... :-)
9:15 AM
Anurag S.
It's ok I am fine.
9:15 AM
Mark M.
my comment regarding ThreadPoolExecutor was aimed at avoiding N services
but a pull-to-refresh operation does not necessarily require a service
Anurag S.
OK.
Pull to refeesh dose two jos fetch data based on timestamp and inser/update data in db and then notify the UI where DiffUtils run in RecyclerView to update UI.
Mark M.
that should be fairly quick and therefore would not need to be managed by a service
have your repository or something use a background thread (e.g., RxJava)
Anurag S.
Ok, so should I craete one THreadPoolExecuter for the complete application.
If I am not using RxJava as of now.
?
Mark M.
you could have a singleton ThreadPoolExecutor that you use for both in-UI work (e.g., pull-to-refresh) and for a service
the key would be how the service knows to stop itself
9:20 AM
Mark M.
as if you are using the thread pool for other things, the service cannot use an empty thread pool as an indicator that it could shut down
Anurag S.
I agree. Right now I use a static variable to stop the service
Another question if You don't have to throw some more insight:
May I proceed with next question?
Mark M.
sure!
Anurag S.
View paste (6 more lines)
My application supports portrait mode only on Mobile and portrait, landscape for Tablet. I am setting not default portrait or lanscape in manifest. 

I am only declaring Activity with android:configChanges="orientation|screenSize in manifest.

However if the app running on device haapens to be table then I execute a conditional statement for tablet only as:

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (!isDeviceTablet()) {
            LoggerUtils.info(TAG, "isMobile: ");
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        super.onCreate(savedInstanceState);
    }

...
Mark M.
well, the best approach is to support all orientations on all devices
after all, with multi-window, you have limited control over window sizes
particularly with freeform multi-window (e.g., Chrome OS)
9:25 AM
Mark M.
in terms of your existing implementation, I am not surprised at the behavior
about the only thing that I can think of to avoid it would be to use <activity-alias> to set up a parallel set of "activities", where you force the screen orientation to portrait, and use those aliases (instead of the real activities) for !isDeviceTablet() scenarios
Anurag S.
Great!
Mark M.
getting the launcher right might be tricky and may involve an invisible activity (Theme.Translucent.NoTitleBar) to redirect the user to the proper activity based isDeviceTablet()
Anurag S.
:-)
Mark M.
I have no idea if this would work, and I would rather invest the time in landscape support for all devices
but, if you're insistent upon portrait-only for smaller screens, it's worth a try
Anurag S.
Sure, I will try the above suggestion.
Another question:
I want all the Fragments to register with EventBus because they will be updated according based on the action from any Fragment of ViewPager?
Mark M.
sorry, but I do not understand your question
9:30 AM
Anurag S.
I am using ViewPager and using GalleryFragment where EventBus is registered.
Suppose I am showing three fragments and I am viewing the 2nd fragment.
I perform a ntwork operation from 2nd and base upon the response I want to update all the three accordingly.
EventBus dose not allow me to register because it's alraedy being registered.
Mark M.
EventBus requires distinct objects
Anurag S.
Sorry, Re-register.
Mark M.
so, each fragment should be able to register
but you cannot register the hosting activity three times
Anurag S.
Activity is registered once only.
Each fragment should be able to register. I also agree but it's seems to be not working.
Mark M.
what are the specific symptoms?
9:35 AM
Anurag S.
An error in logcat already registerd
View paste
I used @Override
    public void onResume() {
        LoggerUtils.info(TAG, "onResume()::");
        super.onResume();
        if (!EventBus.getDefault().hasSubscriberForEvent(CancelEvent.class)) {
            EventBus.getDefault().register(this);
        } else {
            EventBus.getDefault().unregister(this);
            EventBus.getDefault().register(this);
        }

    }
Mark M.
and this is in the fragment?
Anurag S.
Yes
Mark M.
I cannot explain that, sorry
Anurag S.
NO, problem
Mark M.
you would need to take it up with the EventBus authors, or consider other approaches (e.g., a shared ViewModel, as I do in the MVI samples in "Android's Architecture Components"
Anurag S.
Yes I read and I will implement all of this in phase 2.
It's just about the release.
Another question:
View paste
I am fetching media from external camera using flash air sd card in dsrl camera.
I am using FetchMediaIntentService to fetch all the images one by one and show in a GalleryViewAdapter.

I post events from FetchMediaIntentService using EventBus to notify the GalleryViewActivity about newly fethced media(thumbnail), 
update previously fetched media(full version of thumbnail) which in turn calls notifyItemInserted or notifyItemChanged method of GalleryViewAdapter accordingly. 

I am receiving the images at bullet speed. EventBus also posts event at a very fast speed and while GalleryViewActivity tries to notify the GalleryViewAdapter sometimes the application crashes.

Fatal Exception: java.lang.IndexOutOfBoundsException
Inconsistency detected. Invalid view holder adapter positionViewHolder{574ebea position=94 id=-1, oldPos=0, pLpos:0 scrap [attachedScrap] tmpDetached no parent} com.afollestad.dragselectrecyclerview.DragSelectRecyclerView{890a74a VFED..... .F....I. 0,260-1080,1554 #7f0901b0 app:id/recycler_view}, adapter:somepackage.GalleryViewAdapter@5cbf6bb, layout:android.support.v7.widget.GridLayoutManager@ca737d8, context:somepackage.GalleryViewActivity@d54a1ce

I understand that
...
Mark M.
I have no idea, sorry
9:40 AM
Mark M.
you might temporarily switch to a regular RecyclerView, instead of DragSelectRecyclerView, and see if the problem continues
if the problem goes away, then it may be an issue with DragSelectRecyclerView, and you would need to work with its author (as I assume that's from a library)
Anurag S.
If I switch to RecyclerView it's very rarest that the exception occurs, but using DragSelectRecyclerView it's frequent.
Mark M.
I have not seen that error message before, and so I do not know what likely causes are
Anurag S.
It's ok
Another very quick question:
I am using recyclerview and shoing two edittext in each row.
I am usng realm for this.
For storing the response.
9:45 AM
Anurag S.
User can or cannot change the existing value in editetext.
I want to use some kind of dirty check inorder to avoid to saving all the field every time user switches to another tab.
There are four tabs and all tabs have same UI but with different type of data capturing.
Am I making sense.
Mark M.
yes, though you have not really asked a question here
so, I am not certain what to tell you
Anurag S.
I do not want to update all the rows in db every time the user switches to another tab. Instead save only modified values in order to save battery drain from n number of read/write.
Mark M.
so, do that
9:50 AM
Mark M.
somewhere, you have code that is taking data from the UI, updating a Realm object, and persisting it
9:50 AM
Anurag S.
Yes
Mark M.
make sure that you have a copy of the original data populated in the UI (e.g., the original Realm object), and do your comparisons
it's possible that Realm already has stuff for this -- I know of Realm but haven't used it personally
Anurag S.
Actually it is not.
But still I would look into it.
Mark M.
then, you would need to change your "update the Realm object" code to "compare the Realm object against the UI, and only update the Realm object if data changed" code
Anurag S.
Ok. Is there any way of getting edittext field id with data in recyclerview when user changes from one edittext to another. Or switches to another tab then grab the last focused edittext field id with value Or presses back navigation button?
Mark M.
I would check everything in the tab
Anurag S.
Realm is really good if memory is limited
9:55 AM
Mark M.
there are focus-change listeners that you can register, IIRC, but I would not bother, and I would check everything in the tab
Anurag S.
Ok
Registering focus change listeners in recycler view makes the application to use more memory.
Mark M.
that's possible, but IMHO it's also more complicated
Anurag S.
Yes, agree many conditions to handle and user can tap anywhere.
Mark M.
though, to be honest, I am not certain why you are using a RecyclerView for a data-entry form
Anurag S.
Thankyou Mark, I will ponder what you wrote (as usual you have given me MUCH to think about).
Mark M.
OK
Anurag S.
Thankyou, you have been of great help! Thankyou, for your precious time! Take care :-)!
Mark M.
you're welcome!
10:00 AM
Mark M.
that concludes today's chat
the transcript will be posted to https://commonsware.com/office-hours/ in a bit
the next office hours are tomorrow at 7:30pm US Eastern
have a pleasant day!
Anurag S.
has left the room
Mark M.
turned off guest access

Yesterday, April 10

 

Office Hours

People in this transcript

  • Anurag Singh
  • Mark Murphy