Implement uncaught exception handling mechanism

git-svn-id: https://osmand.googlecode.com/svn/trunk@91 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-05-28 08:33:45 +00:00
parent 8555ac76ee
commit dc7521cde5
2 changed files with 102 additions and 20 deletions

View file

@ -11,7 +11,7 @@ public class ToDoConstants {
* Write activity to show something about authors / donation ....
*/
public int DESCRIBE_ABOUT_AUTHORS = 8;
// TODO ANDROID
// 25. POI search near to map location (show categories & type). Second cut. (implement incremental search)
@ -21,13 +21,12 @@ public class ToDoConstants {
// 24. Implement ResourceManager, load cities/streets/buildings on Low memory (clear previous all addresses cities).
// 5. Search for city/streets/buildings
// 9. Configure file log & see log from file (when exception happened to see from device)
// 15. Investigate interruption of any long running operation & implement where it is needed
// 17. Enable go to location by specifying coordinates
// 11. Print out additional info speed, altitude, number of satellites
// 19. Show how map is rotated where north/south on map (do not consider compass)
// 23. Implement moving point from center to bottom (for rotating map). (+)
// 23. Implement moving point from center to bottom (for rotating map)
// 21. Implement zooming tile (if tile doesn't exist local, we can zoom in previous tile).
@ -43,20 +42,23 @@ public class ToDoConstants {
// 3. Fix progress information (loading indices) for android version
// 4. Fix when POI selected & enable button backToLocation
// 5. Call ResourceManager.close when it is needed
// 6. Understand concept of application where to save/restore global setting
// (for example reset navigate to point, reset link map with location). It should be reset after user call exit.
// 6. Understand concept of application where to save/restore global setting.
// (for example reset navigate to point, reset link map with location). It should be reset after user call exit.
// 7. Implement search amenities by type (!).
// Rewrite search activity in order to limit amenities not to all types.
// TODO SWING:
// 1. Download tiles without using dir tiles
// 2. Configure file log & see log from file
// 2. Configure file log & see log from file (add uncaught exception handling)
// 5. Implement supress warning for duplicate id
// 6. Implement renaming/deleting street/building/city
// 7. Implement saving bundle of tiles in different folder
// DONE ANDROID :
// 18. Implement go to point
// 2. Showing compass on the map : use device compass if exists(?)
// 9. Configure file log & see log from file (when exception happened to see from device)
// DONE SWING

View file

@ -1,30 +1,88 @@
package com.osmand.activities;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintStream;
import java.lang.Thread.UncaughtExceptionHandler;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.osmand.LogUtil;
import com.osmand.ProgressDialogImplementation;
import com.osmand.R;
import com.osmand.ResourceManager;
public class MainMenuActivity extends Activity {
private static boolean applicationAlreadyStarted = false;
private static final String EXCEPTION_PATH = "/osmand/exception.log";
private static final String EXCEPTION_FILE_SIZE = "/osmand/exception.log";
private Button showMap;
private Button exitButton;
private Button settingsButton;
private Button searchButton;
private NotificationManager mNotificationManager;
private int APP_NOTIFICATION_ID;
public void startApplication(){
if(!applicationAlreadyStarted){
// TODO exception!!! has leaked window ?
final ProgressDialog dlg = ProgressDialog.show(this, "Loading data", "Reading indices...");
final ProgressDialogImplementation impl = new ProgressDialogImplementation(dlg);
new Thread("Reader indexes") {
@Override
public void run() {
try {
ResourceManager.getResourceManager().indexingPoi(impl);
ResourceManager.getResourceManager().indexingAddresses(impl);
} finally {
dlg.dismiss();
}
}
}.start();
applicationAlreadyStarted = true;
Thread.setDefaultUncaughtExceptionHandler(new DefaultExceptionHandler());
long size = getPreferences(MODE_WORLD_READABLE).getLong(EXCEPTION_FILE_SIZE, 0);
File file = new File(Environment.getExternalStorageDirectory(), EXCEPTION_PATH);
if(file.exists() && file.length() > 0){
if(size != file.length()){
String msg = "Previous application run was crashed. Log file is in " + EXCEPTION_PATH +". ";
msg += "Please raise the issue and attach log file.";
Builder builder = new AlertDialog.Builder(MainMenuActivity.this);
builder.setMessage(msg).setNeutralButton("Close", null).show();
getPreferences(MODE_WORLD_READABLE).edit().putLong(EXCEPTION_FILE_SIZE, file.length()).commit();
}
} else {
if(size > 0){
getPreferences(MODE_WORLD_READABLE).edit().putLong(EXCEPTION_FILE_SIZE, 0).commit();
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -84,21 +142,43 @@ public class MainMenuActivity extends Activity {
MainMenuActivity.this.finish();
}
});
// TODO exception!!! has leaked window !
final ProgressDialog dlg = ProgressDialog.show(this, "Loading data", "Reading indices...");
final ProgressDialogImplementation impl = new ProgressDialogImplementation(dlg);
new Thread() {
@Override
public void run() {
try {
ResourceManager.getResourceManager().indexingPoi(impl);
ResourceManager.getResourceManager().indexingAddresses(impl);
} finally {
dlg.dismiss();
}
}
}.start();
startApplication();
}
private class DefaultExceptionHandler implements UncaughtExceptionHandler {
private UncaughtExceptionHandler defaultHandler;
public DefaultExceptionHandler(){
defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
}
@Override
public void uncaughtException(final Thread thread, final Throwable ex) {
File file = new File(Environment.getExternalStorageDirectory(), EXCEPTION_PATH);
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(out);
ex.printStackTrace(printStream);
StringBuilder msg = new StringBuilder();
msg.append("Exception occured in thread " + thread.toString() + " : ").
append(DateFormat.format("MMMM dd, yyyy h:mm:ss", System.currentTimeMillis())).append("\n").
append(new String(out.toByteArray()));
if(Environment.getExternalStorageDirectory().canRead()){
BufferedWriter writer = new BufferedWriter(new FileWriter(file, true));
writer.write(msg.toString());
writer.close();
}
defaultHandler.uncaughtException(thread, ex);
} catch (Exception e) {
// swallow all exceptions
Log.e(LogUtil.TAG, "Exception while handle other exception", e);
}
}
}
}