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

来源:互联网 发布:外包美工加班多吗 编辑:程序博客网 时间:2024/05/22 03:46

ActivityService进行通信的三种方式

第一种 简单通信

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

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

MainActivity

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {  
  2.     private Intent intent;  
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.         intent = new Intent(MainActivity.this, MyService.class);  
  8.   
  9.         findViewById(R.id.btyStartService).setOnClickListener(this);  
  10.         findViewById(R.id.btyStopService).setOnClickListener(this);  
  11.   
  12.     }  
  13.   
  14.     @Override  
  15.     public void onClick(View view) {  
  16.         switch (view.getId()) {  
  17.             case R.id.btyStartService://启动服务  
  18.                 intent.putExtra("data", editText.getText().toString());  
  19.                 startService(intent);  
  20.                 break;  
  21.             case R.id.btyStopService://终止服务  
  22.                 stopService(intent);  
  23.                 break;  
  24.              
  25.         }  
  26.     }  
  27.    }  


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

Myservice

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class MyService extends Service {  
  2.     private Boolean myflags = false;  
  3.     private String data = "服务器正在执行";  
  4.     private static final String TAG = "ActivityTest";  
  5.     private Callback callback;  
  6.     public MyService() {  
  7.     }  
  8.   
  9.     @Override  
  10.     public IBinder onBind(Intent intent) {  
  11.               return new Binder();  
  12.     }  
  13.   
  14.     @Override  
  15.     public void onCreate() {  
  16.         super.onCreate();  
  17.         myflags = true;  
  18.         new Thread(){  
  19.             @Override  
  20.             public void run() {  
  21.                 super.run();  
  22.                 while(myflags){  
  23.                     try {  
  24.                         String str = data;  
  25.                         Log.d(TAG, str);  
  26.                         sleep(1000);  
  27.                     } catch (InterruptedException e) {  
  28.                         e.printStackTrace();  
  29.                         Toast.makeText(MyService.this"出错了", Toast.LENGTH_SHORT).show();  
  30.                     }  
  31.                 }  
  32.                 Log.d(TAG, "服务器已停止");  
  33.             }  
  34.   
  35.         }.start();  
  36.     }  
  37.   
  38.     @Override  
  39.     public int onStartCommand(final Intent intent, int flags, int startId) {  
  40.         data = intent.getStringExtra("data");  
  41.         return super.onStartCommand(intent, flags, startId);  
  42.     }  
  43. }  


第二种

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

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public IBinder onBind(Intent intent) {  
  2.         Log.d(TAG, "服务器已绑定");  
  3.        return new Binder();  
  4. }  



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

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class Binder extends android.os.Binder{  
  2.         public void setData(String data){  
  3.             MyService.this.data = data;  
  4.         }  
  5.     }  

MyService

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class MyService extends Service {  
  2.     private Boolean myflags = false;  
  3.     private String data = "服务器正在执行";  
  4.     private static final String TAG = "ActivityTest";  
  5.     private Callback callback;  
  6.     public MyService() {  
  7.     }  
  8.   
  9.     @Override  
  10.     public IBinder onBind(Intent intent) {  
  11.         Log.d(TAG, "服务器已绑定");  
  12.        return new Binder();  
  13.     }  
  14.   
  15.     public class Binder extends android.os.Binder{  
  16.         public void setData(String data){  
  17.             MyService.this.data = data;  
  18.         }  
  19.     }  
  20.     @Override  
  21.     public void onCreate() {  
  22.         super.onCreate();  
  23.         myflags = true;  
  24.         new Thread(){  
  25.             @Override  
  26.             public void run() {  
  27.                 super.run();  
  28.                 while(myflags){  
  29.                     //System.out.println("程序正在运行.....");  
  30.                     try {  
  31.                         String str = data;  
  32.                         Log.d(TAG, str);  
  33.                         sleep(1000);  
  34.                     } catch (InterruptedException e) {  
  35.                         e.printStackTrace();  
  36.                         Toast.makeText(MyService.this"出错了", Toast.LENGTH_SHORT).show();  
  37.                     }  
  38.                 }  
  39.                 Log.d(TAG, "服务器已停止");  
  40.             }  
  41.   
  42.         }.start();  
  43.     }  
  44.   
  45.     @Override  
  46.     public int onStartCommand(final Intent intent, int flags, int startId) {  
  47.         data = intent.getStringExtra("data");  
  48.         return super.onStartCommand(intent, flags, startId);  
  49.     }  
  50.     @Override  
  51.     public void onDestroy() {  
  52.         super.onDestroy();  
  53.         myflags = false;  
  54.     }  
  55.     @Override  
  56.     public boolean onUnbind(Intent intent) {  
  57.         return super.onUnbind(intent);  
  58.     }  
  59.   
  60. }  

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

