Downloads concurrency crash fix
This commit is contained in:
parent
c472c05249
commit
72cccbde57
8 changed files with 118 additions and 99 deletions
|
@ -27,6 +27,7 @@ import java.text.MessageFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -119,23 +120,40 @@ public class BaseDownloadActivity extends ActionBarProgressActivity {
|
|||
}
|
||||
|
||||
public ItemsListBuilder getItemsBuilder() {
|
||||
return getItemsBuilder("");
|
||||
return getItemsBuilder("", false);
|
||||
}
|
||||
|
||||
public ItemsListBuilder getItemsBuilder(String regionId) {
|
||||
if (downloadListIndexThread.isDataPrepared()) {
|
||||
return new ItemsListBuilder(getMyApplication(), regionId, downloadListIndexThread.getResourcesByRegions(),
|
||||
public ItemsListBuilder getVoicePromptsBuilder() {
|
||||
return getItemsBuilder("", true);
|
||||
}
|
||||
|
||||
public ItemsListBuilder getItemsBuilder(String regionId, boolean voicePromptsOnly) {
|
||||
if (downloadListIndexThread.getResourcesLock().tryLock()) {
|
||||
try {
|
||||
ItemsListBuilder builder = new ItemsListBuilder(getMyApplication(), regionId, downloadListIndexThread.getResourcesByRegions(),
|
||||
downloadListIndexThread.getVoiceRecItems(), downloadListIndexThread.getVoiceTTSItems());
|
||||
if (!voicePromptsOnly) {
|
||||
return builder.build();
|
||||
} else {
|
||||
return builder;
|
||||
}
|
||||
} finally {
|
||||
downloadListIndexThread.getResourcesLock().unlock();
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, IndexItem> getIndexItemsByRegion(WorldRegion region) {
|
||||
if (downloadListIndexThread.isDataPrepared()) {
|
||||
return downloadListIndexThread.getResourcesByRegions().get(region);
|
||||
public List<IndexItem> getIndexItemsByRegion(WorldRegion region) {
|
||||
if (downloadListIndexThread.getResourcesLock().tryLock()) {
|
||||
try {
|
||||
return new LinkedList<>(downloadListIndexThread.getResourcesByRegions().get(region).values());
|
||||
} finally {
|
||||
downloadListIndexThread.getResourcesLock().unlock();
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
return new LinkedList<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ import java.util.Map.Entry;
|
|||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class DownloadIndexesThread {
|
||||
|
@ -73,7 +74,7 @@ public class DownloadIndexesThread {
|
|||
private List<IndexItem> voiceRecItems = new LinkedList<>();
|
||||
private List<IndexItem> voiceTTSItems = new LinkedList<>();
|
||||
|
||||
private boolean dataPrepared;
|
||||
private final ReentrantLock resourcesLock = new ReentrantLock();
|
||||
|
||||
DatabaseHelper dbHelper;
|
||||
|
||||
|
@ -85,6 +86,10 @@ public class DownloadIndexesThread {
|
|||
dbHelper = new DatabaseHelper(app);
|
||||
}
|
||||
|
||||
public ReentrantLock getResourcesLock() {
|
||||
return resourcesLock;
|
||||
}
|
||||
|
||||
public DatabaseHelper getDbHelper() {
|
||||
return dbHelper;
|
||||
}
|
||||
|
@ -152,10 +157,6 @@ public class DownloadIndexesThread {
|
|||
return itemsToUpdate;
|
||||
}
|
||||
|
||||
public boolean isDataPrepared() {
|
||||
return dataPrepared;
|
||||
}
|
||||
|
||||
public Map<WorldRegion, Map<String, IndexItem>> getResourcesByRegions() {
|
||||
return resourcesByRegions;
|
||||
}
|
||||
|
@ -169,6 +170,9 @@ public class DownloadIndexesThread {
|
|||
}
|
||||
|
||||
private boolean prepareData(List<IndexItem> resources) {
|
||||
resourcesLock.lock();
|
||||
try {
|
||||
|
||||
List<IndexItem> resourcesInRepository;
|
||||
if (resources != null) {
|
||||
resourcesInRepository = resources;
|
||||
|
@ -208,6 +212,10 @@ public class DownloadIndexesThread {
|
|||
});
|
||||
|
||||
return true;
|
||||
|
||||
} finally {
|
||||
resourcesLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void processRegion(List<IndexItem> resourcesInRepository, boolean processVoiceFiles, WorldRegion region) {
|
||||
|
@ -531,7 +539,6 @@ public class DownloadIndexesThread {
|
|||
currentRunningTask.add(this);
|
||||
super.onPreExecute();
|
||||
this.message = ctx.getString(R.string.downloading_list_indexes);
|
||||
dataPrepared = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -548,7 +555,6 @@ public class DownloadIndexesThread {
|
|||
protected void onPostExecute(IndexFileList result) {
|
||||
indexFiles = result;
|
||||
if (indexFiles != null && uiActivity != null) {
|
||||
dataPrepared = resourcesByRegions.size() > 0;
|
||||
boolean basemapExists = uiActivity.getMyApplication().getResourceManager().containsBasemap();
|
||||
IndexItem basemap = indexFiles.getBasemap();
|
||||
if (basemap != null) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package net.osmand.plus.download.items;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.map.OsmandRegions;
|
||||
|
@ -15,7 +13,6 @@ import net.osmand.plus.download.IndexItem;
|
|||
import net.osmand.plus.srtmplugin.SRTMPlugin;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
|
@ -24,7 +21,7 @@ import java.util.Map;
|
|||
|
||||
public class ItemsListBuilder {
|
||||
|
||||
public static final String WORLD_BASEMAP_KEY = "world_basemap.obf.zip";
|
||||
//public static final String WORLD_BASEMAP_KEY = "world_basemap.obf.zip";
|
||||
public static final String WORLD_SEAMARKS_KEY = "world_seamarks_basemap.obf.zip";
|
||||
|
||||
private Map<WorldRegion, Map<String, IndexItem>> resourcesByRegions;
|
||||
|
@ -96,7 +93,7 @@ public class ItemsListBuilder {
|
|||
public enum VoicePromptsType {
|
||||
NONE,
|
||||
RECORDED,
|
||||
TTS;
|
||||
TTS
|
||||
}
|
||||
|
||||
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(ItemsListBuilder.class);
|
||||
|
@ -130,12 +127,12 @@ public class ItemsListBuilder {
|
|||
return list;
|
||||
}
|
||||
|
||||
public String getVoicePromtName(VoicePromptsType type) {
|
||||
public static String getVoicePromtName(Context ctx, VoicePromptsType type) {
|
||||
switch (type) {
|
||||
case RECORDED:
|
||||
return app.getResources().getString(R.string.index_name_voice);
|
||||
return ctx.getResources().getString(R.string.index_name_voice);
|
||||
case TTS:
|
||||
return app.getResources().getString(R.string.index_name_tts_voice);
|
||||
return ctx.getResources().getString(R.string.index_name_tts_voice);
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
@ -167,8 +164,8 @@ public class ItemsListBuilder {
|
|||
List<IndexItem> voiceRecItems, List<IndexItem> voiceTTSItems) {
|
||||
this.app = app;
|
||||
this.resourcesByRegions = resourcesByRegions;
|
||||
this.voiceRecItems = voiceRecItems;
|
||||
this.voiceTTSItems = voiceTTSItems;
|
||||
this.voiceRecItems = new LinkedList<>(voiceRecItems);
|
||||
this.voiceTTSItems = new LinkedList<>(voiceTTSItems);
|
||||
|
||||
regionMapItems = new LinkedList<>();
|
||||
allResourceItems = new LinkedList<>();
|
||||
|
@ -177,8 +174,12 @@ public class ItemsListBuilder {
|
|||
region = app.getWorldRegion().getRegionById(regionId);
|
||||
}
|
||||
|
||||
public boolean build() {
|
||||
return obtainDataAndItems();
|
||||
public ItemsListBuilder build() {
|
||||
if (obtainDataAndItems()) {
|
||||
return this;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean obtainDataAndItems() {
|
||||
|
@ -223,7 +224,7 @@ public class ItemsListBuilder {
|
|||
}
|
||||
|
||||
List<ResourceItem> regionMapArray = new LinkedList<>();
|
||||
List<Object> allResourcesArray = new LinkedList<Object>();
|
||||
List<Object> allResourcesArray = new LinkedList<>();
|
||||
|
||||
Context context = app.getApplicationContext();
|
||||
OsmandRegions osmandRegions = app.getRegions();
|
||||
|
|
|
@ -73,8 +73,8 @@ public class RegionItemsFragment extends OsmandExpandableListFragment {
|
|||
setListView(listView);
|
||||
|
||||
if (regionId.length() > 0) {
|
||||
ItemsListBuilder builder = getDownloadActivity().getItemsBuilder(regionId);
|
||||
if (builder != null && builder.build()) {
|
||||
ItemsListBuilder builder = getDownloadActivity().getItemsBuilder(regionId, false);
|
||||
if (builder != null) {
|
||||
fillRegionItemsAdapter(builder);
|
||||
listAdapter.notifyDataSetChanged();
|
||||
expandAllGroups();
|
||||
|
|
|
@ -287,16 +287,11 @@ public class SearchItemsFragment extends Fragment {
|
|||
}
|
||||
|
||||
for (WorldRegion region : regions) {
|
||||
Map<String, IndexItem> indexItems = getDownloadActivity().getIndexItemsByRegion(region);
|
||||
List<IndexItem> items = new LinkedList<>();
|
||||
|
||||
if (region.getSubregions().size() > 0) {
|
||||
filter.add(region);
|
||||
}
|
||||
for (IndexItem item : indexItems.values()) {
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
List<IndexItem> items = getDownloadActivity().getIndexItemsByRegion(region);
|
||||
if (items.size() > 1) {
|
||||
if (!filter.contains(region)) {
|
||||
filter.add(region);
|
||||
|
|
|
@ -71,8 +71,7 @@ public class VoiceDialogFragment extends DialogFragment {
|
|||
VoiceItemsFragment.createInstance(voicePromptsType)).commit();
|
||||
}
|
||||
|
||||
ItemsListBuilder builder = getDownloadActivity().getItemsBuilder();
|
||||
toolbar.setTitle(builder.getVoicePromtName(voicePromptsType));
|
||||
toolbar.setTitle(ItemsListBuilder.getVoicePromtName(getActivity(), voicePromptsType));
|
||||
}
|
||||
((DownloadActivity)getActivity()).registerFreeVersionBanner(view);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ public class VoiceItemsFragment extends OsmandExpandableListFragment {
|
|||
setListView(listView);
|
||||
|
||||
if (voicePromptsType != VoicePromptsType.NONE) {
|
||||
ItemsListBuilder builder = getDownloadActivity().getItemsBuilder();
|
||||
ItemsListBuilder builder = getDownloadActivity().getVoicePromptsBuilder();
|
||||
if (builder != null) {
|
||||
fillVoiceItemsAdapter(builder);
|
||||
listAdapter.notifyDataSetChanged();
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
package net.osmand.plus.download.items;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
|
@ -23,21 +33,11 @@ import net.osmand.plus.srtmplugin.SRTMPlugin;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.TextView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WorldItemsFragment extends OsmandExpandableListFragment {
|
||||
public static final String TAG = "WorldItemsFragment";
|
||||
|
@ -112,11 +112,11 @@ public class WorldItemsFragment extends OsmandExpandableListFragment {
|
|||
int unusedSubIndex = 0;
|
||||
List<String> voicePromptsItems = new LinkedList<>();
|
||||
if (!builder.isVoicePromptsItemsEmpty(VoicePromptsType.RECORDED)) {
|
||||
voicePromptsItems.add(builder.getVoicePromtName(VoicePromptsType.RECORDED));
|
||||
voicePromptsItems.add(ItemsListBuilder.getVoicePromtName(getActivity(), VoicePromptsType.RECORDED));
|
||||
voicePromptsItemsRecordedSubIndex = unusedSubIndex++;
|
||||
}
|
||||
if (!builder.isVoicePromptsItemsEmpty(VoicePromptsType.TTS)) {
|
||||
voicePromptsItems.add(builder.getVoicePromtName(VoicePromptsType.TTS));
|
||||
voicePromptsItems.add(ItemsListBuilder.getVoicePromtName(getActivity(), VoicePromptsType.TTS));
|
||||
voicePromptsItemsTTSSubIndex = unusedSubIndex;
|
||||
}
|
||||
if (!voicePromptsItems.isEmpty()) {
|
||||
|
@ -188,7 +188,7 @@ public class WorldItemsFragment extends OsmandExpandableListFragment {
|
|||
|
||||
public void onCategorizationFinished() {
|
||||
ItemsListBuilder builder = getDownloadActivity().getItemsBuilder();
|
||||
if (builder != null && builder.build()) {
|
||||
if (builder != null) {
|
||||
fillWorldItemsAdapter(builder);
|
||||
listAdapter.notifyDataSetChanged();
|
||||
expandAllGroups();
|
||||
|
|
Loading…
Reference in a new issue