Intermitent NullPointerException when using AlarmManager


#1

Hello, everyone,

I’m having some problems when putting together background services and handler thread classes. I’ve originally posted my problem on stackoverflow http://stackoverflow.com/questions/22138251/intermitent-nullpointerexception-when-using-alarmmanager-in-android, but as I used the book “Android Programming: the big nerd ranch guide”, I thought that maybe someone could help me here too. Any help is really welcome!

I’ve developed a small Android application which uses an AlarmManager to call a Handler Thread that synchronizes some information from the mobile device with a remote server. This process happens every 15 minutes.

When I use the HandlerThread without the aid of the AlarmManager, everything ALWAYS works fine. But when I try to put these two to work together, SOMETIMES it works and SOMETIMES I get the following error :

W/System.err(10557): java.lang.NullPointerException W/System.err(10557):at Synchronizer.queueSyncEverything(Synchronizer.java:109) W/System.err(10557): at SyncService.onHandleIntent(SyncService.java:33) W/System.err(10557): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) W/System.err(10557): at android.os.Handler.dispatchMessage(Handler.java:99)<BR/> W/System.err(10557): at android.os.Looper.loop(Looper.java:137) W/System.err(10557): at android.os.HandlerThread.run(HandlerThread.java:60)

The code is really simple as you can see in the following snippets:

[code]//Method from SyncService, a class which extends IntentService    
protected void onHandleIntent(Intent intent) {
	ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
	if(cm.getActiveNetworkInfo() == null){
		return;
	}
	if(mSynchronizer == null){
		mSynchronizer = new Synchronizer(getApplicationContext(), this);
		mSynchronizer.start();
	        mSynchronizer.getLooper();
	}		
	mSynchronizer.queueSyncEverything();
	
}[/code]

//Method from Synchronizer, a class which extends HandlerThread public void queueSyncEverything(){ try{ mHandler.obtainMessage(MESSAGE_SYNC_EVERYTHING).sendToTarget(); } catch(Exception e){ mListener.onError(); e.printStackTrace(); } }

As @DavidWasser suggested, I did some more testing and discovered that sometimes mHandler is null. This variable is set inside the method onLooperPrepared from Synchronizer (which extends from HandlerThread) as you can see here:

[code] @Override
protected void onLooperPrepared(){
mHandler = new Handler(){

		@Override
		public void handleMessage(Message msg){

            if(msg.what == MESSAGE_SYNC_EVERYTHING){
				handleSyncEverything();
				mListener.onFinished();
			}
		}
	};
}[/code]

The constructor of this class, as @DavidWasser asked, is just:

[code]public Synchronizer(Synchronizer.Listener listener){
	super(TAG);
	mListener = listener;		
}[/code]

mListener is just an delegate-like object who receives events sent by the Synchronizer class, like when the Synchronization is finished. TAG is just a name to make it easier to debug. Maybe my main difficulty is to understand how the class HandlerThread works and when is it the right time to set its Handler object.

P.S.: This way of setting up the HandlerThread I got by reading the book “Android Programming: The Big Nerd Ranch Guide”.