MainActivity

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {  
  2.   
  3.     private Intent intent;  
  4.     private EditText editText;  
  5.     private TextView textView;  
  6.     private MyService.Binder myBinder = null;//①  
  7.   
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.activity_main);  
  12.         intent = new Intent(MainActivity.this, MyService.class);  
  13.         editText = (EditText) findViewById(R.id.editText);  
  14.         textView = (TextView) findViewById(R.id.textView);  
  15.   
  16.         findViewById(R.id.btyStartService).setOnClickListener(this);  
  17.         findViewById(R.id.btyStopService).setOnClickListener(this);  
  18.         findViewById(R.id.btyBindService).setOnClickListener(this);  
  19.         findViewById(R.id.btyUnbindService).setOnClickListener(this);  
  20.         findViewById(R.id.btySend).setOnClickListener(this);  
  21.   
  22.     }  
  23.   
  24.     @Override  
  25.     public void onClick(View view) {  
  26.         switch (view.getId()) {  
  27.             case R.id.btyStartService://启动服务  
  28.                 intent.putExtra("data", editText.getText().toString());  
  29.                 startService(intent);  
  30.                 break;  
  31.             case R.id.btyStopService://终止服务  
  32.                 stopService(intent);  
  33.                 break;  
  34.             case R.id.btyBindService://绑定服务  
  35.                 bindService(intent, this, Context.BIND_AUTO_CREATE);  
  36.                 break;  
  37.             case R.id.btyUnbindService://解除绑定  
  38.                 unbindService(this);  
  39.                 break;  
  40.             case R.id.btySend://想MyService传递数据  
  41.                 if (myBinder != null) {  
  42.                     myBinder.setData(editText.getText().toString());//③  
  43.                 }  
  44.                 break;  
  45.         }  
  46.     }  
  47.     //一旦绑定成功就会执行该函数  
  48.     @Override  
  49.     public void onServiceConnected(ComponentName componentName, IBinder iBinder) {  
  50.         myBinder = (MyService.Binder) iBinder;//②  
  51.     }  
  52.   
  53.     @Override  
  54.     public void onServiceDisconnected(ComponentName componentName) {  
  55.   
  56.     }  
  57.   
  58. }  


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

MyService

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

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public static interface Callback{  
  2.         void onDataChange(String data);  
  3.     }  

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

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. private Callback callback;  
  2. public void setCallback(Callback callback) {  
  3.     this.callback = callback;  
  4. }  
  5.   
  6. public Callback getCallback() {  
  7.     return callback;  
  8. }  

(3)向外界派发信息

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. if (callback != null){  
  2.     callback.onDataChange(str);  
  3. }  

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

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public MyService getMyService(){  
  2.     return MyService.this;  
  3. }  

MyService

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class MyService extends Service {  
  2.     private Boolean myflags = false;  
  3.     private String data = "服务器正在执行";  
  4.     private static final String TAG = "ActivityTest";  
  5.     private Callback callback;  
  6.     public MyService() {  
  7.     }  
  8.   
  9.     @Override  
  10.     public IBinder onBind(Intent intent) {  
  11.         Log.d(TAG, "服务器已绑定");  
  12.        return new Binder();  
  13.     }  
  14.   
  15.     public class Binder extends android.os.Binder{  
  16.         public void setData(String data){  
  17.             MyService.this.data = data;  
  18.         }  
  19.         public MyService getMyService(){  
  20.             return MyService.this;  
  21.         }  
  22.     }  
  23.     @Override  
  24.     public void onCreate() {  
  25.         super.onCreate();  
  26.         myflags = true;  
  27.         new Thread(){  
  28.             @Override  
  29.             public void run() {  
  30.                 super.run();  
  31.                 int i =1;  
  32.                 while(myflags){  
  33.                     //System.out.println("程序正在运行.....");  
  34.                     try {  
  35.                         String str = i + ":" +data;  
  36.                         Log.d(TAG, str);  
  37.                         if (callback != null){  
  38.                             callback.onDataChange(str);  
  39.                         }  
  40.                         sleep(1000);  
  41.                         i++;  
  42.                     } catch (InterruptedException e) {  
  43.                         e.printStackTrace();  
  44.                         Toast.makeText(MyService.this"出错了", Toast.LENGTH_SHORT).show();  
  45.                     }  
  46.                 }  
  47.                 Log.d(TAG, "服务器已停止");  
  48.             }  
  49.   
  50.         }.start();  
  51.     }  
  52.   
  53.     @Override  
  54.     public int onStartCommand(final Intent intent, int flags, int startId) {  
  55.         data = intent.getStringExtra("data");  
  56.         return super.onStartCommand(intent, flags, startId);  
  57.     }  
  58.   
  59.     @Override  
  60.     public void onDestroy() {  
  61.         super.onDestroy();  
  62.         myflags = false;  
  63.     }  
  64.   
  65.     @Override  
  66.     public boolean onUnbind(Intent intent) {  
  67.         return super.onUnbind(intent);  
  68.     }  
  69.   
  70.     public void setCallback(Callback callback) {  
  71.         this.callback = callback;  
  72.     }  
  73.   
  74.     public Callback getCallback() {  
  75.         return callback;  
  76.     }  
  77.   
  78.     public static interface Callback{  
  79.         void onDataChange(String data);  
  80.     }  
  81. }  

