Android学习之Activity与Service进行通信的三种方式

ActivityService进行通信的三种方式

第一种 简单通信

直接通过Intent进行传值,我们在启动一个Service的时候通过Intent的对象向Service进行传值,这种方式传递值比较不方便,性能不是很高。

(1)在MainActivity中通过启动服务和终止服务的按钮分别调用startService(intent)和stopService(intent)来启动和停止服务

MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {
    private Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(MainActivity.this, MyService.class);

        findViewById(R.id.btyStartService).setOnClickListener(this);
        findViewById(R.id.btyStopService).setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btyStartService://启动服务
                intent.putExtra("data", editText.getText().toString());
                startService(intent);
                break;
            case R.id.btyStopService://终止服务
                stopService(intent);
                break;
           
        }
    }
   }


2)在Myservice中,我们通过onStartCommand(finalIntent intent, int flags, intstartId)这个函数来接收从Activity传过来的值

Myservice

public class MyService extends Service {
    private Boolean myflags = false;
    private String data = "服务器正在执行";
    private static final String TAG = "ActivityTest";
    private Callback callback;
    public MyService() {
    }

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

    @Override
    public void onCreate() {
        super.onCreate();
        myflags = true;
        new Thread(){
            @Override
            public void run() {
                super.run();
                while(myflags){
                    try {
                        String str = data;
                        Log.d(TAG, str);
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();
                    }
                }
                Log.d(TAG, "服务器已停止");
            }

        }.start();
    }

    @Override
    public int onStartCommand(final Intent intent, int flags, int startId) {
        data = intent.getStringExtra("data");
        return super.onStartCommand(intent, flags, startId);
    }
}


第二种

我们在绑定服务的时候,首先要做的就是让我们的MainActivity实现ServiceConnection类,实现这个类之后,我们还需要重写ServiceConnection类中的两个方法onServiceConnectedonServiceDisconnected,这两个方法分别是在绑定成功和服务所在进程崩溃的时候被调用,如果绑定成功了,那么onServiceConnected(ComponentName componentName, IBinder iBinder) 就会被执行,然后第二个参数IBinder正是MyServiceonBind()方法的返回值,因此我们可以通过这个返回值来想MyService传递数据。

public IBinder onBind(Intent intent) {
        Log.d(TAG, "服务器已绑定");
       return new Binder();
}



(1)MyService 中我们创建一个Binder类,让其实现android.os.Binder类,并且定义一个方法setData,然后我们通过onBind()方法将其对象返回MainActivity。

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

MyService

public class MyService extends Service {
    private Boolean myflags = false;
    private String data = "服务器正在执行";
    private static final String TAG = "ActivityTest";
    private Callback callback;
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "服务器已绑定");
       return new Binder();
    }

    public class Binder extends android.os.Binder{
        public void setData(String data){
            MyService.this.data = data;
        }
    }
    @Override
    public void onCreate() {
        super.onCreate();
        myflags = true;
        new Thread(){
            @Override
            public void run() {
                super.run();
                while(myflags){
                    //System.out.println("程序正在运行.....");
                    try {
                        String str = data;
                        Log.d(TAG, str);
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();
                    }
                }
                Log.d(TAG, "服务器已停止");
            }

        }.start();
    }

    @Override
    public int onStartCommand(final Intent intent, int flags, int startId) {
        data = intent.getStringExtra("data");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        myflags = false;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

}

2)在MainActivity中,首先添加一个Binder对象,然后在ServiceConnection中获取MyService中返回的Binder对象,接着我们通过Binder对象调用它的方法setData向其传递数据

MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {

    private Intent intent;
    private EditText editText;
    private TextView textView;
    private MyService.Binder myBinder = null;//①

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(MainActivity.this, MyService.class);
        editText = (EditText) findViewById(R.id.editText);
        textView = (TextView) findViewById(R.id.textView);

        findViewById(R.id.btyStartService).setOnClickListener(this);
        findViewById(R.id.btyStopService).setOnClickListener(this);
        findViewById(R.id.btyBindService).setOnClickListener(this);
        findViewById(R.id.btyUnbindService).setOnClickListener(this);
        findViewById(R.id.btySend).setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btyStartService://启动服务
                intent.putExtra("data", editText.getText().toString());
                startService(intent);
                break;
            case R.id.btyStopService://终止服务
                stopService(intent);
                break;
            case R.id.btyBindService://绑定服务
                bindService(intent, this, Context.BIND_AUTO_CREATE);
                break;
            case R.id.btyUnbindService://解除绑定
                unbindService(this);
                break;
            case R.id.btySend://想MyService传递数据
                if (myBinder != null) {
                    myBinder.setData(editText.getText().toString());//③
                }
                break;
        }
    }
    //一旦绑定成功就会执行该函数
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        myBinder = (MyService.Binder) iBinder;//②
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {

    }

}


