如果服务在另一个进程中,如何绑定服务?

How to bind Service if it's in another process?

清单:

 <service android:name="com.example.MainService" android:process=":main_service"/>

正在尝试在 Activity 中绑定服务:

public class MainActivity extends Activity {
    MainService mMainService;

    private boolean mBound;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        bindService(intentForMainService, mConnection, Context.BIND_AUTO_CREATE)
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className,
                                       IBinder service) {
            MainService.MainServiceBinder binder = (MainService.MainServiceBinder) service;//HERE IS EXCEPTION
            mMainService = (MainService) binder.getService();
            mBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            mMainService = null;
            mBound = false;
        }
    };

    @Override
    protected void onStop() {
        doUnbindService();
        super.onStop();
    }

    void doUnbindService() {
        if (mBound) {
          unbindService(mConnection);
        }
    }
}

错误:

    FATAL EXCEPTION: main
 Process: com.hos.android, PID: 9001
   java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.example.service.main.MainService$MainServiceBinder
   at com.example.ui.base.BaseServiceActivity.onServiceConnected(MainActivity.java:34)
   at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1335)
   at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1352)
   at android.os.Handler.handleCallback(Handler.java:739)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:158)
   at android.app.ActivityThread.main(ActivityThread.java:7224)

但是当我删除这个 android:process=":main_service" 一切正常

第 1 步:编写 an AIDL file,描述客户端可以绑定到的服务要导出的接口。出于此答案的目的,我将调用此接口 Foo,因此 AIDL 文件将是 Foo.aidl。请注意,如果客户端和服务位于单独的 Android Studio 模块中,则两者都需要相同的 Foo.aidl 内容。

第 2 步:让您的服务的活页夹扩展 Foo.Stub 并覆盖 Foo.Stub 上的方法,而不是扩展 IBinder.

第 3 步:在您的客户端中,在 onServiceConnected() 中,通过 Foo.Stub.asInterface(service) 将原始绑定器转换为 Foo 实例,并且 Foo 具有客户端AIDL 定义的 API.

This pair of sample projects 说明了这一点,在我的例子中,客户端和服务位于不同的应用程序中。

我觉得你做就好了

首先创建Servic

public class MyService extends Service {

MyReceiver receiver = new MyReceiver();
@Override
public void onCreate() {
    super.onCreate();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    receiver.startAlarm(this);
    return START_STICKY;
}

@Override
public void onStart(Intent intent, int startId) {
    receiver.startAlarm(this);
}

}

启动闹钟后监听闹钟创建BroadcastReceiver

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, Intent intent) { 
        Log.e("Receiver", "end alarm")
    }
}


public void setAlarm(Context context) {
    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent i = new Intent(context, BootReceiver.class);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
    am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 10, pi); // Millisec * Second * Minute
}

public void cancelAlarm(Context context) {
    Intent intent = new Intent(context, BootReceiver.class);
    PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.cancel(sender);
}

添加清单

<service android:name=".MyService"
        android:enabled="true"
        android:process=":my_service"/>

    <receiver
        android:name="MyReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.parse.push.intent.RECEIVE" />
            <action android:name="com.parse.push.intent.DELETE" />
            <action android:name="com.parse.push.intent.OPEN" />
        </intent-filter>
    </receiver>