MainActivity中我们可以通过onServiceConnected方法中的iBinder对象来实现MyServiceCallback的接口,在Android中有一个安全机制,辅助线程是不能直接修改主线程中的数据的,因此我们需要再定义一个Hander对象。

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. //①  
  2. public void onServiceConnected(ComponentName componentName, IBinder iBinder) {  
  3.     myBinder = (MyService.Binder) iBinder;  
  4.     myBinder.getMyService().setCallback(new MyService.Callback(){  
  5.         @Override  
  6.         public void onDataChange(String data) {  
  7.             Message msg = new Message();  
  8.             Bundle b = new Bundle();  
  9.             b.putString("data",data);  
  10.             msg.setData(b);  
  11.             hander.sendMessage(msg);  
  12.         }  
  13.     });  
  14. }  
  15.   
  16. //②  
  17. private Handler hander = new Handler(){  
  18.     @Override  
  19.     public void handleMessage(Message msg) {  
  20.         super.handleMessage(msg);  
  21.         textView.setText(msg.getData().getString("data"));  
  22.     }  
  23. };  

MainActivity

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {  
  2.   
  3.     private Intent intent;  
  4.     private EditText editText;  
  5.     private TextView textView;  
  6.     private MyService.Binder myBinder = null;  
  7.   
  8.   
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.activity_main);  
  13.         intent = new Intent(MainActivity.this, MyService.class);  
  14.         editText = (EditText) findViewById(R.id.editText);  
  15.         textView = (TextView) findViewById(R.id.textView);  
  16.   
  17.         findViewById(R.id.btyStartService).setOnClickListener(this);  
  18.         findViewById(R.id.btyStopService).setOnClickListener(this);  
  19.         findViewById(R.id.btyBindService).setOnClickListener(this);  
  20.         findViewById(R.id.btyUnbindService).setOnClickListener(this);  
  21.         findViewById(R.id.btySend).setOnClickListener(this);  
  22.   
  23.     }  
  24.   
  25.     @Override  
  26.     public void onClick(View view) {  
  27.         switch (view.getId()) {  
  28.             case R.id.btyStartService:  
  29.                 intent.putExtra("data", editText.getText().toString());  
  30.                 startService(intent);  
  31.                 break;  
  32.             case R.id.btyStopService:  
  33.                 stopService(intent);  
  34.                 break;  
  35.             case R.id.btyBindService:  
  36.                 bindService(intent, this, Context.BIND_AUTO_CREATE);  
  37.                 break;  
  38.             case R.id.btyUnbindService:  
  39.                 unbindService(this);  
  40.                 break;  
  41.             case R.id.btySend:  
  42.                 if (myBinder != null) {  
  43.                     myBinder.setData(editText.getText().toString());  
  44.                 }  
  45.                 break;  
  46.         }  
  47.     }  
  48.     //一旦绑定成功就会执行该函数  
  49.     @Override  
  50.     public void onServiceConnected(ComponentName componentName, IBinder iBinder) {  
  51.         myBinder = (MyService.Binder) iBinder;  
  52.         myBinder.getMyService().setCallback(new MyService.Callback(){  
  53.             @Override  
  54.             public void onDataChange(String data) {  
  55.                 Message msg = new Message();  
  56.                 Bundle b = new Bundle();  
  57.                 b.putString("data",data);  
  58.                 msg.setData(b);  
  59.                 hander.sendMessage(msg);  
  60.             }  
  61.         });  
  62.     }  
  63.   
  64.     @Override  
  65.     public void onServiceDisconnected(ComponentName componentName) {  
  66.          
  67.     }  
  68.   
  69.     private Handler hander = new Handler(){  
  70.         @Override  
  71.         public void handleMessage(Message msg) {  
  72.             super.handleMessage(msg);  
  73.             textView.setText(msg.getData().getString("data"));  
  74.         }  
  75.     };  
  76. }  


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

0 0
原创粉丝点击