I am using service to check the server state and notice user about it. It works fine until the app's activity destroyed. I keep the service even if activity destroyed but if fails each time. Any suggestions?
Service:
package com.vasil.wall.chss.MP;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.Binder;
import android.os.Handler;
import android.support.v4.app.NotificationCompat;
import android.os.Handler;
import java.util.TimerTask;
import java.util.Timer;
import org.peter.cucker.Single;
import android.util.Log;
import android.os.AsyncTask;
import com.vasil.wall.R;
public class OpponentService extends android.app.Service {
private boolean mRunning;//state
private static String service_tag = "MyService";
private NotificationManager nm;
private static final int NOTIFICATION_ID_CONNECTED = 0;
private final int requestPeriod = 4000;//20seconds
final Handler handler = new Handler();
private Timer timer = new Timer();
private TimerTask invitesListenerServiceTask;
private InvitesManager incomingIvitesManager = new InvitesManager();
public class LocalBinder extends Binder
{
public OpponentService getService()
{
return OpponentService.this;
}
}
private final IBinder mBinder = new LocalBinder();
@Override
public IBinder onBind(final Intent intent)
{
Log.d(service_tag, "onBindService");
return mBinder;
}
@Override
public boolean onUnbind(final Intent intent)
{
Log.d(service_tag, "onUnbindService");
return super.onUnbind(intent);
}
@Override
public void onCreate()
{
mRunning = false;
super.onCreate();
Log.d(service_tag, "onCreateService");
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId)
{
if (!mRunning) {
mRunning = true;
}
ii_listener_start(MPapi.getinstance().get_gameid( getApplicationContext() ));
return START_STICKY;
//return START_NOT_STICKY;
}
@Override
public void onDestroy()
{
mRunning = false;
ii_listener_cancel();
super.onDestroy();
Log.d(service_tag, "onDestroyService");
}
public void ii_listener_start(final int createdgame_id) {
invitesListenerServiceTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
incomingIvitesManager.get_invites_from_server(createdgame_id);
if ( !incomingIvitesManager.RES_GETINVITES.equals("") &&
!incomingIvitesManager.RES_GETINVITES.equals("invite") ) {
ii_listener_cancel();
restoreForeground(incomingIvitesManager.RES_GETINVITES);
//stopSelf();//stop service
}
else {}
}
});
}
};
timer.schedule(invitesListenerServiceTask, 0, requestPeriod);// execute in every 4s till success
}
public void ii_listener_cancel() {
//stopSelf();//stop service
if (invitesListenerServiceTask != null)
invitesListenerServiceTask.cancel();
}
public void restoreForeground(String player2) {
final NotificationCompat.Builder notification = new NotificationCompat.Builder(OpponentService.this);
notification.setSmallIcon(R.drawable.chess_notification);
notification.setContentTitle(getString(R.string.app_name));
notification.setContentText(getString(R.string.mp_opponent_ready, player2));
notification.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, Single.class), 0));
notification.setWhen(System.currentTimeMillis());
notification.setOngoing(true);
notification.setAutoCancel(true);
notification.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
nm.notify(NOTIFICATION_ID_CONNECTED, notification.getNotification());
}
}
log:
08-17 01:49:44.662: E/AndroidRuntime(10372): FATAL EXCEPTION: main
08-17 01:49:44.662: E/AndroidRuntime(10372): android.os.NetworkOnMainThreadException
08-17 01:49:44.662: E/AndroidRuntime(10372): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
08-17 01:49:44.662: E/AndroidRuntime(10372): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
08-17 01:49:44.662: E/AndroidRuntime(10372): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
08-17 01:49:44.662: E/AndroidRuntime(10372): at java.net.InetAddress.getAllByName(InetAddress.java:214) 08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
08-17 01:49:44.662: E/AndroidRuntime(10372): at com.vasil.wall.chss.HttpWorker.getJSONFromUrl(HttpWorker.java:173)
08-17 01:49:44.662: E/AndroidRuntime(10372): at com.vasil.wall.chss.MP.InvitesManager.get_invites_from_server(InvitesManager.java:82)
08-17 01:49:44.662: E/AndroidRuntime(10372): at com.vasil.wall.chss.MP.OpponentService$1$1.run(OpponentService.java:97)
08-17 01:49:44.662: E/AndroidRuntime(10372): at android.os.Handler.handleCallback(Handler.java:615)
08-17 01:49:44.662: E/AndroidRuntime(10372): at android.os.Handler.dispatchMessage(Handler.java:92)
08-17 01:49:44.662: E/AndroidRuntime(10372): at android.os.Looper.loop(Looper.java:137)
08-17 01:49:44.662: E/AndroidRuntime(10372): at android.app.ActivityThread.main(ActivityThread.java:4867)
08-17 01:49:44.662: E/AndroidRuntime(10372): at java.lang.reflect.Method.invokeNative(Native Method)
08-17 01:49:44.662: E/AndroidRuntime(10372): at java.lang.reflect.Method.invoke(Method.java:511)
08-17 01:49:44.662: E/AndroidRuntime(10372): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
08-17 01:49:44.662: E/AndroidRuntime(10372): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
08-17 01:49:44.662: E/AndroidRuntime(10372): at dalvik.system.NativeStart.main(Native Method)
The error is exactly as the exception says, you're doing network stuff on the main (UI) thread.
To understand why you need to know that new Handler()
binds to the thread on which it is created, which will presumably be the main thread since it is created during construction of the service.
This means the work done in the handler.post(..)
call will be executed on the main thread, causing the exception.
To fix the problem either use an AsyncTask or ensure the Handler is bound to a different Looper when it is created.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.