Jeet
Jeet

Reputation: 781

Service Connection leak

I have a very basic Service program, but I am getting this warning message

02-11 04:58:23.383: E/ActivityThread(1686): Activity com.example.serviceexample.Client has leaked ServiceConnection com.example.serviceexample.Client$1@416e56e8 that was originally bound here
02-11 04:58:23.383: E/ActivityThread(1686): android.app.ServiceConnectionLeaked: Activity com.example.serviceexample.Client has leaked ServiceConnection com.example.serviceexample.Client$1@416e56e8 that was originally bound here
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:974)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:868)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.ContextImpl.bindServiceAsUser(ContextImpl.java:1452)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.ContextImpl.bindService(ContextImpl.java:1440)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.content.ContextWrapper.bindService(ContextWrapper.java:496)
02-11 04:58:23.383: E/ActivityThread(1686):     at com.example.serviceexample.Client.onStart(Client.java:72)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.Activity.performStart(Activity.java:5143)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.os.Looper.loop(Looper.java:137)
02-11 04:58:23.383: E/ActivityThread(1686):     at android.app.ActivityThread.main(ActivityThread.java:5103)
02-11 04:58:23.383: E/ActivityThread(1686):     at java.lang.reflect.Method.invokeNative(Native Method)
02-11 04:58:23.383: E/ActivityThread(1686):     at java.lang.reflect.Method.invoke(Method.java:525)
02-11 04:58:23.383: E/ActivityThread(1686):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
02-11 04:58:23.383: E/ActivityThread(1686):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-11 04:58:23.383: E/ActivityThread(1686):     at dalvik.system.NativeStart.main(Native Method)

Code Part:

 public class Client extends Activity {
 boolean mBounded;
 Server mServer;
 TextView text;
 Button button;
 LocalBinder mLocalBinder;
 ServiceConnection mConnection = new ServiceConnection() {

  public void onServiceDisconnected(ComponentName name) {
   Toast.makeText(Client.this, "Service is disconnected", 1000).show();
   mBounded = false;
   mServer = null;
  }

  public void onServiceConnected(ComponentName name, IBinder service) {
   Toast.makeText(Client.this, "Service is connected", 1000).show();
   mBounded = true;
   LocalBinder mLocalBinder = (LocalBinder)service;
   mServer = mLocalBinder.getServerInstance();
  }
 };
 @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Toast.makeText(this, "onCreate Called", Toast.LENGTH_SHORT).show();
    setContentView(R.layout.activity_main);

    text = (TextView)findViewById(R.id.text);
    button = (Button) findViewById(R.id.button);
  mServer = new Server();
   // mServer = mLocalBinder.getServerInstance();
    try{
    button.setOnClickListener(new OnClickListener() {

  public void onClick(View v) {
     try{
   text.setText(mServer.getTime());
   }
      catch(Exception e)
      {e.printStackTrace();}
      }
  });
    }
    catch(Exception e)
    {e.printStackTrace();}
}

 @Override
 protected void onStart() {
  super.onStart();
 Toast.makeText(this, "onStart Called", Toast.LENGTH_SHORT).show();
  Intent mIntent = new Intent(this, Server.class);
    bindService(mIntent, mConnection,BIND_ADJUST_WITH_ACTIVITY);// BIND_AUTO_CREATE);// This is Line 72 
};



 @Override
 protected void onStop() {
 super.onStop();
  if(mBounded) {
  unbindService(mConnection);
  mBounded = false;
  Toast.makeText(this, "onStop Called", Toast.LENGTH_SHORT).show();
 }
}
 protected void onDestroy()
 {
 super.onDestroy();
 Toast.makeText(this, "onStop Called", Toast.LENGTH_SHORT).show();
 if(mBounded) {
       unbindService(mConnection);
       mBounded = false;
       Toast.makeText(this, "onStop Called", Toast.LENGTH_SHORT).show();
      }

   }
  }

Server Class :

public class Server extends Service{

IBinder mBinder = new LocalBinder();

@Override
public IBinder onBind(Intent intent) {
return mBinder;
}


public class LocalBinder extends Binder {
 public Server getServerInstance() {

 return Server.this;
  }
 }

public String getTime() {
SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return mDateFormat.format(new Date());
   }
 }

Please let me know what can I do to solve this logcat message. I can see that some issue on line 72. But I dont know how to solve it. Please help.

Upvotes: 3

Views: 1706

Answers (1)

Ranjit
Ranjit

Reputation: 5150

You have not unbind your service yet. Service Connection leak comes only when you forgot to stop or unbind service.

See your code..your mBounded is false when you try to unbind the service because you make it false in servicedisconnected method of serviceconnection interface which make obstacle to unbind your service.

see here what you did:

public void onServiceDisconnected(ComponentName name) {
Toast.makeText(Client.this, "Service is disconnected", 1000).show();
mBounded = false;//here you make false to the boolean variable which make obstacle to unbind your service
mServer = null; }

Delete mBounded = false; from here

You have to understand that connection disconnected() is differet than Service unbind().

you have to make it true when you bind your service. i.e:

Intent mIntent = new Intent(this, Server.class);
bindService(mIntent, mConnection,Context.BIND_AUTO_CREATE);
mBound = true;

And after unbind service make the boolean variable false not inside serviceconnection.like:

 if(mBound){
 unbindService(mConnection);
 mBounded = false;
 }

it will solve your problem..

Upvotes: 2

Related Questions