2016-04-08 4 views
1

Я посмотрел в Интернете, но не смог найти пример, охватывающий мой сценарий. То, что я пытаюсь сделать, это:Как вести опрос связанного сервиса?

1) Для того, чтобы начать и подключаться к службе, как только моя деятельность начинается (сделано)

2) Служба затем связывает себя с другим сервисом ищет пользователя вход с подключенного устройства, и сохраняет строку, строку в переменной (сделано)

3) Я хотел бы, чтобы послать эту строку в деятельности, так что я могу проверить, что это это на основе которого выполняется сетевой вызов.

Теперь номер 3) является моей задачей. Мне удалось сделать это с помощью таймера, который работает в течение одной секунды, а затем проверяет значение, записанное в службе, но почему-то это не кажется правильным, и я думаю, что может быть более зрелое решение. Однако я не могу понять это.

Я взял код из документации и добавил только таймер. Это всего лишь одна услуга в этом примере, которая просто генерирует случайное число (это, как правило, будет заменено моей второй службой). Это код для службы:

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; 
     } 
    }; 
} 

Мой вопрос: является ли это хороший подход (он работает) или это плохо, и Какая альтернатива?

+0

у вас есть связанное обслуживание так Не используйте широковещательные приемники: у вас есть связанное соединение, просто передайте объект интерфейса в свою службу и позвольте службе позвонить ему где-нибудь – pskink

+0

@pskink Я не уверен, что w Вы хотите сказать, позвольте службе вызвать объект интерфейса? – Apostrofix

+0

в вашем 'LocalService' создать метод' register (ISomeInterface) ', и когда ваша активность связывается с вашей службой (внутри' onServiceConnected'), вызовите 'mService.register (MainActivity.this)', конечно, 'MainActivity' должен реализовать' ISomeInterface', таким образом, если вы вызываете 'register', ваша служба может хранить' ISomeInterface' в приватном поле и позже вызывать некоторые из его методов, если есть несколько клиентов, ваша служба может использовать 'List' из них или' android. класс os.RemoteCallbackList', который предназначен для такого случая – pskink

ответ

2

Вы можете использовать LocalBroadcastManager для отправки передач от вашего Service к вашему 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"); 
    } 
} 
+0

Это очень хороший пример! Только один вопрос: следует ли регистрировать и не регистрировать получателя в 'onServiceConnected' и' onServiceDisconnected', или это нормально делать в 'onStart' и' onStop'? – Apostrofix

+1

'onStop()' и 'onStart()' отлично! –

2

Я хотел бы отправить эту строку в действие, чтобы я мог проверить, что это такое и на ее основе сделать сетевой вызов.

Использовать LocalBroadcastManager, eventBus greenrobot, Square Otto или другую реализацию встроенных событий. Поднимите событие, когда вы изменили данные. Чтобы узнать о событии, зарегистрируйтесь на этом автобусе. Если это изменение произошло, используйте переменные данные.

это хороший подход

No.

 Смежные вопросы

  • Нет связанных вопросов^_^