My app is currently crashing on start I only have one class MainActivity I'm trying to figure out what causing it
I found that there is multiple Log
Log.v(); // Verbose Log.d(); // Debug Log.i(); // Info Log.w(); // Warning Log.e(); // Error
Which one should I use ? and what about Breakpoint should I check every entry method ?
I tried implementing like this I'm not sure if it's the best or right way
try{
camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openDialog();
}
});
catch (Exception ex)
{
Log.e("I shouldn't be here", ex.getMessage());
}
If you look at the logcat stacktrace, it already should tell you what caused the exception. You should only need to set breakpoints around where the exception happens
As for which level of logging you need, it is up to you to determine the severity & verbosity of the message. Info is a general print, error is critical, warn is somewhere in between and debug is for putting lots of details. And Log.wtf is just for laughs 😁 (although the actual reason is mentioned in the documentation)
Rather than using the default Log class, consider using Timber.
Remember, whenever you log in production a puppy dies. 🐶🐶🐶☠️
Related
I am attempting to implement a navigation component to my application following this MapBox guide:
https://docs.mapbox.com/help/tutorials/android-navigation-sdk/
When I attempt to call .startNavigation(...) I get an unexpected error:
2020-03-08 19:51:45.786 11394-11394/com.example.mapboxnav A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8 in tid 11394 (mple.mapboxnav), pid 11394 (mple.mapboxnav)
Since the application I'm creating features many buttons, I've implemented View.OnClickListener and am calling the Navigation interface when a user presses the navigation button (R.id.startNav). However, as soon as a user presses the button the application crashes.
The currentRoute is working and shown on the map upon calling getRoute, like the example. I have verified that currentRoute is definitely not null. I have also attempted to start navigation with different coordinates without any luck.
currentRoute contains a route from the user's current/last known location to a specified destination. For reference, the line is set/generated with the following method:
public void initLine(Double lng, Double lat) {
Location lastKnownLocation = mapboxMap.getLocationComponent().getLastKnownLocation();
Point origin = Point.fromLngLat(lastKnownLocation.getLongitude(), lastKnownLocation.getLatitude());
Point destination = Point.fromLngLat(lng, lat);
getRoute(origin, destination);
}
onClick:
public void onClick(View v) {
switch (v.getId()) {
...
case R.id.startNav:
boolean simulateRoute = true;
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.directionsRoute(currentRoute)
.shouldSimulateRoute(simulateRoute)
.build();
NavigationLauncher.startNavigation(MainActivity.this, options); // Causes Crash
}
}
I spend two and a half days over this until I discovered that the problem is that we need to set the location Engine before calling :
NavigationLauncher.startNavigation(MainActivity.this, options);
so your code should look like this and it should work:
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.directionsRoute(currentRoute)
.shouldSimulateRoute(simulateRoute)
.build();
// Just add these three lines
MapboxNavigation navigation = new MapboxNavigation(DriveActivity.this, getString(R.string. mapbox_access_token));
navigation.setLocationEngine(locationEngine); mapboxMap.getLocationComponent().setLocationComponentEnabled(true);
NavigationLauncher.startNavigation(MainActivity.this, options);
Let me know how it goes
Criss
Hmm, very strange. I still feel like there's gotta be more info buried in the logcat. Maybe well above the Fatal signal 11 line? Maybe, just maybe, it's related to Location lastKnownLocation = mapboxMap.getLocationComponent().getLastKnownLocation();. Add a null check for lastKnownLocation and put
Point origin = Point.fromLngLat(lastKnownLocation.getLongitude(), lastKnownLocation.getLatitude());
Point destination = Point.fromLngLat(lng, lat);
getRoute(origin, destination);
inside of the null check block?
Maybe you're using the wrong classes? Look at the Nav SDK's NavigationLauncher test app activity: https://github.com/mapbox/mapbox-navigation-android/blob/master/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java#L342-L347. It's using NavigationLauncherOptions.Builder, whereas you aren't.
https://github.com/mapbox/mapbox-navigation-android/blob/master/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java#L365
A SIGSEGV error is thrown when you attempt to access memory incorrectly or are accessing a piece of memory that is not allotted for your use. See What causes a SIGSEGV for more information on this.
The fact that the error occurs on the line below,
NavigationLauncher.startNavigation(MainActivity.this, options);
leads me to believe that NavigationLauncherOptions options is not being assigned correctly and is possibly NULL causing you to derefrence a null pointer.
I know this isn't a perfect answer and doesn't really provide a solution to your problem, but I hope it helps bring you closer to finding an answer.
Here are some links that may help(including documentation):
https://github.com/mapbox/mapbox-navigation-android/issues/1529
https://docs.mapbox.com/android/navigation/overview/
Am I able to listen for messages being places into the LogCat by my own application?
For example something like...
// Somewhere in my application (on a background service):
Log.i("myModule", "Something been done");
and....
// Somewhere else something like...
LogCatListener logCatListener = new LogCatListener()
{
public void onInfoRecieved(String tag, String message)
{
//Do whatever you want with the message
}
}
I'm an Android noob so be gentle with me!
Thanks.
Unfortunately it looks like you directly can't do that for typical Log calls (.d, .i, .w). If you look at the source code of the Log class (https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r2.1/core/java/android/util/Log.java) you'll see that these calls are just translated into a println_native, a private function mapped to a native implementation.
Also, the Log class is final, so you can't extend it and hook into .d , .i , .e, .w
I'm afraid your only solution is to write a Log class wrapper if you need to capture those calls. This will work for your custom Log's but obviously not for the system-issued calls to the Log class.
But good news is there's a special Log function that allows listeners. There's a funny method on the Log class:
public static TerribleFailureHandler setWtfHandler(TerribleFailureHandler handler)
And you can set a handler that will be called when you do
Log.wtf (TAG, message)
funny google method names :)
If my app crashes, it hangs for a couple of seconds before I'm told by Android that the app crashed and needs to close. So I was thinking of catching all exceptions in my app with a general:
try {
// ...
} catch(Exception e) {
// ...
}
And make a new Activity that explains that the application crashed instantly (and also giving users an opportunity to send a mail with the error details), instead of having that delay thanks to Android. Are there better methods of accomplishing this or is this discouraged?
Update: I am using a Nexus 5 with ART enabled and I am not noticing the delay I used to experience with apps crashing (the "hanging" I was talking about originally). I think since everything is native code now, the crash happens instantly along with getting all the crash information. Perhaps the Nexus 5 is just quick :) regardless, this may not be a worry in future releases of Android (given that ART is going to be the default runtime in Android L).
Here, check for the link for reference.
In here you create a class say ExceptionHandler that implements java.lang.Thread.UncaughtExceptionHandler..
Inside this class you will do your life saving stuff like creating stacktrace and gettin ready to upload error report etc....
Now comes the important part i.e. How to catch that exception.
Though it is very simple. Copy following line of code in your each Activity just after the call of super method in your overriden onCreate method.
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
Your Activity may look something like this…
public class ForceClose extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
setContentView(R.layout.main);
}
}
You could just use a generic alert dialog to quickly display error messages.
For example...
//******************************************
//some generic method
//******************************************
private void doStuff()
{
try
{
//do some stuff here
}
catch(Exception e)
{
messageBox("doStuff", e.getMessage());
}
}
//*********************************************************
//generic dialog, takes in the method name and error message
//*********************************************************
private void messageBox(String method, String message)
{
Log.d("EXCEPTION: " + method, message);
AlertDialog.Builder messageBox = new AlertDialog.Builder(this);
messageBox.setTitle(method);
messageBox.setMessage(message);
messageBox.setCancelable(false);
messageBox.setNeutralButton("OK", null);
messageBox.show();
}
You could also add other error handling options into this method, such as print stacktrace
i found the "wtf" (what a terrible failure) method in the Log class. From the description:
Depending on system configuration, a report may be added to the
DropBoxManager and/or the process may be terminated immediately with
an error dialog.
http://developer.android.com/reference/android/util/Log.html
I am designing an application which shows unhandled exception due to lot of reason. So I want my application to show alert in catch block instead.
You could do something like this:
private Alert alert;
private Display display;
// Obtain display with display = Display.getDisplay(this); in consturctor
catch(Exception e) {
alert = new Alert("Error occurred", "Message: " + e.getMessage(), null, AlertType.ERROR);
alert.setTimeout(Alert.FOREVER);
display.setCurrent(alert, form);
}
Hope this helps.
I think you can just put the alert handling in the catch block:
catch(Exception e) {
// create new alert and
}
The problem I think this guy is having, is that the exceptions are appearing seemingly randomly, i.e. he won't know which piece of code is throwing it.
Some J2ME handsets (e.g. Nokias) have a habit of showing the exception name to the user in an alert, while others (e.g. Sony Ericssons) silently swallow them.
You need to identify all the points at which code can be executed (i.e. all the threads you're creating, and all the MIDP lifecycle methods that the framework could be calling for you), and wrap all of those in try/catch blocks, to ensure that no exceptions can be shown in this way.
That will probably slow your code down a lot though, so you should get to the bottom of what causes these exceptions to appear, and fix the problem!
I have a button in my program that, when pressed, is supposed to take you to my wiki page about the program. I used the following line to do so:
java.awt.Desktop.getDesktop().browse(new java.net.URI("http://supuh.wikia.com/wiki/BHT"));
The problem is that, no matter what environment in which the program is run, I always get the following error:
java.security.AccessControlException: access denied (java.awt.AWTPermission showWindowWithoutWarningBanner)
does anyone know how I can fix this? Note that this only works in the one program. Any other program I make can use the same method with no problem.
Exit hook
At the start of my program, this hook is added. The program runs fine without it...
System.setSecurityManager(new SecurityManager()
{
#Override
public void checkExit(int status)
{
closeFile(status);
}
});
this hook is needed, but the browse(URI uri) method in question won't work with it. Solutions?
This means you are running with a security manager:
SecurityException - if a security manager exists and it denies the AWTPermission("showWindowWithoutWarningBanner") permission, or the calling thread is not allowed to create a subprocess; and not invoked from within an applet or Java Web Started application
If this is an applet, or a Java Web Start app - sign your jar.
Update Adding a security manager to detect program exit is wrong. There are multiple ways to do this properly. In your case I guess this would be most appropriate:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
closeFile();
}
));
Swing-specific solutions are:
if you don't have to perform extra actions, use frame.setDefaultCloseAction(Frame.EXIT_ON_CLOSE)
use addWindowStateListener and check for WindowEvent.WINDOW_CLOSED
That said, two notes:
you must not hold files open for a long time. Use try/catch/finally to open and close them whenever they are needed.
if you really need a security manager at some point, make sure you override the appropriate method of the SecurityManager that checks whether you can open the link. (won't tell you which one, so that you are not tempted to jump onto this solution, which is wrong)
To summarize, I'd go for setDefaultActionOnClose, and close each file right after I finish reading/writing it.
Update 2: After you linked to your original question describing what exactly are you trying to achieve, things change a bit. You are trying to prevent exit, so you do need a SecurityManager. This makes it so that you should override the checkPermission method and do nothing there (i.e. don't throw exceptions), at least when these permissions are checked (they are checked when browse is called):
new AWTPermission("showWindowWithoutWarningBanner")
new FilePermission("<<ALL FILES>>", SecurityConstants.FILE_EXECUTE_ACTION)
Update 3 Here's how exactly to override the method:
#Override
public void checkPermission(Permission permission) {
if (permission instanceof AWTPermission) {
if (permission.getName().equals("showWindowWithoutWarningBanner")) {
return;
}
}
if (permission instanceof FilePermission) {
if (permission.getActions().equalsIgnoreCase("execute")) {
return;
}
}
java.security.AccessController.checkPermission(permission);
}
(you can go without the outer if-s)
Update 4 The above method will work only if you have given permissions to your program. Otherwise it is a not-well documented behaviour of the JVM that overriding security managers are not allowed to be unprivileged. Take a look at this report - the comments say how to work it around.
To make your life simpler, you can simply #Override public void checkPermission(..) with an empty method body.
Instead of using your own SecurityManager, install a shutdown hook instead:
Runnable runnable = new Runnable() {
closeFile(status);
}
Runtime.getRuntime().addShutdownHook(new Thread (runnable, "Close file"));