第三种,监听服务中的进程的变化

MyService

(1)添加一个公开的接口Callback

public static interface Callback{
    	void onDataChange(String data);
    }

(2)在MyService内部添加一个变量

private Callback callback;
public void setCallback(Callback callback) {
    this.callback = callback;
}

public Callback getCallback() {
    return callback;
}

(3)向外界派发信息

if (callback != null){
    callback.onDataChange(str);
}

(4)在Binder中返回一个当前的MyService对象,然外部可以添加事件的绑定

public MyService getMyService(){
    return MyService.this;
}

MyService

public class MyService extends Service {
    private Boolean myflags = false;
    private String data = "服务器正在执行";
    private static final String TAG = "ActivityTest";
    private Callback callback;
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "服务器已绑定");
       return new Binder();
    }

    public class Binder extends android.os.Binder{
        public void setData(String data){
            MyService.this.data = data;
        }
        public MyService getMyService(){
            return MyService.this;
        }
    }
    @Override
    public void onCreate() {
        super.onCreate();
        myflags = true;
        new Thread(){
            @Override
            public void run() {
                super.run();
                int i =1;
                while(myflags){
                    //System.out.println("程序正在运行.....");
                    try {
                        String str = i + ":" +data;
                        Log.d(TAG, str);
                        if (callback != null){
                            callback.onDataChange(str);
                        }
                        sleep(1000);
                        i++;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();
                    }
                }
                Log.d(TAG, "服务器已停止");
            }

        }.start();
    }

    @Override
    public int onStartCommand(final Intent intent, int flags, int startId) {
        data = intent.getStringExtra("data");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        myflags = false;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    public Callback getCallback() {
        return callback;
    }

    public static interface Callback{
        void onDataChange(String data);
    }
}

MainActivity中我们可以通过onServiceConnected方法中的iBinder对象来实现MyServiceCallback的接口,由于 onDataChange() 是执行在子线程中的,因此我们需要再定义一个Hander对象,将任务由子线程切换到主线程中,让主线程来进行 UI 操作。

//①
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    myBinder = (MyService.Binder) iBinder;
    myBinder.getMyService().setCallback(new MyService.Callback(){
        @Override
        public void onDataChange(String data) {
            Message msg = new Message();
            Bundle b = new Bundle();
            b.putString("data",data);
            msg.setData(b);
            hander.sendMessage(msg);
        }
    });
}

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

MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {

    private Intent intent;
    private EditText editText;
    private TextView textView;
    private MyService.Binder myBinder = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(MainActivity.this, MyService.class);
        editText = (EditText) findViewById(R.id.editText);
        textView = (TextView) findViewById(R.id.textView);

        findViewById(R.id.btyStartService).setOnClickListener(this);
        findViewById(R.id.btyStopService).setOnClickListener(this);
        findViewById(R.id.btyBindService).setOnClickListener(this);
        findViewById(R.id.btyUnbindService).setOnClickListener(this);
        findViewById(R.id.btySend).setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btyStartService:
                intent.putExtra("data", editText.getText().toString());
                startService(intent);
                break;
            case R.id.btyStopService:
                stopService(intent);
                break;
            case R.id.btyBindService:
                bindService(intent, this, Context.BIND_AUTO_CREATE);
                break;
            case R.id.btyUnbindService:
                unbindService(this);
                break;
            case R.id.btySend:
                if (myBinder != null) {
                    myBinder.setData(editText.getText().toString());
                }
                break;
        }
    }
    //一旦绑定成功就会执行该函数
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        myBinder = (MyService.Binder) iBinder;
        myBinder.getMyService().setCallback(new MyService.Callback(){
            @Override
            public void onDataChange(String data) {
                Message msg = new Message();
                Bundle b = new Bundle();
                b.putString("data",data);
                msg.setData(b);
                hander.sendMessage(msg);
            }
        });
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
       
    }

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


在以上的代码中,按钮等控件可以自行添加




你可能感兴趣的:(java,Android)