Skip to content

Commit

Permalink
#335 resolving issues caught by @MKergall for polylines and polygons,…
Browse files Browse the repository at this point in the history
… after running much longer tests, it revealed that there was still another leak with the ExampleActivity which is now fixed

NOJIRA - removing the silly copy sources task in favor of a source redirector (gradle build only)
NOJIRA - adding Leak Canary and ACRA for leak testing and crash logging
  • Loading branch information
spyhunter99 committed Jul 5, 2016
1 parent d436504 commit 3cadcd3
Show file tree
Hide file tree
Showing 30 changed files with 336 additions and 191 deletions.
85 changes: 16 additions & 69 deletions OpenStreetMapViewer/build.gradle
Expand Up @@ -20,88 +20,35 @@ android {
lintOptions {
abortOnError false
}
sourceSets {
androidTest {
java.srcDirs = ['../osmdroid-android-it/src/main/java']
}
}
}

apply from: 'https://raw.githubusercontent.com/chrisdoyle/gradle-fury/master/gradle/android-support.gradle'

dependencies {
compile 'com.android.support:support-v4:23+'
compile project(':osmdroid-android')
androidTestCompile 'com.android.support:support-annotations:23+'
androidTestCompile 'com.android.support.test:runner:0.4.+'
androidTestCompile 'com.android.support.test:rules:0.4.+'
}


//copy the instrumentation tests from the maven osmdroid-android-it src folder
task copyTestClasses(type: Copy) {
description 'Copies the osmdroid-android-it maven test classes to androidTest folder.'
from ("${rootDir}/osmdroid-android-it/src/main/java")
into "./src/androidTest/java"
//crash logging
compile 'ch.acra:acra:4.7.0'

}

preBuild.dependsOn copyTestClasses
//memory leak testing
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'

/*
android.applicationVariants.all { variant ->
if (variant.getBuildType().name == "debug") {
variant.connectedInstrumentTest.doFirst {
//task "configDevice${variant.name.capitalize()}" (type: Exec){
// dependsOn variant.install
//group = 'setPermissions'
//description = 'Sets API23 style permissions.'
def adb = android.getAdbExe().toString()
def mypermission = 'android.permission.INTERNET'
exec {
commandLine "echo adb shell pm grant ${variant.applicationId} $mypermission".split(' ')
commandLine "$adb shell pm grant ${variant.applicationId} $mypermission".split(' ')
}
mypermission = 'android.permission.ACCESS_FINE_LOCATION'
exec {
commandLine "echo adb shell pm grant ${variant.applicationId} $mypermission".split(' ')
commandLine "$adb shell pm grant ${variant.applicationId} $mypermission".split(' ')
}
mypermission = 'android.permission.WRITE_EXTERNAL_STORAGE'
exec {
commandLine "echo adb shell pm grant ${variant.applicationId} $mypermission".split(' ')
commandLine "$adb shell pm grant ${variant.applicationId} $mypermission".split(' ')
}
}
//variant.testVariant.connectedInstrumentTest.dependsOn "configDevice${variant.name.capitalize()}"
}
}*/
/*
def adb = android.getAdbExe().toString()
task nameofyourtask(type: Exec, dependsOn: 'installDebug') { // or install{productFlavour}{buildType}
group = 'nameofyourtaskgroup'
description = 'Describe your task here.'
def mypermission = 'android.permission.ACCESS_FINE_LOCATION'
commandLine "$adb shell pm grant ${variant.applicationId} $mypermission".split(' ')
}
task nameofyourtask2(type: Exec, dependsOn: 'installDebug') { // or install{productFlavour}{buildType}
group = 'nameofyourtaskgroup'
description = 'Describe your task here.'
def mypermission = 'android.permission.WRITE_EXTERNAL_STORAGE'
commandLine "$adb shell pm grant ${variant.applicationId} $mypermission".split(' ')
//on device testing
androidTestCompile 'com.android.support:support-annotations:23+'
androidTestCompile 'com.android.support.test:runner:0.4.+'
androidTestCompile 'com.android.support.test:rules:0.4.+'
}

tasks.whenTaskAdded { task ->
if (task.name.startsWith('connectedDebugAndroidTest')) { // or connected{productFlavour}{buildType}AndroidTest
task.dependsOn nameofyourtask
task.dependsOn nameofyourtask2
}
}*/

//the following sets the required permissions for API 23+ devices and AVDs

android.applicationVariants.all { variant ->
if (variant.getBuildType().name == "debug") {
Expand Down
4 changes: 4 additions & 0 deletions OpenStreetMapViewer/pom.xml
Expand Up @@ -30,6 +30,10 @@
<groupId>android.support</groupId>
<artifactId>compatibility-v4</artifactId>
</dependency>
<dependency>
<groupId>ch.acra</groupId>
<artifactId>acra</artifactId>
</dependency>

<!-- test dependencies -->
<dependency>
Expand Down
3 changes: 2 additions & 1 deletion OpenStreetMapViewer/src/main/AndroidManifest.xml
Expand Up @@ -37,8 +37,9 @@
android:required="false" />

<application
android:name=".OsmApplication"
android:hardwareAccelerated="true"
android:largeHeap="true"
android:largeHeap="false"
android:icon="@drawable/icon"
android:label="@string/app_name">

Expand Down
122 changes: 122 additions & 0 deletions OpenStreetMapViewer/src/main/java/org/osmdroid/OsmApplication.java
@@ -0,0 +1,122 @@
package org.osmdroid;

import android.app.Application;
import android.content.Context;
import android.os.Environment;
import android.util.Log;

import com.squareup.leakcanary.LeakCanary;

import org.acra.ACRA;
import org.acra.annotation.ReportsCrashes;
import org.acra.collector.CrashReportData;
import org.acra.sender.ReportSender;
import org.acra.sender.ReportSenderException;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
* This is the base application for the sample app. We only use to catch errors during development cycles
* Created by alex on 7/4/16.
*/
@ReportsCrashes( formUri = "")
public class OsmApplication extends Application{

@Override
public void onCreate(){
super.onCreate();
LeakCanary.install(this);
Thread.currentThread().setUncaughtExceptionHandler(new OsmUncaughtExceptionHandler());
}

@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);



// Initialise ACRA
ACRA.init(this);
ACRA.getErrorReporter().setReportSender(new ErrorFileWriter());



}

public static class OsmUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e("UncaughtException", "Got an uncaught exception: "+ex.toString());
if(ex.getClass().equals(OutOfMemoryError.class))
{
writeHprof();
}
ex.printStackTrace();
}
}

