Binding few activities to one service - class whic

2019-08-13 16:19发布

问题:

I will start from my approach I want to have one service which is running even if none of application screen is visible for user. This service will scan for beacons. Every screen of application needs to get access to method of service so I used binding to service here. I designed serviceconnector class which will be connecting Activities with service, this class look like this.

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;



public class ServiceConnector {
    Context context;
    BeaconScanningService scanningService;
    boolean mBound = false;

    public ServiceConnector(Context context) {
        LogShower.printLogs("Service Connector created");
        this.context = context;
        createBinding();
    }

    public void createBinding()
    {
        Intent intent = new Intent(context, BeaconScanningService.class);

        if(scanningService.isBeaconScanningServiceRunning())
        {
            LogShower.printLogs("Service is already running.");
            context.bindService(intent, mConnection, 0);
        }
        else
        {
            LogShower.printLogs("Service is not running yet.");
            context.startService(new Intent(context, BeaconScanningService.class));
            context.bindService(intent, mConnection, 0);
        }
    }

    public void startScanning()
    {
        LogShower.printLogs("Start Scanning.");

        scanningService.startBeaconScanner();
    }

    public void stopScanning()
    {
        LogShower.printLogs("Stop Scanning.");

        scanningService.stopBeaconScanner();
    }

    public void destroyBinding()
    {
        if (mBound) {
            scanningService.unbindService(mConnection);
            mBound = false;
        }
    }



    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                                       IBinder service)
        {
            LogShower.printLogs("onServiceConnected");
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            BeaconScanningService.LocalBinder binder = (BeaconScanningService.LocalBinder) service;
            scanningService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            LogShower.printLogs("onServiceDisconnected");

            mBound = false;
        }
    };
}

This is activity when I make binding and try to unbind

import android.app.Activity;
import android.os.Bundle;

public class StartScreen extends Activity
{
    ServiceConnector serviceConnector ;


    @Override
    protected void onCreate (Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.starting_screen_layout);
        serviceConnector = new ServiceConnector(this);

    }

    @Override
    protected void onDestroy ()
    {
        serviceConnector.destroyBinding();
        super.onDestroy();
    }
}

Name of service is BeaconScanningService and this is my manifest

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.bka.tog.ole" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".ZooBeacon"
            android:label="@string/app_name" >

        </activity>
        <service android:enabled="true" android:name=".beaconeserviceandconnector.BeaconScanningService">

        </service>
        <activity
            android:name=".StartScreen"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

The problem is that I don't know why my ServiceConnector class is interprete as Service during unbinding process or just I can't make analysis of this logcat.

3405-3405/com.bka.tog.ole E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.bka.tog.ole, PID: 3405
java.lang.RuntimeException: Unable to destroy activity {com.bka.tog.ole/com.bka.tog.ole.StartScreen}: java.lang.IllegalArgumentException: Service not registered: com.bka.tog.ole.beaconeserviceandconnector.ServiceConnector$1@41d2f8d0
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3647)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3665)
        at android.app.ActivityThread.access$1400(ActivityThread.java:144)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1299)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5212)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.IllegalArgumentException: Service not registered: com.bka.tog.ole.beaconeserviceandconnector.ServiceConnector$1@41d2f8d0
        at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:973)
        at android.app.ContextImpl.unbindService(ContextImpl.java:1671)
        at android.content.ContextWrapper.unbindService(ContextWrapper.java:536)
        at com.bka.tog.ole.beaconeserviceandconnector.ServiceConnector.destroyBinding(ServiceConnector.java:59)
        at com.bka.tog.ole.StartScreen.onDestroy(StartScreen.java:27)
        at android.app.Activity.performDestroy(Activity.java:5412)
        at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1118)
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3634)
            at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3665)
            at android.app.ActivityThread.access$1400(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1299)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5212)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
            at dalvik.system.NativeStart.main(Native Method)

What is the reason of this behavior?

回答1:

In my ServiceConnector class should be:

context.unbindService(mConnection);

instead of this line:

scanningService.unbindService(mConnection);

I don't know how this misscoding come from, but I lost few hours, so be sure that you unbind from context of activity.

Normally i would delete this question, but one person make it favorite so I want to show what was the reason of my error.