12

its failing @ below line -

bindService(intent, m_serviceConnection, Context.BIND_AUTO_CREATE);

Below is the trace....

Activity com.example.alwaysrunningprocesswithcallanswertap.MainActivity has leaked ServiceConnection com.example.alwaysrunningprocesswithcallanswertap.MainActivity$1@e794142 that was originally bound here
android.app.ServiceConnectionLeaked: Activity com.example.alwaysrunningprocesswithcallanswertap.MainActivity has leaked ServiceConnection com.example.alwaysrunningprocesswithcallanswertap.MainActivity$1@e794142 that was originally bound here
    at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1077)
    at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:971)
    at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1774)
    at android.app.ContextImpl.bindService(ContextImpl.java:1757)
    at android.content.ContextWrapper.bindService(ContextWrapper.java:539)
    at com.example.alwaysrunningprocesswithcallanswertap.MainActivity.onCreate(MainActivity.java:48)
    at android.app.Activity.performCreate(Activity.java:5990)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)   
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
    at android.app.ActivityThread.access$800(ActivityThread.java:151)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5257)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

MainActivity.class

public class MainActivity extends Activity 
{
    CallNotifierService m_service;
    boolean isBound = false;

    private ServiceConnection m_serviceConnection = new ServiceConnection() 
    {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) 
        {
            m_service = ((CallNotifierService.MyBinder)service).getService();
            Toast.makeText(MainActivity.this, "Service Connected", Toast.LENGTH_LONG).show();
            isBound = true;
            Intent intent = new Intent(MainActivity.this, CallNotifierService.class);
            startService(intent);
        }

        @Override
        public void onServiceDisconnected(ComponentName className) 
        {
            Toast.makeText(MainActivity.this, "Service Dis-connected", Toast.LENGTH_LONG).show();
            m_service = null;
            isBound = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(this, CallNotifierService.class);
        bindService(intent, m_serviceConnection, Context.BIND_AUTO_CREATE);
    }

    .
    .
    .

}
Bharat
  • 750
  • 1
  • 9
  • 20

3 Answers3

21

You need to add this in your code.

@Override
protected void onDestroy() {
    super.onDestroy();
    unbindService(m_serviceConnection);
    Toast.makeText(MainActivity.this, "Service Un-Binded", Toast.LENGTH_LONG).show();
};
Bharat
  • 750
  • 1
  • 9
  • 20
  • but what if we intent the service to be run continuously in background? – krishnamurthy May 24 '18 at 04:51
  • Don't use onDestroy in that case but check if Your service is already running in the onCreate method before You create the service again and again at Application start. Refer this: https://stackoverflow.com/questions/600207/how-to-check-if-a-service-is-running-on-android – Claudio Ferraro Aug 02 '18 at 21:04
0

Another good practice to do this could be adding a flag to know when the service was added.

private boolean m_serviceBound = false;
private ServiceConnection m_serviceConnection = new ServiceConnection() 
{
    ...
};


@Override
protected void onCreate(Bundle savedInstanceState) 
{
    ...
    Intent intent = new Intent(this, CallNotifierService.class);
    bindService(intent, m_serviceConnection, Context.BIND_AUTO_CREATE);
    m_serviceBound = true;
    ...
}

@Override
protected void onDestroy() {
    ...
    if (m_serviceBound) {
        unbindService(m_serviceConnection);
        m_serviceBound = false;
    }
    ...
};

This is useful if you bind and unbind the service in different segments of the app's life cycle.

Teocci
  • 7,189
  • 1
  • 50
  • 48
0

onStop()

is another place where you can unbind a service in your activity.

This approach is quite preferable when you want to interact with a service only when your Activity is in the foreground. See official Android Developer guide suggestion

Override
protected void onStop() {
   super.onStop();
   unbindService(m_serviceConnection);
};

In this case, prefered way to bind service is in the onStart() method of the Activity.

Community
  • 1
  • 1
Rohit Singh
  • 16,950
  • 7
  • 90
  • 88