Service与Activity通信:Binder

Activity与 Service通信:
1.通过BroadCastReceiver:这种方式是最简单的,只能用来交换简单的数据;
2.通过Messager:这种方式是通过一个传递一个Messager给对方,通过这个它来发送Message对象。这种方式只能单向传递数据。可以是Service到Activity,也可以是从Activity发送数据给Service。一个Messeger不能同时双向发送;
3.通过Binder来实现远程调用(IPC):这种方式是Android的最大特色之一,让你调用远程Service的接口,就像调用本地对象一样,实现非常灵活,写起来也相对复杂。
怎样在启动一个Service时向它传递数据,关键点:Intent传值,onStartCommand()接收。
binder流程如下:
1、在Service子类创建 binder子类,返回当前服务的this对象。让前端能够通过 binder 类实现对 service 的调用。
2、service 中的 onbinder方法返回 binder 实例。
3、在前端中的 onserviceconnected 中接收返回的 binder 实例。通过binder 实例获得服务的this对,通过对象调用公共方法,实现通信。

Service:
package com.example.chengwenbo.myservce;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

private static final String TAG = "MyService";
/**
 * 一般开发的时候 都会在你自己写的方法里面或者自己叫不准的位置加一句Log,以备在跑程序的时候能准确找到错误点,
 一般的格式是 Log.v(TAG,"你想备注的名字");
 Log.e或Log.v或Log.d或Log.i
 这时候就要补这一句,MainActivity是该文件名
 */

private LocalBinder mbinder = new LocalBinder();

/**
 * //在服务里面新建一个内部类LocalBinder
 //LocalBinder新增了两个自己的方法binderFun1(),binderFun2()
 //LocalBinder的getService()返回当前服务的this对象
 /**
 *在onBinder方法中返回LocalBinder对象,回LocalBinder对象包含了service的句柄,
 *客户端通过句柄就可以调用servcie的公共方法funLocalService()了.
 */

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    //throw new UnsupportedOperationException("Not yet implemented");
    return mbinder;//只有绑定时才返回binder对象
}


public class LocalBinder extends Binder{
    public MyService getservices(){//返回当前服务的this对象
        return MyService.this;
    }
    public String fun1(){
        return "fun1";
    }
    public String fun2(){
        return "fun2";
    }
}

 @Override
 public void onCreate(){
     super.onCreate();
     /*
     serviceRunning = true;
     new Thread() {
         @Override
         public void run() {
             int n = 0;
             while (serviceRunning) {
                 n++;
                 String str = n + data;
                 System.out.println(str);
                 if (dataCallback != null) {
                     dataCallback.dataChanged(str);
                 }
                 try {
                     sleep(1000);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
         };
     }.start();
     */
 }

 // 每次启动Servcie时都会调用该方法
 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
    //System.out.println("--onStartCommand()--");
    //data = intent.getStringExtra("data");
    return super.onStartCommand(intent, flags, startId);
 }

 // 解绑Servcie调用该方法
@Override
public boolean onUnbind(Intent intent) {
    //System.out.println("--onUnbind()--");
    return super.onUnbind(intent);
}

// 退出或者销毁时调用该方法
@Override
public void onDestroy() {
    //serviceRunning = false;
    //System.out.println("--onDestroy()--");
    super.onDestroy();
}

//公共方法,通过getservices()返回的服务建立的对象调用,实现通信
public String myway(){

    return "hello world";
}

}

Activity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

private MyService mMyService;
private ServiceConnection mConnection;
private MyService.LocalBinder binder;

private Button bt1,bt2,bt3,bt4;

private static final String TAG = "MainActivity";

private String st1 = "1";
private String st2 = "2";
private String st3 = "3";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    bt1 = findViewById(R.id.btn_start);
    bt2 = findViewById(R.id.btn_stop);
    bt3 = findViewById(R.id.btn_bind);
    bt4 = findViewById(R.id.btn_unbind);

    bt1.setOnClickListener(this);
    bt2.setOnClickListener(this);
    bt3.setOnClickListener(this);
    bt4.setOnClickListener(this);

    //绑定开启的时候调用。
    mConnection = new ServiceConnection(){
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //调用LocalBinder自己的方法
            binder = (MyService.LocalBinder) iBinder;
            st2 = binder.fun1();
            st3 = binder.fun2();
            //client得到服务LocalService的句柄,便可以调用服务里面声明的public方法funLocalService()
            mMyService = binder.getservices();
            st1 = mMyService.myway();
        }
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mMyService = null;
            Log.e(TAG, "onServiceDisconnected:");
        }
    };
}
/**
 * 里面主要是为了实现一个可以从service的回调接口
 */
@Override
public void onClick(View v){
    switch (v.getId()){
        case R.id.btn_start:
            Intent start = new Intent(this,MyService.class);
            startService(start);
            Toast.makeText(this,"s-"+st1+"-"+st2 + "-"+st3,Toast.LENGTH_SHORT).show();
            break;
        case R.id.btn_stop:
            Intent stop = new Intent(this,MyService.class);
            stopService(stop);
            Toast.makeText(this,"st"+st1+"-"+st2 + "-"+st3,Toast.LENGTH_SHORT).show();
            break;
        case R.id.btn_bind:
            Intent bind = new Intent(this,MyService.class);
            bindService(bind,mConnection, Service.BIND_AUTO_CREATE);
            /**
             * bindService是异步调用和Service进行绑定, 如果绑定成功,
             * 则会调用ServiceConnection的onServiceConnected
             * 当调用bindService方法后就会回调Activity的onServiceConnected,
             * 在这个方法中会向Activity中传递一个IBinder的实例,Acitity需要保存这个实例
             */
            Toast.makeText(this,"b"+st1+"-"+st2 + "-"+st3,Toast.LENGTH_SHORT).show();
            break;
        case R.id.btn_unbind:
            //Intent unbind = new Intent(this,MyService.class);
            unbindService(mConnection);
            Toast.makeText(this,"ub"+st1+"-"+st2 + "-"+st3,Toast.LENGTH_SHORT).show();
            break;
            default:
                break;
    }
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值