package org.osmdroid.debug; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import org.osmdroid.R; import org.osmdroid.debug.browser.CacheBrowserActivity; import org.osmdroid.debug.model.SqlTileWriterExt; import org.osmdroid.tileprovider.modules.SqlTileWriter; import org.osmdroid.tileprovider.util.Counters; import java.util.ArrayList; import java.util.List; /** * A debug utility to show various cache metrics and management * <p> * requires api11+ due to the use of sqlite * <p> * created on 12/21/2016. * * @author Alex O'Ree * @since 5.6.2 */ public class CacheAnalyzerActivity extends Activity implements AdapterView.OnItemClickListener, Runnable { SqlTileWriterExt cache = null; TextView cacheStats; AlertDialog show = null; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_cache_analyzer); cacheStats = (TextView) findViewById(R.id.cacheStats); final ArrayList<String> list = new ArrayList<>(); list.add("Browse the cache"); list.add("Purge the cache"); list.add("Purge a specific tile source"); list.add("See the debug counters"); ListView lv = (ListView) findViewById(R.id.statslist); ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, list); lv.setAdapter(adapter); lv.setOnItemClickListener(this); } public void onResume() { super.onResume(); cache = new SqlTileWriterExt(); new Thread(this).start(); } public void onPause() { super.onPause(); cache.onDetach(); cache = null; if (show != null) show.dismiss(); show = null; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { switch (position) { case 0: this.startActivity(new Intent(this, CacheBrowserActivity.class)); break; case 1: purgeCache(); break; case 2: purgeTileSource(); break; case 3: showDebugCounters(); break; } } private void showDebugCounters() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Tile Source"); StringBuilder sb = new StringBuilder(); sb.append(Counters.class.getCanonicalName() + "\nPerformance and debug counters\n\n"); sb.append("Out of memory errors: " + Counters.countOOM + "\n"); sb.append("File cache hit: " + Counters.fileCacheHit + "\n"); sb.append("File cache miss: " + Counters.fileCacheMiss + "\n"); sb.append("File cache oom: " + Counters.fileCacheOOM + "\n"); sb.append("File cache save errors: " + Counters.fileCacheSaveErrors + "\n"); sb.append("Tile download errors: " + Counters.tileDownloadErrors + "\n"); builder.setMessage(sb.toString()); show = builder.show(); } private void purgeTileSource() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Tile Source"); final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this, android.R.layout.select_dialog_singlechoice); List<SqlTileWriterExt.SourceCount> sources = cache.getSources(); for (int i = 0; i < sources.size(); i++) { arrayAdapter.add(sources.get(i).source); } builder.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String item = arrayAdapter.getItem(which); boolean b = cache.purgeCache(item); if (b) Toast.makeText(CacheAnalyzerActivity.this, "SQL Cache purged", Toast.LENGTH_SHORT).show(); else Toast.makeText(CacheAnalyzerActivity.this, "SQL Cache purge failed, see logcat for details", Toast.LENGTH_LONG).show(); } }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); builder.show(); } private void purgeCache() { SqlTileWriter sqlTileWriter = new SqlTileWriter(); boolean b = sqlTileWriter.purgeCache(); sqlTileWriter.onDetach(); sqlTileWriter = null; if (b) Toast.makeText(this, "SQL Cache purged", Toast.LENGTH_SHORT).show(); else Toast.makeText(this, "SQL Cache purge failed, see logcat for details", Toast.LENGTH_LONG).show(); } @Override public void run() { List<SqlTileWriterExt.SourceCount> sources = cache.getSources(); final StringBuilder sb = new StringBuilder("Source: tile count\n"); if (sources.isEmpty()) sb.append("None"); for (int i = 0; i < sources.size(); i++) { sb.append(sources.get(i).source + ": " + sources.get(i).rowCount + "\n"); } long expired = cache.getRowCountExpired(); sb.append("Expired tiles: " + expired); this.runOnUiThread(new Runnable() { @Override public void run() { try { TextView tv = (TextView) findViewById(R.id.cacheStats); if (tv != null) { tv.setText(sb.toString()); } } catch (Exception ex) { } } }); } }