如何保持对绑定服务的轮询?

时间:2016-04-08 12:45:56

标签: android android-service android-service-binding

我在互联网上查了一下,但找不到涵盖我的情景的例子。我想做的是:

  

1)我的活动开始后立即开始并绑定到服务 (已完成)

     

2)然后,服务将自己绑定到另一个寻找用户的服务   从连接的设备输入,并将字符串保存到变量(完成)

     

3)我想把这个字符串发回给活动,所以我可以查看它是什么   是基于它来进行网络呼叫。

现在排名第3)是我的挑战。我设法用一个运行一秒钟的Timer,然后检查服务中写入的值,但不知怎的,这似乎不是正确的方式,我认为可能有一个更成熟的解决方案。但是,我似乎无法弄明白。

我从文档中获取了代码并且只添加了计时器。在这个例子中只有一个服务只生成一个随机数(这通常会被我的第二个服务所取代)。 这是服务的代码:

public class LocalService extends Service {

    private final IBinder mBinder = new LocalBinder();

    private final Random mGenerator = new Random();

    public class LocalBinder extends Binder {
        LocalService getService() {
            return LocalService.this;
        }
    }

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

    public int getRandomNumber() {
        return mGenerator.nextInt(100);
    }
}

这是我活动中的代码:

public class MainActivity extends AppCompatActivity {

    LocalService mService;
    boolean mBound = false;
    Timer timer;

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

        timer = new Timer();
    }

    @Override
    protected void onStart() {
        super.onStart();
        Intent intent = new Intent(this, LocalService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

        timer.schedule(new MyTimerTask(new Handler(), this), 1000, 1000); // run on every second
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }

        timer.cancel();
        timer.purge();
    }

    private class MyTimerTask extends TimerTask {
        Handler handler;
        MainActivity ref;

        public MyTimerTask(Handler handler, MainActivity ref) {
            super();
            this.handler = handler;
            this.ref = ref;
        }

        @Override
        public void run() {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    if (mBound) {
                        int num = ref.mService.getRandomNumber();
                        // just as an example, raise a toast to see if it works
                        // but otherwise the value will be handled
                        Toast.makeText(ref, "number: " + num, Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                                       IBinder service) {
            LocalService.LocalBinder binder = (LocalService.LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
}

我的问题是:这是一种好的方法(它有效)还是不好又有什么选择?

2 个答案:

答案 0 :(得分:2)

  

我想将此字符串发送回活动,因此我可以检查它是什么,并根据它来进行网络通话。

使用LocalBroadcastManager,greenrobot的EventBus,Square的Otto或其他一些进程内事件总线实现。更改数据后引发事件。让活动在公交车上注册,了解活动情况。当更改发生时,让活动使用更改的数据。

  

这是一个很好的方法

没有

答案 1 :(得分:2)

您可以使用LocalBroadcastManagerService的广播发送到Activity。例如,在Service声明:

public static final String BROADCAST_INTENT = "broadcast_intent";
public static final String BROADCAST_VALUE = "broadcast_value";

private LocalBroadcastManager broadcastManager;

public void onCreate() {
    super.onCreate();

    broadcastManager = LocalBroadcastManager.getInstance(this);
}

现在,只要您想向String发送Activity,就可以这样做:

private void sendBroadcast(String value) {

    Intent intent = new Intent(BROADCAST_INTENT);
    intent.putExtra(BROADCAST_VALUE, value);
    broadcastManager.sendBroadcast(intent);
}

Activity声明BroadcastReceiver

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {

        handleIntent(intent);
    }
};

绑定到Service

时注册接收者
IntentFilter broadcastIntentFilter = new IntentFilter();
broadcastIntentFilter.addAction(StreamService.BROADCAST_INTENT);
LocalBroadcastManager.getInstance(context).registerReceiver((broadcastReceiver), broadcastIntentFilter);

取消注册您从Service

取消绑定的位置
LocalBroadcastManager.getInstance(context).unregisterReceiver(broadcastReceiver);

现在,当您的服务发送广播时,您可以在Activity

中处理
private void handleIntent(Intent intent) {

    if (intent.getAction().equals(StreamService.BROADCAST_INTENT)) {
        String value = intent.getStringExtra(StreamService.BROADCAST_VALUE, "default");
    }
}