/**
* writes the current heap to the file system at /sdcard/osmdroid/trace-{timestamp}.hprof
*/
public static void writeHprof(){
try {
android.os.Debug.dumpHprofData(Environment.getExternalStorageDirectory().getAbsolutePath() + "/osmdroid/trace-" + System.currentTimeMillis()+ ".hprof");
} catch (IOException e) {
e.printStackTrace();
}
}


/**
* Writes hard crash stack traces to a file on the SD card.
*/
private static class ErrorFileWriter implements ReportSender {

@Override
public void send(Context context, CrashReportData crashReportData) throws ReportSenderException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss",
Locale.US);
String timeStamp = sdf.format(new Date());
String rootDirectory = Environment.getExternalStorageDirectory()
.getAbsolutePath();
File f = new File(rootDirectory
+ File.separatorChar
+ "TCE"
+ File.separatorChar
+ "logs"
+ File.separatorChar
+ "crash"
+ File.separatorChar);
f.mkdirs();
f = new File(rootDirectory
+ File.separatorChar
+ "TCE"
+ File.separatorChar
+ "logs"
+ File.separatorChar
+ "crash"
+ File.separatorChar
+ "CRASH_"
+ BuildConfig.APPLICATION_ID+ "_"
+ timeStamp + ".log");
f.delete();

try {
f.createNewFile();
PrintWriter pw = new PrintWriter(new FileWriter(f));
pw.println(crashReportData.toString());
pw.close();
} catch (Exception exc) {
exc.printStackTrace();
}


}
}
}
Expand Up @@ -160,13 +160,19 @@ public void onPause() {

this.mLocationOverlay.disableMyLocation();

//this part terminates all of the overlays and background threads for osmdroid
//only needed when you programmatically create the map
mMapView.onDetach();

super.onPause();
}

@Override
public void onDestroyView(){
super.onDestroyView();
//this part terminates all of the overlays and background threads for osmdroid
//only needed when you programmatically create the map
mMapView.onDetach();

}

@Override
public void onResume() {
super.onResume();
Expand Down
Expand Up @@ -27,14 +27,28 @@ public static FragmentSamples newInstance() {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

//the following block of code took me an entire weekend to track down the root cause.
//if the code block is in onCreate, it will leak. onActivityCreated = no leak.
//makes no sense, but that's Android for you.

// Generate a ListView with Sample Maps
final ArrayList<String> list = new ArrayList<>();
// Put samples next
for (int a = 0; a < sampleFactory.count(); a++) {
final BaseSampleFragment f = sampleFactory.getSample(a);
list.add(f.getSampleTitle());
}
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(),
//changed from getActivity to Application context per http://www.slideshare.net/AliMuzaffar2/android-preventing-common-memory-leaks
//prior to that, we had a memory leak that would only show on long running tests. the issue is that the array adapter
//wasn't being gc'd.
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter);
}
Expand All @@ -58,4 +72,9 @@ public void onResume(){
fm.popBackStack();
System.gc();
}

@Override
public void onDestroyView(){
super.onDestroyView();
}
}
Expand Up @@ -26,7 +26,7 @@ public String getSampleTitle() {
@Override
public void addOverlays() {
super.addOverlays();
//this part will recalculate and render the lat/lon gridlines
mMapView.getController().setZoom(10);

}

Expand Down Expand Up @@ -70,7 +70,7 @@ public void run() {
double lat = rand.nextDouble() * 180 - 90;
double lon = rand.nextDouble() * 360 - 180;
mMapView.getController().animateTo(new GeoPoint(lat, lon));
Toast.makeText(getActivity(), "Animate to " + SampleMapEventListener.df.format(lat) + "," + SampleMapEventListener.df.format(lon), Toast.LENGTH_LONG).show();
Toast.makeText(getActivity(), "Animate to " + SampleMapEventListener.df.format(lat) + "," + SampleMapEventListener.df.format(lon), Toast.LENGTH_SHORT).show();
}
}
});
Expand Down
@@ -1,7 +1,6 @@
package org.osmdroid.samplefragments;

import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase;
import org.osmdroid.samplefragments.models.USGSTileSource;

/**
* Simple how to for setting a custom tile source
Expand Down
Expand Up @@ -2,6 +2,7 @@

import android.util.Log;

import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.overlay.FolderOverlay;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
Expand All @@ -25,6 +26,8 @@ public String getSampleTitle() {

@Override
protected void addOverlays() {
mMapView.getController().setCenter(new GeoPoint(0d,0d));
mMapView.getController().setZoom(5);
mMapView.setTilesScaledToDpi(true);
mMapView.setMapListener(this);
mMapView.getController().setZoom(3);
Expand Down

0 comments on commit 3cadcd3

Please sign in to comment.