即使在未绑定和停止之后,也可以在Activity中访问绑定的服务方法

时间:2018-05-19 09:47:52

标签: android android-service

考虑这个序列:

startService > bindService > getRandomNumber > unbindService > stopService > getRandomNumber

根据我的理解,在我通过活动取消绑定服务之后,我不应该能够访问服务中的方法,但是我仍然可以在取消绑定之后甚至在停止服务之后访问它们。

对此行为的任何解释?

我使用了BIND_AUTO_CREATE标志,仍然可以访问的方法是一个简单的随机数生成器方法,它不依赖于任何其他对象。

这是我的活动:

public class MainActivity extends AppCompatActivity {

private TextView textView;
private Intent serviceIntent;
private MyService.MyServiceBinder myServiceBinder;
ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        myServiceBinder = ((MyService.MyServiceBinder) service);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textView = findViewById(R.id.threadUpdate);
    serviceIntent = new Intent(this, MyService.class);
}

public void startService(View view) {
    startService(serviceIntent);

}

public void stopService(View view) {
    stopService(serviceIntent);
}

public void getRandomNumber(View view) {
    String str = "Is binder alive :" + myServiceBinder.isBinderAlive() 
            + "\n" + "ServiceConnection :" + connection + "\n"
            + "getRandomNum :" + myServiceBinder.getRandomNumber();

    textView.setText(str);
}

public void bindService(View view) {
    bindService(serviceIntent, connection, BIND_AUTO_CREATE);
}

public void unBindService(View view) {
    unbindService(connection);
}
}

这是我的服务:

public class MyService extends Service {
private static final String TAG = "FromMyService";

public MyService() {
}

@Override
public IBinder onBind(Intent intent) {
    Log.d(TAG, "Service bound");
    return new MyServiceBinder();
}

public class MyServiceBinder extends Binder {
    public int getRandomNumber() {
        Log.d(TAG, "Service getRandomNumber");
        return MyService.this.getRandomNumber();
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "Service Started");
    return Service.START_STICKY;
}

public int getRandomNumber() {
    Log.d(TAG, "Service getRandomNumber");
    return (int) (Math.random() * 100);
}

@Override
public void onRebind(Intent intent) {
    super.onRebind(intent);
    Log.d(TAG, "Service reBound");
}

@Override
public boolean onUnbind(Intent intent) {
    Log.d(TAG, "Service unBound");
    return super.onUnbind(intent);
}

@Override
public void onDestroy() {
    Log.d(TAG, "Service Destroyed");
    super.onDestroy();
}
}

这是日志输出:

    05-19 17:28:29.488 28077-28077/com.thnki.learning D/FromMyService:
    Service Started
    05-19 17:28:32.230 28077-28077/com.thnki.learning D/FromMyService: Service bound
    05-19 17:28:33.966 28077-28077/com.thnki.learning D/FromMyService: Service getRandomNumber
    Service getRandomNumber
    05-19 17:28:40.094 28077-28077/com.thnki.learning D/FromMyService: Service unBound
    05-19 17:28:42.818 28077-28077/com.thnki.learning D/FromMyService: Service Destroyed
    05-19 17:28:44.368 28077-28077/com.thnki.learning D/FromMyService: Service getRandomNumber
    Service getRandomNumber
    05-19 17:28:46.522 28077-28077/com.thnki.learning D/FromMyService: Service getRandomNumber
    Service getRandomNumber

1 个答案:

答案 0 :(得分:1)

有界和开始是两种不同类型的Service。 您可以创建既启动又绑定的服务。也就是说,您可以通过调用startService()来启动服务,该服务允许服务无限期运行,您还可以通过调用bindService()来允许客户端绑定到服务。

您正在执行以下操作: -

 startService > bindService > unbindService > stopService

Service已启动以Activity为界的服务。因此,当Unbind系统未停止Service时,您必须通过致电stopSelf()stopService()明确停止服务。

PS: - 如果Service正在为某些SActivity服务,那么只需将其设置为startService,在这种情况下,Service将在最后一次解除绑定后自动降级。

  

请注意,如果已停止的服务仍然具有与BIND_AUTO_CREATE集绑定的ServiceConnection对象,则在删除所有这些绑定之前不会销毁它。有关服务生命周期的更多详细信息,请参阅Service documentation

编辑 - 在您的情况下,服务在解除绑定后不再运行。您只能调用该方法,因为您引用Binder并不意味着它正在运行。请记住ServiceComponent  要测试它,您可以在每个阶段调用下面的方法。

private boolean isServiceRunning(Class<?> className) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (className.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}



if(isServiceRunning(MyService.class)){
                Log.e("Service","Running");
            }else{
                Log.e("Service","NotRunning");
            }

unbindService() official definition says

  

断开与应用程序服务的连接。服务重新启动后,您将不再接听电话,现在可以随时停止服务。