Android中Service通信(二)——绑定Service进行通信

一、把输入文本的数据同步到服务的实例(如何执行服务的内部代码)

  绑定服务比启动服务更加方便高效,绑定服务中的直接方法调用比Intent作为载体传输更为快捷得多。

1、activity_main.xml

  <Button
    android:text="绑定服务"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/btnBindService" />
  <Button
    android:text="解除绑定服务"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/btnUnbindService" />
  <Button
    android:text="同步数据"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/btnSyncData" />

2、MainActivity.java

  private MyService.Binder binder = null;

  findViewById(R.id.btnBindService).setOnClickListener(this);
  findViewById(R.id.btnUnbindService).setOnClickListener(this);
  findViewById(R.id.btnSyncData).setOnClickListener(this);

  case R.id.btnBindService:
    bindService(new Intent(this,MyService.class),this,Context.BIND_AUTO_CREATE);
    break;
  case R.id.btnUnbindService:
    unbindService(this);
  break;
  case R.id.btnSyncData:
    if (binder != null) {
      binder.setData(editText.getText().toString());
    }
  break;

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
    binder = (MyService.Binder)service;
  }

  @Override
  public void onServiceDisconnected(ComponentName name) {  }

3、MyService.java

  public IBinder onBind(Intent intent) {
    return new Binder();
  }

  public class Binder extends android.os.Binder{
    public void setData(String data){
      MyService.this.data = data;

    }
  }

二、内部信息呈现到外界的实例(如何侦听服务的内部状态

1、activity_main.xml

  <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tvOut"/>

2、MainActivity.java

  private TextView textView;

  textView = (TextView) findViewById(R.id.tvOut);

  public void onServiceConnected(ComponentName name, IBinder service) {
    binder = (MyService.Binder)service;
    binder.getService().setCallback(new MyService.Callback(){
      @Override
      public void onDataChange(String data) {
        //textView.setText(data);  //错误用法。程序由新创建的线程调用,不允许其他辅线程来直接获取UI线程(主线程)的资源。
        Message msg = new Message();
        Bundle b = new Bundle();
        b.putString("data",data);
        msg.setData(b);
        handler.sendMessage(msg);
      }
    });
  }

  private Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      textView.setText(msg.getData().getString("data"));
    }
  };

3、MyService.java

  public class Binder extends android.os.Binder{
    public void setData(String data){
      MyService.this.data = data;
    }
    public MyService getService(){
      return MyService.this;
    }
  }

  public void onCreate() {
    super.onCreate();
    running = true;
    new Thread(){
    @Override
    public void run() {
      super.run();
      int i = 0 ;
      while(running){
        i++;
        String str = i+":"+data;
        System.out.println(str);
        if(callback != null){
          callback.onDataChange(str);
        }
         try {
            sleep(1000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }.start();
  }

  private Callback callback = null;

  public void setCallback(Callback callback) {
    this.callback = callback;
  }
  public Callback getCallback() {
    return callback;
  }
  //内部通知外界:回调机制
  public static interface Callback{
    void onDataChange(String data);
  }

 

posted @ 2016-12-23 16:55  Sheldon_wz  阅读(199)  评论(0编辑  收藏  举报