I am trying to implement a "never-ending background service" in my android app. It should be used to wait for a server sending a certain type of object to the client and notify the user when this happens. As a template I use fabcirablog. When I try to start the Service with an intent the references I have to use in onStartCommand these refs appear to be null.
I tried setting the variables one by one in the Service-constructor and fetch them in onStartCommand itself. Every time they result in nullreferences.
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
...
if (clientHandler == null)
clientHandler = new ClientHandler(this, this);
if (clientService == null) {
clientService = new ClientService(this, this);
mServiceIntent = new Intent(this, clientService.getClass());
if (!isMyServiceRunning(clientService.getClass()))
startService(mServiceIntent); //somehow creates a new ClientService instance with null variables such as mainActivity, clientHandlder...
}
}
public ClientService(Context applicationContext, MainActivity mainActivity) {
super();
this.mainActivity = mainActivity;
client = mainActivity.getClient();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
client.addListener(new Listener(){ //FIXME client is null (a mainActivity would be null too)
@Override
public void connected(Connection connection) {
super.connected(connection);
}
@Override
public void disconnected(Connection connection) {
super.disconnected(connection);
}
@Override
public void received(Connection connection, Object o) {
Log.i("SERVICE", "Received: " + o.toString());
}
});
client.start();
Network.register(client);
return START_STICKY;
}
java.lang.RuntimeException: Unable to start service com.simplecodings.smma.tools.ClientService@b6efbc2 with Intent { cmp=com.simplecodings.smma/.tools.ClientService }: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.esotericsoftware.kryonet.Client.addListener(com.esotericsoftware.kryonet.Listener)' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3343)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1582)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.esotericsoftware.kryonet.Client.addListener(com.esotericsoftware.kryonet.Listener)' on a null object reference
at com.simplecodings.smma.tools.ClientService.onStartCommand(ClientService.java:50)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3326)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1582)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Can I, e.g. reference the client / mainActivity by passing them via .putExtra?
Read this and implement a bound service using the method "Extending the Binder class". The way you are trying to communicate between your Activity
and your Service
is incorrect.
Having a never-ending background service is also not possible. You might get away with using a foreground service. You should consider not monitoring your server in a Service
, but instead use push messages like Firebase Cloud Messaging to notify your app when something happens in your server.