Activity与Service进行通信的三种方式
第一种 简单通信
直接通过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类中的两个方法onServiceConnected和onServiceDisconnected,这两个方法分别是在绑定成功和服务所在进程崩溃的时候被调用,如果绑定成功了,那么onServiceConnected(ComponentName componentName, IBinder iBinder) 就会被执行,然后第二个参数IBinder正是MyService中onBind()方法的返回值,因此我们可以通过这个返回值来想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对象来实现MyService中Callback的接口,由于 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"));
- }
- };
- }
在以上的代码中,按钮等控件可以自行添加