Java NullPointerException is an unchecked exception and extends RuntimeException
. NullPointerException doesn’t force us to use catch block to handle it. This exception is very much like a nightmare for most of java developer community. They usually pop up when we least expect them.
I have also spent a lot of precious time while looking for reasons and best approaches to handle such issues. I will be writing here some best practices followed industry-wise, some expert talks and my own learning over the time.
Table of Contents 1. Why NullPointerException occur in the code 2. Common places where NullPointerException usually occur 3. Best ways to avoid NullPointerException 4. Available NullPointerException safe operations 5. What if you must allow NullPointerException in some places
1. Why NullPointerException occur in the code
NullPointerException is a situation in code where you try to access/ modify an object which has not been initialized yet. It essentially means that object reference variable is not pointing anywhere and refers to nothing or ‘null‘. A example java program which throws null pointer exception.
package com.howtodoinjava.demo.npe; public class SampleNPE { public static void main(String[] args) { String s = null; System.out.println( s.toString() ); // 's' is un-initialized and is null } }
2. Common places where Java NullPointerException usually occur
Well, NullPointerException can occur anywhere in the code for various reasons but I have prepared list of most frequent places based on my experience.
- Invoking methods on an object which is not initialized
- Parameters passed in a method are
null
- Calling
toString()
method on object which isnull
- Comparing object properties in
if
block without checkingnull
equality - Incorrect configuration for frameworks like spring which works on dependency injection
- Using
synchronized
on an object which isnull
- Chained statements i.e. multiple method calls in a single statement
This is not an exhaustive list. There are several other places and reasons also. If you can recall any such other, please leave a comment. it will help others (beginners) also.
3. Best ways to avoid Java NullPointerException
3.1. Ternary Operator
This operator results to the value on the left hand side if not null else right hand side is evaluated. It has syntax like :
boolean expression ? value1 : value2;
If expression is evaluated as true then entire expression returns value1 otherwise value2. Its more like if-else construct but it is more effective and expressive. To prevent NullPointerException (NPE) , use this operator like below code:
String str = (param == null) ? "NA" : param;
3.2. Use apache commons StringUtils for String operations
Apache commons lang is a collection of several utility classes for various king of operation. One of them is StringUtils.java. Use StringUtils.isNotEmpty() for verifying if string passed as parameter is null or empty string. If it is not null or empty; then use it further.
Other similar methods are StringUtils. IsEmpty(), and StringUtils.equals(). They claim in their javadocs that if StringUtils.isNotBlank() throws an NPE, then there is a bug in the API.
if (StringUtils.isNotEmpty(obj.getvalue())){ String s = obj.getvalue(); .... }
3.3. Check Method Arguments for null very early
You should always put input validation at the beginning of your method so that the rest of your code does not have to deal with the possibility of incorrect input. So if someone passes in a null, things will break early in the stack rather than in some deeper location where the root problem will be rather difficult to identify.
Aiming for fail fast behavior is a good choice in most situations.
3.4. Consider Primitives Rather than Objects
Null problem occurs where object references points to nothing. So it is always safe to use primitives as much as possible because they does not suffer with null references. All primitives must have some default values also attached so beware of it.
3.5. Carefully Consider Chained Method Calls
While chained statements are nice to look at in the code, they are not NPE friendly. A single statement spread over several lines will give you the line number of the first line in the stack trace regardless of where it occurs.
ref.method1().method2().method3().methods4();
These kind of chained statement will print only “NullPointerException occurred in line number xyz”. It really is hard to debug such code. Avoid such calls.
3.6. Use String.valueOf() Rather than toString()
If you have to print the string representation of any object, the don’t use object.toString(). This is a very soft target for NPE. Instead use String.valueOf(object).
Even if object is null in second method, it will not give exception and will prints ‘null’ to output stream.
3.7. Avoid returning null from your methods
An awesome tip to avoid NPE is to return empty strings or empty collections rather than a null. Do this consistently across your application. You will note that a bucket load of null checks become unneeded if you do so.
An example could be:
List<string> data = null; @SuppressWarnings("unchecked") public List getDataDemo() { if(data == null) return Collections.EMPTY_LIST; //Returns unmodifiable list return data; }
Users of above method, even if they missed the null check, will not see ugly NPE.
3.8. Discourage Passing of Null Parameters
I have seen some method declarations where method expects two or more parameters. If one of parameter is passed as null, then also method works if some different manner. Avoid this.
In stead you should define two methods; one with single parameter and second with two parameters. Make parameters passing mandatory. This helps a lot when writing application logic inside methods because you are sure that method parameters will not be null; so you don’t put unnecessary assumptions and assertions.
3.9. Call String.equals(String) on ‘Safe’ Non-Null String
In stead of writing below code for string comparison
public class SampleNPE { public void demoEqualData(String param) { if (param.equals("check me")) { // some code } } }
write above code like this. This will not cause in NPE even if param is passed as null.
public class SampleNPE { public void demoEqualData(String param) { if ("check me".equals(param)) // Do like this { // some code } } }
4. Available NullPointerException safe operations
4.1. instanceof operator
The instanceof operator is NPE safe. So, instanceof null always returns false. It does not cause a NullPointerException. You can eliminate messy conditional code if you remember this fact.
// Unnecessary code if (data != null && data instanceof InterestingData) { } // Less code. Better!! if (data instanceof InterestingData) { }
4.2. Accessing static members of a class
If you are dealing with static variables or static method than you won’t get null pointer exception even if you have your reference variable pointing to null because static variables and method call are bonded during compile time based on class name and not associated with object
MyObject obj = null; String attrib = obj.staticAttribute; //no NullPointerException because staticAttribute is static variable defined in class MyObject
Please let me know if you know some more such language constructs which does not fail when null is encountered.
5. What if you must allow NullPointerException in some places
Joshua bloch in effective java says that “Arguably, all erroneous method invocations boil down to an illegal argument or illegal state, but other exceptions are standardly used for certain kinds of illegal arguments and states. If a caller passes null in some parameter for which null values are prohibited, convention dictates that NullPointerException
be thrown rather than IllegalArgumentException
.”
So if you must allow NullPointerException
in some places in you code then make sure you make them more informative then they usually are. Take a look at below example:
package com.howtodoinjava.demo.npe; public class SampleNPE { public static void main(String[] args) { // call one method at a time doSomething(null); doSomethingElse(null); } private static String doSomething(final String param) { System.out.println(param.toString()); return "I am done !!"; } private static String doSomethingElse(final String param) { if (param == null) { throw new NullPointerException( " :: Parameter 'param' was null inside method 'doSomething'."); } System.out.println(param.toString()); return "I am done !!"; } }
Output of both method calls is this:
Exception in thread "main" java.lang.NullPointerException at com.howtodoinjava.demo.npe.SampleNPE.doSomething(SampleNPE.java:14) at com.howtodoinjava.demo.npe.SampleNPE.main(SampleNPE.java:8) Exception in thread "main" java.lang.NullPointerException: :: Parameter 'param' was null inside method 'doSomething'. at com.howtodoinjava.demo.npe.SampleNPE.doSomethingElse(SampleNPE.java:21) at com.howtodoinjava.demo.npe.SampleNPE.main(SampleNPE.java:8)
Clearly second stack trace is more informative and makes debugging easy. Use this in future.
I am done with my experience around NullPointerException till date. If you know other points around the topic, please share with all of us !!
Happy Learning !!
Ashwin
Using java’s feature Optional can be effectively avoid NPE and also can write maintainable code
Lokesh Gupta
Yes, you are right.
Shailesh
Thanks 😉
Very Nice Article as I many times faced NPE in code.
wisse denis
Unable to create service java.lang.NullPointerException
this is my error
7306-7306/org.pearlcom E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: org.pearlcom, PID: 7306
java.lang.RuntimeException: Unable to create service org.pearlcom.PearlcomService: java.lang.NullPointerException
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2582)
at android.app.ActivityThread.access$1800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at org.pearlcom.PearlcomService.onCreate(PearlcomService.java:110)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2572)
at android.app.ActivityThread.access$1800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
at dalvik.system.NativeStart.main(Native Method)
MY PEARLCOM SERVICE
package org.pearlcom;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCore.GlobalState;
import org.linphone.core.LinphoneCore.RegistrationState;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreListenerBase;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.mediastream.Log;
import org.linphone.mediastream.Version;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.provider.MediaStore;
/**
*
*
* @Created by REVO-WISSE on 4/22/2015
*
*/
public final class PearlcomService extends Service {
/* Listener needs to be implemented in the Service as it calls
* setLatestEventInfo and startActivity() which needs a context.
*/
public static final String START_PEARLCOM_LOGS = ” ==== Phone information dump ====”;
public static final int IC_LEVEL_ORANGE=0;
/*private static final int IC_LEVEL_GREEN=1;
private static final int IC_LEVEL_RED=2;*/
public static final int IC_LEVEL_OFFLINE=3;
private static PearlcomService instance;
private final static int NOTIF_ID=1;
private final static int INCALL_NOTIF_ID=2;
private final static int MESSAGE_NOTIF_ID=3;
private final static int CUSTOM_NOTIF_ID=4;
public static boolean isReady() {
return instance != null && instance.mTestDelayElapsed;
}
/**
* @throws RuntimeException service not instantiated
*/
public static PearlcomService instance() {
if (isReady()) return instance;
throw new RuntimeException(“PearlcomService not instantiated yet”);
}
public Handler mHandler = new Handler();
// private boolean mTestDelayElapsed; // add a timer for testing
private boolean mTestDelayElapsed = true; // no timer
private NotificationManager mNM;
private Notification mNotif;
private Notification mIncallNotif;
private Notification mMsgNotif;
private Notification mCustomNotif;
private int mMsgNotifCount;
private PendingIntent mNotifContentIntent;
private PendingIntent mkeepAlivePendingIntent;
private String mNotificationTitle;
private boolean mDisableRegistrationStatus;
private LinphoneCoreListenerBase mListener;
public int getMessageNotifCount() {
return mMsgNotifCount;
}
public void resetMessageNotifCount() {
mMsgNotifCount = 0;
}
@Override
public void onCreate() {
super.onCreate();
// In case restart after a crash. Main in MainPearlcom
mNotificationTitle = getString(R.string.service_name);
// Needed in order for the two next calls to succeed, libraries must have been loaded first
LinphoneCoreFactory.instance().setLogCollectionPath(getFilesDir().getAbsolutePath());
LinphoneCoreFactory.instance().enableLogCollection(!(getResources().getBoolean(R.bool.disable_every_log)));
// Dump some debugging information to the logs
Log.i(START_PEARLCOM_LOGS);
dumpDeviceInformation();
dumpInstalledPearlcomInformation();
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNM.cancel(INCALL_NOTIF_ID); // in case of crash the icon is not removed
Intent notifIntent = new Intent(this, incomingReceivedActivity);
notifIntent.putExtra(“Notification”, true);
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap bm = null;
try {
bm = BitmapFactory.decodeResource(getResources(), R.drawable.log);
} catch (Exception e) {
}
mNotif = Compatibility.createNotification(this, mNotificationTitle, “”, R.drawable.status_level, IC_LEVEL_OFFLINE, bm, mNotifContentIntent, true);
PearlcomManager.createAndStart(PearlcomService.this);
instance = this; // instance is ready once pearlcom manager has been created
PearlcomManager.getLc().addListener(mListener = new LinphoneCoreListenerBase(){
@Override
public void callState(LinphoneCore lc, LinphoneCall call, State state, String message) {
if (instance == null) {
Log.i(“Service not ready, discarding call state change to “,state.toString());
return;
}
if (state == State.IncomingReceived) {
onIncomingReceived();
}
if (state == State.CallUpdatedByRemote) {
// If the correspondent proposes video while audio call
boolean remoteVideo = call.getRemoteParams().getVideoEnabled();
boolean localVideo = call.getCurrentParamsCopy().getVideoEnabled();
boolean autoAcceptCameraPolicy = Preferences.instance().shouldAutomaticallyAcceptVideoRequests();
if (remoteVideo && !localVideo && !autoAcceptCameraPolicy && !PearlcomManager.getLc().isInConference()) {
try {
PearlcomManager.getLc().deferCallUpdate(call);
} catch (LinphoneCoreException e) {
e.printStackTrace();
}
}
}
if (state == State.StreamsRunning) {
// Workaround bug current call seems to be updated after state changed to streams running
if (getResources().getBoolean(R.bool.enable_call_notification))
refreshIncallIcon(call);
} else {
if (getResources().getBoolean(R.bool.enable_call_notification))
refreshIncallIcon(PearlcomManager.getLc().getCurrentCall());
}
}
@Override
public void globalState(LinphoneCore lc,GlobalState state, String message) {
if (state == GlobalState.GlobalOn) {
sendNotification(IC_LEVEL_OFFLINE, R.string.notification_started);
}
}
@Override
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, RegistrationState state, String smessage) {
// if (instance == null) {
// Log.i(“Service not ready, discarding registration state change to “,state.toString());
// return;
// }
if (!mDisableRegistrationStatus) {
if (state == RegistrationState.RegistrationOk && PearlcomManager.getLc().getDefaultProxyConfig() != null && PearlcomManager.getLc().getDefaultProxyConfig().isRegistered()) {
sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
}
if ((state == RegistrationState.RegistrationFailed || state == RegistrationState.RegistrationCleared) && (PearlcomManager.getLc().getDefaultProxyConfig() == null || !PearlcomManager.getLc().getDefaultProxyConfig().isRegistered())) {
sendNotification(IC_LEVEL_OFFLINE, R.string.notification_register_failure);
}
if (state == RegistrationState.RegistrationNone) {
sendNotification(IC_LEVEL_OFFLINE, R.string.notification_started);
}
}
}
});
// Retrieve methods to publish notification and keep Android
// from killing us and keep the audio quality high.
if (Version.sdkStrictlyBelow(Version.API05_ECLAIR_20)) {
try {
mSetForeground = getClass().getMethod(“setForeground”, mSetFgSign);
} catch (NoSuchMethodException e) {
Log.e(e, “Couldn’t find foreground method”);
}
} else {
try {
mStartForeground = getClass().getMethod(“startForeground”, mStartFgSign);
mStopForeground = getClass().getMethod(“stopForeground”, mStopFgSign);
} catch (NoSuchMethodException e) {
Log.e(e, “Couldn’t find startGoreground or stopForeground”);
}
}
startForegroundCompat(NOTIF_ID, mNotif);
if (!mTestDelayElapsed) {
// Only used when testing. Simulates a 5 seconds delay for launching service
mHandler.postDelayed(new Runnable() {
@Override public void run() {
mTestDelayElapsed = true;
}
}, 5000);
}
//make sure the application will at least wakes up every 10 mn
Intent intent = new Intent(this, KeepAliveHandler.class);
mkeepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP
, SystemClock.elapsedRealtime()+600000
, 600000
, mkeepAlivePendingIntent);
}
private enum IncallIconState {INCALL, PAUSE, VIDEO, IDLE}
private IncallIconState mCurrentIncallIconState = IncallIconState.IDLE;
private synchronized void setIncallIcon(IncallIconState state) {
if (state == mCurrentIncallIconState) return;
mCurrentIncallIconState = state;
int notificationTextId = 0;
int inconId = 0;
switch (state) {
case IDLE:
mNM.cancel(INCALL_NOTIF_ID);
return;
case INCALL:
inconId = R.drawable.phone_call_on;
notificationTextId = R.string.incall_notif_active;
break;
case PAUSE:
inconId = R.drawable.pause_on;
notificationTextId = R.string.incall_notif_paused;
break;
case VIDEO:
inconId = R.drawable.conf_video;
notificationTextId = R.string.incall_notif_video;
break;
default:
throw new IllegalArgumentException(“Unknown state ” + state);
}
if (PearlcomManager.getLc().getCallsNb() == 0) {
return;
}
LinphoneCall call = PearlcomManager.getLc().getCalls()[0];
String userName = call.getRemoteAddress().getUserName();
String domain = call.getRemoteAddress().getDomain();
String displayName = call.getRemoteAddress().getDisplayName();
LinphoneAddress address = LinphoneCoreFactory.instance().createLinphoneAddress(userName,domain,null);
address.setDisplayName(displayName);
Uri pictureUri = PearlcomUtils.findUriPictureOfContactAndSetDisplayName(address, getContentResolver());
Bitmap bm = null;
try {
bm = MediaStore.Images.Media.getBitmap(getContentResolver(), pictureUri);
} catch (Exception e) {
bm = BitmapFactory.decodeResource(getResources(), R.drawable.friends_on);
}
String name = address.getDisplayName() == null ? address.getUserName() : address.getDisplayName();
mIncallNotif = Compatibility.createInCallNotification(getApplicationContext(), mNotificationTitle, getString(notificationTextId), inconId, bm, name, mNotifContentIntent);
notifyWrapper(INCALL_NOTIF_ID, mIncallNotif);
}
public void refreshIncallIcon(LinphoneCall currentCall) {
LinphoneCore lc = PearlcomManager.getLc();
if (currentCall != null) {
if (currentCall.getCurrentParamsCopy().getVideoEnabled() && currentCall.cameraEnabled()) {
// checking first current params is mandatory
setIncallIcon(IncallIconState.VIDEO);
} else {
setIncallIcon(IncallIconState.INCALL);
}
} else if (lc.getCallsNb() == 0) {
setIncallIcon(IncallIconState.IDLE);
} else if (lc.isInConference()) {
setIncallIcon(IncallIconState.INCALL);
} else {
setIncallIcon(IncallIconState.PAUSE);
}
}
@Deprecated
public void addNotification(Intent onClickIntent, int iconResourceID, String title, String message) {
addCustomNotification(onClickIntent, iconResourceID, title, message, true);
}
public void addCustomNotification(Intent onClickIntent, int iconResourceID, String title, String message, boolean isOngoingEvent) {
PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap bm = null;
try {
bm = BitmapFactory.decodeResource(getResources(), R.drawable.log);
} catch (Exception e) {
}
mCustomNotif = Compatibility.createNotification(this, title, message, iconResourceID, 0, bm, notifContentIntent, isOngoingEvent);
mCustomNotif.defaults |= Notification.DEFAULT_VIBRATE;
mCustomNotif.defaults |= Notification.DEFAULT_SOUND;
mCustomNotif.defaults |= Notification.DEFAULT_LIGHTS;
notifyWrapper(CUSTOM_NOTIF_ID, mCustomNotif);
}
public void removeCustomNotification() {
mNM.cancel(CUSTOM_NOTIF_ID);
resetIntentLaunchedOnNotificationClick();
}
public void displayMessageNotification(String fromSipUri, String fromName, String message) {
Intent notifIntent = new Intent(this, MainPearlcom.class);
notifIntent.putExtra(“GoToChat”, true);
notifIntent.putExtra(“ChatContactSipUri”, fromSipUri);
PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (fromName == null) {
fromName = fromSipUri;
}
if (mMsgNotif == null) {
mMsgNotifCount = 1;
} else {
mMsgNotifCount++;
}
Uri pictureUri;
try {
pictureUri = PearlcomUtils.findUriPictureOfContactAndSetDisplayName(LinphoneCoreFactory.instance().createLinphoneAddress(fromSipUri), getContentResolver());
} catch (LinphoneCoreException e1) {
Log.e(“Cannot parse from address”,e1);
pictureUri=null;
}
Bitmap bm = null;
try {
bm = MediaStore.Images.Media.getBitmap(getContentResolver(), pictureUri);
} catch (Exception e) {
bm = BitmapFactory.decodeResource(getResources(), R.drawable.friends_on);
}
mMsgNotif = Compatibility.createMessageNotification(getApplicationContext(), mMsgNotifCount, fromName, message, bm, notifContentIntent);
notifyWrapper(MESSAGE_NOTIF_ID, mMsgNotif);
}
public void removeMessageNotification() {
mNM.cancel(MESSAGE_NOTIF_ID);
resetIntentLaunchedOnNotificationClick();
}
private static final Class[] mSetFgSign = new Class[] {boolean.class};
private static final Class[] mStartFgSign = new Class[] {
int.class, Notification.class};
private static final Class[] mStopFgSign = new Class[] {boolean.class};
private Method mSetForeground;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mSetForegroundArgs = new Object[1];
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];
private Class incomingReceivedActivity = MainPearlcom.class;
void invokeMethod(Method method, Object[] args) {
try {
method.invoke(this, args);
} catch (InvocationTargetException e) {
// Should not happen.
Log.w(e, “Unable to invoke method”);
} catch (IllegalAccessException e) {
// Should not happen.
Log.w(e, “Unable to invoke method”);
}
}
/**
* This is a wrapper around the new startForeground method, using the older
* APIs if it is not available.
*/
void startForegroundCompat(int id, Notification notification) {
// If we have the new startForeground API, then use it.
if (mStartForeground != null) {
mStartForegroundArgs[0] = Integer.valueOf(id);
mStartForegroundArgs[1] = notification;
invokeMethod(mStartForeground, mStartForegroundArgs);
return;
}
// Fall back on the old API.
if (mSetForeground != null) {
mSetForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mSetForeground, mSetForegroundArgs);
// continue
}
notifyWrapper(id, notification);
}
/**
* This is a wrapper around the new stopForeground method, using the older
* APIs if it is not available.
*/
void stopForegroundCompat(int id) {
// If we have the new stopForeground API, then use it.
if (mStopForeground != null) {
mStopForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mStopForeground, mStopForegroundArgs);
return;
}
// Fall back on the old API. Note to cancel BEFORE changing the
// foreground state, since we could be killed at that point.
mNM.cancel(id);
if (mSetForeground != null) {
mSetForegroundArgs[0] = Boolean.FALSE;
invokeMethod(mSetForeground, mSetForegroundArgs);
}
}
@SuppressWarnings(“deprecation”)
private void dumpDeviceInformation() {
StringBuilder sb = new StringBuilder();
sb.append(“DEVICE=”).append(Build.DEVICE).append(“\n”);
sb.append(“MODEL=”).append(Build.MODEL).append(“\n”);
//MANUFACTURER doesn’t exist in android 1.5.
//sb.append(“MANUFACTURER=”).append(Build.MANUFACTURER).append(“\n”);
sb.append(“SDK=”).append(Build.VERSION.SDK_INT).append(“\n”);
sb.append(“EABI=”).append(Build.CPU_ABI).append(“\n”);
Log.i(sb.toString());
}
private void dumpInstalledPearlcomInformation() {
PackageInfo info = null;
try {
info = getPackageManager().getPackageInfo(getPackageName(),0);
} catch (NameNotFoundException nnfe) {}
if (info != null) {
Log.i(“Pearlcom version is “, info.versionName + ” (” + info.versionCode + “)”);
} else {
Log.i(“Pearlcom version is unknown”);
}
}
public void disableNotificationsAutomaticRegistrationStatusContent() {
mDisableRegistrationStatus = true;
}
public synchronized void sendNotification(int level, int textId) {
String text = getString(textId);
if (text.contains(“%s”) && PearlcomManager.getLc() != null) {
// Test for null lc is to avoid a NPE when Android mess up badly with the String resources.
LinphoneProxyConfig lpc = PearlcomManager.getLc().getDefaultProxyConfig();
String id = lpc != null ? lpc.getIdentity() : “”;
text = String.format(text, id);
}
Bitmap bm = null;
try {
bm = BitmapFactory.decodeResource(getResources(), R.drawable.log);
} catch (Exception e) {
}
mNotif = Compatibility.createNotification(this, mNotificationTitle, text, R.drawable.status_level, level, bm, mNotifContentIntent, true);
notifyWrapper(NOTIF_ID, mNotif);
}
/**
* Wrap notifier to avoid setting the pearlcom icons while the service
* is stopping. When the (rare) bug is triggered, the pearlcom icon is
* present despite the service is not running. To trigger it one could
* stop pearlcom as soon as it is started. Transport configured with TLS.
*/
private synchronized void notifyWrapper(int id, Notification notification) {
if (instance != null && notification != null) {
mNM.notify(id, notification);
} else {
Log.i(“Service not ready, discarding notification”);
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public synchronized void onDestroy() {
LinphoneCore lc = PearlcomManager.getLcIfManagerNotDestroyedOrNull();
if (lc != null) {
lc.removeListener(mListener);
}
instance = null;
PearlcomManager.destroy();
// Make sure our notification is gone.
stopForegroundCompat(NOTIF_ID);
mNM.cancel(INCALL_NOTIF_ID);
mNM.cancel(MESSAGE_NOTIF_ID);
((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).cancel(mkeepAlivePendingIntent);
super.onDestroy();
}
public void setActivityToLaunchOnIncomingReceived(Class activity) {
incomingReceivedActivity = activity;
resetIntentLaunchedOnNotificationClick();
}
private void resetIntentLaunchedOnNotificationClick() {
Intent notifIntent = new Intent(this, incomingReceivedActivity);
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (mNotif != null) {
mNotif.contentIntent = mNotifContentIntent;
}
notifyWrapper(NOTIF_ID, mNotif);
}
protected void onIncomingReceived() {
//wakeup pearlcom
startActivity(new Intent()
.setClass(this, incomingReceivedActivity)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
public void tryingNewOutgoingCallButAlreadyInCall() {
}
public void tryingNewOutgoingCallButCannotGetCallParameters() {
}
public void tryingNewOutgoingCallButWrongDestinationAddress() {
}
public void onCallEncryptionChanged(final LinphoneCall call, final boolean encrypted,
final String authenticationToken) {
}
}
please help me
Simon Kaleb
I am reverse geocoding in a class that extends intentservice. However, when I send the converted address to the main activity it throws the pesky npe besides having a result receive with the appropriate onreceived method. Here is the code
private void deliverResultToReceiver(int resultCode, String message) {
//mReceiver = new ResultReceiver(new Handler());
Bundle bundle = new Bundle();
try {
if (message != null || !””.equals(message))
bundle.putString(Constants.RESULT_DATA_KEY, message);
mReceiver.send(resultCode, bundle);
} catch (NullPointerException npe) {
// TODO Auto-generated catch block
npe.printStackTrace();
}
}
Lokesh Gupta
Is it android specific issue?? If yes, then please post your problem in any android forum. If it’s NPE problem, then please elaborate your problem, it’s not clear with existing description.
Dima
Another common source of NPE is iterating (especially with for-each loop where it is not so obvious) over a collection that is null, because
for (T t : collection) { … }
id expanded into
for (Iterator i = collection.iterator(); i.hasNext(); ) { … }
Most likely it happens when someone returns null from a method that is supposed to return a collection. But you have covered this already.
Lokesh Gupta
You are right. That’s why below initializations are often best approach to avoid NPE in such cases.
Prateek
Lokesh,Isnt writing System.out.println(s)(where s is a String initialized as null) equivalent to System.out.println(s.toString()) ?
but its weird that first doesnt give NullPointerException and second will give NullPointerException.
Lokesh Gupta
I do not find it weird. It’s expected for me. Invoking a method on any uninitialized reference will always result into NullPointerException.
Delli Babu
Good One Sir !!! Very Useful !!
Amit Mishra
Nice artical, Thank you
Asiel
Very useful my problem solved after applying what I have read here.
Thnx
rajasekhar
nice blog..
Jayant
point#6:
NPE in case calling String,valueOf(null)
java.lang.NullPointerException
at java.lang.String.(String.java:177)
at java.lang.String.valueOf(String.java:2840)
at exceptionTypes.Test.main(Test.java:12)
Lokesh Gupta
Correct. Because valueOf(….) is overloaded method. Here method calling finds closest match which turns out to be “String valueOf(char data[])” and it internally throws NPE.
If you use it with object reference (which is suggested in post) then everything will work fine:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Aparna
Good article
Rakesh Ranjan
Good information.
Marco
very nice blog
I don’t totally agree with the instanceof part
if(object instanceof MyClass) will also be true if object = (MyClass) null, which may not be expected, just as a warning 😉 or am I wrong?
Lokesh Gupta
I created two classes Account.java and TestNPE.java
Below is testing code:
public class TestNPE
{
public static void main(String[] args)
{
Account object = new Account(1);
System.out.println(object instanceof Account);
object = null;
System.out.println(object instanceof Account);
object = (Account) null;
System.out.println(object instanceof Account);
}
}
Output is:
true
false
false
So “object = (Account) null;” actually does not make instanceof comparison true.
Am i missing anything???