Verified
Status Update
Comments
yb...@google.com <yb...@google.com>
cc...@google.com <cc...@google.com> #2
Would you be able to describe your use case of why you need to do on the order of hundreds of directions requests please?
cc...@google.com <cc...@google.com> #3
Sure. This is my application: http://lstsim.de/
It is in German, so here's a short description: It's a simulation of an emergency services dispatch center. The user is in charge of sending ambulances to different places all over the area. I'm using the Directions Service, so the ambulances on the map use the actual roads (and even respect the speed limits). Every trip from one location to another takes a single request. This allows me to achieve a pretty realistic replication of the reality.
This also means I don't actually need a routing request every second, but it rather depends on how busy things are in the game. My users were reporting routing errors usually after 300 routings and about an hour or so of playing, so you get an idea of the average request rate.
It is in German, so here's a short description: It's a simulation of an emergency services dispatch center. The user is in charge of sending ambulances to different places all over the area. I'm using the Directions Service, so the ambulances on the map use the actual roads (and even respect the speed limits). Every trip from one location to another takes a single request. This allows me to achieve a pretty realistic replication of the reality.
This also means I don't actually need a routing request every second, but it rather depends on how busy things are in the game. My users were reporting routing errors usually after 300 routings and about an hour or so of playing, so you get an idea of the average request rate.
56...@gmail.com <56...@gmail.com> #4
This problem sounds similar to behavior I am seeing with versions 3.10+ ... my application allows users to create maps of their addresses. After 200 or so rows the geocoder becomes very very slow, even if I delay geocodes 5-10 seconds in-between.
Since the limit is 2500 per day, does it not seem reasonable that you would be able to send a geocode 1 per second as you have in the past until you reach 2500? If this is a change to the quota and limits of the free google maps API please let us know.
Since the limit is 2500 per day, does it not seem reasonable that you would be able to send a geocode 1 per second as you have in the past until you reach 2500? If this is a change to the quota and limits of the free google maps API please let us know.
cc...@google.com <cc...@google.com> #5
Google is forcing 3.10 now so there is no using 3.9 to get around this bug.
I need to know if this is a permanent change on geocoding quotas or if this is truly a bug. If it is a permanent change I will need to make big changes to our app so users can only create maps of 200 or less points, whereas before it was possible to create 2500 marker maps.
I need to know if this is a permanent change on geocoding quotas or if this is truly a bug. If it is a permanent change I will need to make big changes to our app so users can only create maps of 200 or less points, whereas before it was possible to create 2500 marker maps.
Description
Version used: 1.0.0-alpha2
Devices/Android versions reproduced on:
Android O
Unit tests in Android studio
- Sample project to trigger the issue.
- A screenrecord or screenshots showing the issue (if UI related).
We are seeing crashes with the following stack trace:
10-03 09:42:42.633 26917 26917 E AndroidRuntime: FATAL EXCEPTION: main
10-03 09:42:42.633 26917 26917 E AndroidRuntime: Process:
10-03 09:42:42.633 26917 26917 E AndroidRuntime: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{d08cbcb position=84 id=-1, oldPos=75, pLpos:55 scrap [attachedScrap] tmpDetached no parent} android.support.v7.widget.RecyclerView{804e943 VFED..... ......ID 0,0-1080,795 #7f080071 app:id/group_feed_recycler_view}, adapter:com.app.name.ui.main.GroupFeedRowAdapter@5fbebc0, layout:android.support.v7.widget.LinearLayoutManager@49810f9, context:com.app.name.ui.main.MainActivity@cf99efb
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5421)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5603)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5563)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5559)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2229)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1556)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1516)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:618)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3644)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3408)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1710)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4806)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.view.Choreographer.doCallbacks(Choreographer.java:723)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:655)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:789)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:98)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.os.Looper.loop(Looper.java:164)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6541)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
10-03 09:42:42.633 26917 26917 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
We also see the same issue when running unit tests using the instant run rule:
@Rule
public TestRule instantRunRule = new InstantTaskExecutorRule();
We think the problem is that the adapter is calling notifyItemRangeInserted before updating the list the adapter is using.
We are currently using a workaround in our code to try and provide the correct list when the adapter is asked for it:
private List<Item> mListSnapshot;
private PagedList<Item> mList;
public void setList(PagedList<Item> list)
{
mList = list;
mListSnapshot = list.snapshot();
super.setList(list);
}
public int getItemCount()
{
if (mList != super.getCurrentList())
{
// The adapter is calculating a diff
return (mListSnapshot == null) ? 0 : mListSnapshot.size();
}
return (mList == null) ? 0 : mList.size();
}
public Item getItem(int index)
{
if (mList != super.getCurrentList())
{
if (mListSnapshot == null)
{
throw new IndexOutOfBoundsException("Item count is zero, getItem() call is invalid");
}
// No loadAround as the snapshot is not a paged list
return mListSnapshot.get(index);
}
else
{
if (mList == null)
{
throw new IndexOutOfBoundsException("Item count is zero, getItem() call is invalid");
}
mList.loadAround(index);
return mList.get(index);
}
}
This code means that the values from the snapshot of the list are returned when notifyItemRangeInserted is called after calculating the diff (rather than the old list). The snapshot is used as that is what the diff was calculated against.
Can you tell me if there is a specific reason the default adapter calls notifyItemRangeInserted before updating the list, and if there are any big problems that may be encountered using the above workaround?