updating station summary for favourites separated from updating text view within activity

fix/get-all-stations-hangout
Mateusz Lubecki 2022-01-06 12:36:18 +01:00
rodzic 660390391a
commit 0b18117b9c
6 zmienionych plików z 211 dodań i 46 usunięć

Wyświetl plik

@ -20,11 +20,14 @@ import org.tinylog.Logger;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import cc.pogoda.mobile.meteosystem.activity.handler.MainActImageButtonFavouritesClickEvent;
import cc.pogoda.mobile.meteosystem.activity.updater.FavouritesStationDetailsUpdater;
import cc.pogoda.mobile.meteosystem.activity.updater.FavouritesStationSummaryUpdater;
import cc.pogoda.mobile.meteosystem.activity.view.AllStationsActRecyclerViewHolder;
import cc.pogoda.mobile.meteosystem.config.AppConfiguration;
import cc.pogoda.mobile.meteosystem.dao.AllStationsDao;
import cc.pogoda.mobile.meteosystem.file.ConfigurationFile;
@ -34,6 +37,7 @@ import cc.pogoda.mobile.meteosystem.type.ParceableFavsCallReason;
import cc.pogoda.mobile.meteosystem.type.ParceableStationsList;
import cc.pogoda.mobile.meteosystem.type.WeatherStation;
import cc.pogoda.mobile.meteosystem.type.WeatherStationListEvent;
import cc.pogoda.mobile.meteosystem.type.web.Summary;
public class Main extends Application {
@ -61,9 +65,16 @@ public class Main extends Application {
private List<WeatherStation> favs;
private Handler handler = null;
/**
* This download summary for all stations stored on favourites list and stores results
* in 'HashMap<String, Summary> stationSystemNameToSummary'
*/
private FavouritesStationSummaryUpdater favsSummaryUpdater = null;
private FavouritesStationDetailsUpdater favsUpdater = null;
/**
* This map stores summary for all favourites station
*/
private HashMap<String, Summary> stationSystemNameToSummary = null;
public File getDirectory() {
return directory;
@ -77,6 +88,10 @@ public class Main extends Application {
return confFile;
}
public HashMap<String, Summary> getStationSystemNameToSummary() {
return stationSystemNameToSummary;
}
@Override
public void onCreate() {
super.onCreate();
@ -85,13 +100,7 @@ public class Main extends Application {
confFile = new ConfigurationFile(ctx);
StrictMode.VmPolicy.Builder b = new StrictMode.VmPolicy.Builder();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
StrictMode.VmPolicy policy = b.detectAll().detectNonSdkApiUsage().penaltyListener((Runnable r) -> r.run(), (Violation v) -> {v.printStackTrace();}).build();
StrictMode.setVmPolicy(policy);
}
directory = getApplicationContext().getDir("meteosystem", Context.MODE_PRIVATE);
directory = getApplicationContext().getDir("files", Context.MODE_PRIVATE);
directoryForLogs = new File(directory.getAbsolutePath() + "/logs/");
@ -99,6 +108,15 @@ public class Main extends Application {
Logger.info("Application starting...");
// StrictMode.VmPolicy.Builder b = new StrictMode.VmPolicy.Builder();
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// StrictMode.VmPolicy policy = b.detectAll().detectNonSdkApiUsage().penaltyListener((Runnable r) -> r.run(), (Violation v) -> {
// v.printStackTrace();
// Logger.warn("[StrictMode.VmPolicy][penaltyListener][Violation][v.getLocalizedMessage() = " + v.getLocalizedMessage() + "]");
// }).build();
// StrictMode.setVmPolicy(policy);
// }
AndroidThreeTen.init(this);
EventBus.getDefault().register(this);
@ -107,9 +125,7 @@ public class Main extends Application {
confFile.restoreFromFile();
handler = new Handler(Looper.getMainLooper());
favsUpdater = new FavouritesStationDetailsUpdater(handler);
stationSystemNameToSummary = new HashMap<>();
fileNames = new FileNames(ctx);
@ -123,6 +139,10 @@ public class Main extends Application {
// recreate list of favorites
recreateListOfFavs();
favsSummaryUpdater = new FavouritesStationSummaryUpdater(stationSystemNameToSummary);
favsSummaryUpdater.start(100);
if (AppConfiguration.locale != null && !AppConfiguration.locale.equals("default") ) {
Logger.debug("[Main][onCreate][AppConfiguration.locale = " + AppConfiguration.locale + "]");
Locale locale = new Locale(AppConfiguration.locale);
@ -180,6 +200,7 @@ public class Main extends Application {
// as a list does not make a copy of the object. It (ArrayList) keeps
// only a reference to an object
stationSystemNameToSummary.put(fromAllStations.getSystemName(), null);
}
}
@ -223,7 +244,9 @@ public class Main extends Application {
// recreate parceable object and pass it everywhere
recreateListOfFavs();
//Toast.makeText(this, intentServiceResult.getResultValue(), Toast.LENGTH_SHORT).show();
favsSummaryUpdater.updateImmediately();
}
public boolean listOfAllStationsReady() {
@ -236,7 +259,7 @@ public class Main extends Application {
}
public boolean listOfFavsReady() {
if (favs != null && favs.size() > 0) {
if (favs != null/* && favs.size() > 0*/) {
return true;
}
else {
@ -244,25 +267,17 @@ public class Main extends Application {
}
}
public void createAndStartUpdater() {
public boolean checkIsOnFavsList(String _system_name) {
boolean out = false;
// check if there is previous instance of updater
if (favsUpdater != null && favsUpdater.isEnabled()) {
stopUpdater();
for (WeatherStation wx : favs) {
if (wx.getSystemName().equals(_system_name)) {
out = true;
break;
}
handler = new Handler(Looper.getMainLooper());
favsUpdater = new FavouritesStationDetailsUpdater(handler);
handler.postDelayed(favsUpdater, 300);
favsUpdater.setEnabled(true);
}
public void stopUpdater() {
if (reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)) {
handler.removeCallbacks(favsUpdater);
favsUpdater.setEnabled(false);
}
return out;
}
}

Wyświetl plik

@ -5,6 +5,8 @@ import android.graphics.Color;
import android.os.Handler;
import android.widget.TextView;
import org.tinylog.Logger;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@ -17,7 +19,8 @@ import cc.pogoda.mobile.meteosystem.type.web.QualityFactor;
import cc.pogoda.mobile.meteosystem.type.web.Summary;
/**
* This class is used to update entries on Favourites list
* This class is used to update entries (TextView) on Favourites list using HashMap
* which is updated by {@link FavouritesStationSummaryUpdater}
*/
public class FavouritesStationDetailsUpdater implements Runnable {
@ -32,27 +35,27 @@ public class FavouritesStationDetailsUpdater implements Runnable {
*/
private HashMap<String, TextView> stationsToUpdate;
/**
* Used to get data from web service
*/
private SummaryDao dao = null;
/**
*
*/
private AvailableParametersDao availableParametersDao = null;
/**
* This map comes from 'Main' class and it is shared with @link{{@link FavouritesStationSummaryUpdater}}
*/
HashMap<String, Summary> stationNameSummary = null;
/**
* Not sure if this is really required but just to be sure that updater won't be started
* after the activity had been torn down.
*/
private boolean enabled;
public FavouritesStationDetailsUpdater(Handler _handler) {
public FavouritesStationDetailsUpdater(Handler _handler, HashMap<String, Summary> _station_system_name_to_summary) {
handler = _handler;
dao = new SummaryDao();
stationsToUpdate = new HashMap<>();
availableParametersDao = new AvailableParametersDao();
stationNameSummary = _station_system_name_to_summary;
}
public boolean isEnabled() {
@ -71,7 +74,7 @@ public class FavouritesStationDetailsUpdater implements Runnable {
@Override
public void run() {
if (enabled && stationsToUpdate != null && stationsToUpdate.size() > 0) {
if (stationNameSummary != null && enabled && stationsToUpdate != null && stationsToUpdate.size() > 0) {
// get a set of all elements stored in the map
Set<Map.Entry<String, TextView>> entries = stationsToUpdate.entrySet();
@ -87,7 +90,9 @@ public class FavouritesStationDetailsUpdater implements Runnable {
TextView toUpdate = e.getValue();
// query web service for station data
Summary summary = dao.getStationSummary(stationSystemName);
Summary summary = stationNameSummary.get(stationSystemName);
Logger.debug("[FavouritesStationDetailsUpdater][run][stationSystemName = " + stationSystemName +"][summary.last_timestamp = " + summary.last_timestamp +"]");
// query for available parameters
AvailableParametersWeb params = availableParametersDao.getAvaliableParamsByStationName(stationSystemName);
@ -132,7 +137,7 @@ public class FavouritesStationDetailsUpdater implements Runnable {
}
}
handler.postDelayed(this, 30000);
handler.postDelayed(this, 60000);
}
}
}

Wyświetl plik

@ -1,2 +0,0 @@
package cc.pogoda.mobile.meteosystem.activity.updater;public class FavouritesStationDetailsValuesUpdater {
}

Wyświetl plik

@ -0,0 +1,111 @@
package cc.pogoda.mobile.meteosystem.activity.updater;
import android.os.Handler;
import android.telephony.SubscriptionManager;
import org.tinylog.Logger;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import cc.pogoda.mobile.meteosystem.dao.SummaryDao;
import cc.pogoda.mobile.meteosystem.type.web.Summary;
/**
* This class is a runnable executed from background Thread by ScheduledExecuter
* which periodically download current Summary for all stations stored on favourites list
*/
public class FavouritesStationSummaryUpdater implements Runnable {
private HashMap<String, Summary> map;
private SummaryDao summaryDao;
private ScheduledExecutorService executor;
private ScheduledFuture scheduledTask;
private boolean enabled = false;
/**
* Set to true when a update is forced in case of a removal or adding new entry to the map
*/
private boolean forceUpdate = false;
public FavouritesStationSummaryUpdater(HashMap<String, Summary> _out_map) {
map = _out_map;
summaryDao = new SummaryDao();
executor = Executors.newScheduledThreadPool(5);
}
@Override
public void run() {
// check if map was set so something
if (map != null && map.size() > 0) {
// get a set of all stations from favourites
Set<Map.Entry<String, Summary>> _set_of_stations_names = map.entrySet();
// get an iterator to the set
Iterator<Map.Entry<String, Summary>> it = _set_of_stations_names.iterator();
while (it.hasNext()) {
// get currently processed entry
Map.Entry<String, Summary> entry = it.next();
// get station name
String station_name = entry.getKey();
Summary summary = summaryDao.getStationSummary(station_name);
Logger.debug("[FavouritesStationSummaryUpdater][run][station_name = " + station_name +"][summary.last_timestamp = " + summary.last_timestamp +"]");
// put the summary back into the map
map.put(station_name, summary);
}
}
if (forceUpdate) {
forceUpdate = false;
start(66000);
}
}
public void updateImmediately() {
forceUpdate = true;
stop();
Thread t = new Thread(this);
t.start();
}
public void start(int _initial_delay) {
Logger.debug("[FavouritesStationSummaryUpdater][start][_initial_delay = " + _initial_delay +"]");
if (enabled) {
stop();
}
scheduledTask = executor.scheduleAtFixedRate(this, _initial_delay, 123000, TimeUnit.MILLISECONDS);
enabled = true;
}
public void stop() {
if (enabled) {
scheduledTask.cancel(true);
enabled = false;
}
}
}

Wyświetl plik

@ -2,6 +2,7 @@ package cc.pogoda.mobile.meteosystem.adapter;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -14,6 +15,7 @@ import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import cc.pogoda.mobile.meteosystem.Main;
import cc.pogoda.mobile.meteosystem.R;
import cc.pogoda.mobile.meteosystem.activity.handler.AllStationsActRecyclerViewButtonClickEvent;
import cc.pogoda.mobile.meteosystem.activity.updater.FavouritesStationDetailsUpdater;
@ -35,8 +37,18 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<AllS
AvailableParametersDao paramsDao;
FavouritesStationDetailsUpdater favsUpdater = null;
/**
* This updater takes data stored in the hashmap and then updates TextViews on View Holders on
* Favourites list
*/
private FavouritesStationDetailsUpdater favsUpdater = null;
Handler handler = null;
/**
* This instance of 'Main' singleton class is used to obtain HashMap<String, Summary> stationSystemNameToSummary
*/
Main main;
public WeatherStationRecyclerViewAdapter(List<WeatherStation> stations, AppCompatActivity parentActivity, ParceableFavsCallReason.Reason callReason) {
this.stations = stations;
@ -44,8 +56,7 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<AllS
this.reason = callReason;
this.summaryDao = new SummaryDao();
this.paramsDao = new AvailableParametersDao();
this.main = (Main) parentActivity.getApplication();
}
@NonNull
@ -105,4 +116,26 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<AllS
return stations.size();
}
public void createAndStartUpdater() {
// check if there is previous instance of updater
if (favsUpdater != null && favsUpdater.isEnabled()) {
stopUpdater();
}
handler = new Handler(Looper.getMainLooper());
favsUpdater = new FavouritesStationDetailsUpdater(handler, main.getStationSystemNameToSummary());
handler.postDelayed(favsUpdater, 100);
favsUpdater.setEnabled(true);
}
public void stopUpdater() {
if (reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)) {
handler.removeCallbacks(favsUpdater);
favsUpdater.setEnabled(false);
}
}
}

Wyświetl plik

@ -4,6 +4,7 @@ import android.content.Context;
import org.json.JSONException;
import org.json.JSONObject;
import org.tinylog.Logger;
import java.io.File;
import java.io.FileInputStream;
@ -49,6 +50,8 @@ public class ConfigurationFile {
} catch (IOException | JSONException e) {
e.printStackTrace();
Logger.error("[ConfigurationFile][restoreFromFile][e = " + e.getLocalizedMessage() +"]");
AppConfiguration.locale = "default";
AppConfiguration.replaceMsWithKnots = false;
AppConfiguration.decimationPeriod = 0;