Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 888|回复: 0

[默认分类] Android学习之Activity与Service进行通信的三种方式

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-4 13:00:21 | 显示全部楼层 |阅读模式

    Activity与Service进行通信的三种方式

      
      第一种 简单通信
      直接通过Intent进行传值,我们在启动一个Service的时候通过Intent的对象向Service进行传值,这种方式传递值比较不方便,性能不是很高。
      (1)在MainActivity中通过启动服务和终止服务的按钮分别调用startService(intent)和stopService(intent)来启动和停止服务
      MainActivity
    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.         findViewById(R.id.btyStartService).setOnClickListener(this);
    9.         findViewById(R.id.btyStopService).setOnClickListener(this);
    10.     }
    11.     @Override
    12.     public void onClick(View view) {
    13.         switch (view.getId()) {
    14.             case R.id.btyStartService://启动服务
    15.                 intent.putExtra("data", editText.getText().toString());
    16.                 startService(intent);
    17.                 break;
    18.             case R.id.btyStopService://终止服务
    19.                 stopService(intent);
    20.                 break;
    21.            
    22.         }
    23.     }
    24.    }
    复制代码
      

      (2)在Myservice中,我们通过onStartCommand(finalIntent intent, int flags, intstartId)这个函数来接收从Activity传过来的值
      Myservice
    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.     @Override
    9.     public IBinder onBind(Intent intent) {
    10.               return new Binder();
    11.     }
    12.     @Override
    13.     public void onCreate() {
    14.         super.onCreate();
    15.         myflags = true;
    16.         new Thread(){
    17.             @Override
    18.             public void run() {
    19.                 super.run();
    20.                 while(myflags){
    21.                     try {
    22.                         String str = data;
    23.                         Log.d(TAG, str);
    24.                         sleep(1000);
    25.                     } catch (InterruptedException e) {
    26.                         e.printStackTrace();
    27.                         Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();
    28.                     }
    29.                 }
    30.                 Log.d(TAG, "服务器已停止");
    31.             }
    32.         }.start();
    33.     }
    34.     @Override
    35.     public int onStartCommand(final Intent intent, int flags, int startId) {
    36.         data = intent.getStringExtra("data");
    37.         return super.onStartCommand(intent, flags, startId);
    38.     }
    39. }
    复制代码
      

      第二种
      我们在绑定服务的时候,首先要做的就是让我们的MainActivity实现ServiceConnection类,实现这个类之后,我们还需要重写ServiceConnection类中的两个方法onServiceConnected和onServiceDisconnected,这两个方法分别是在绑定成功和服务所在进程崩溃的时候被调用,如果绑定成功了,那么onServiceConnected(ComponentName componentName, IBinder iBinder) 就会被执行,然后第二个参数IBinder正是MyService中onBind()方法的返回值,因此我们可以通过这个返回值来想MyService传递数据。
      
    1. public IBinder onBind(Intent intent) {
    2.         Log.d(TAG, "服务器已绑定");
    3.        return new Binder();
    4. }
    复制代码
      

      

      

      (1)MyService 中我们创建一个Binder类,让其实现android.os.Binder类,并且定义一个方法setData,然后我们通过onBind()方法将其对象返回MainActivity。
    1. public class Binder extends android.os.Binder{
    2.         public void setData(String data){
    3.             MyService.this.data = data;
    4.         }
    5.     }
    复制代码
      MyService
    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.     @Override
    9.     public IBinder onBind(Intent intent) {
    10.         Log.d(TAG, "服务器已绑定");
    11.        return new Binder();
    12.     }
    13.     public class Binder extends android.os.Binder{
    14.         public void setData(String data){
    15.             MyService.this.data = data;
    16.         }
    17.     }
    18.     @Override
    19.     public void onCreate() {
    20.         super.onCreate();
    21.         myflags = true;
    22.         new Thread(){
    23.             @Override
    24.             public void run() {
    25.                 super.run();
    26.                 while(myflags){
    27.                     //System.out.println("程序正在运行.....");
    28.                     try {
    29.                         String str = data;
    30.                         Log.d(TAG, str);
    31.                         sleep(1000);
    32.                     } catch (InterruptedException e) {
    33.                         e.printStackTrace();
    34.                         Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();
    35.                     }
    36.                 }
    37.                 Log.d(TAG, "服务器已停止");
    38.             }
    39.         }.start();
    40.     }
    41.     @Override
    42.     public int onStartCommand(final Intent intent, int flags, int startId) {
    43.         data = intent.getStringExtra("data");
    44.         return super.onStartCommand(intent, flags, startId);
    45.     }
    46.     @Override
    47.     public void onDestroy() {
    48.         super.onDestroy();
    49.         myflags = false;
    50.     }
    51.     @Override
    52.     public boolean onUnbind(Intent intent) {
    53.         return super.onUnbind(intent);
    54.     }
    55. }
    复制代码
      (2)在MainActivity中,首先添加一个Binder对象,然后在ServiceConnection中获取MyService中返回的Binder对象,接着我们通过Binder对象调用它的方法setData向其传递数据
      MainActivity
    1. public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {
    2.     private Intent intent;
    3.     private EditText editText;
    4.     private TextView textView;
    5.     private MyService.Binder myBinder = null;//①
    6.     @Override
    7.     protected void onCreate(Bundle savedInstanceState) {
    8.         super.onCreate(savedInstanceState);
    9.         setContentView(R.layout.activity_main);
    10.         intent = new Intent(MainActivity.this, MyService.class);
    11.         editText = (EditText) findViewById(R.id.editText);
    12.         textView = (TextView) findViewById(R.id.textView);
    13.         findViewById(R.id.btyStartService).setOnClickListener(this);
    14.         findViewById(R.id.btyStopService).setOnClickListener(this);
    15.         findViewById(R.id.btyBindService).setOnClickListener(this);
    16.         findViewById(R.id.btyUnbindService).setOnClickListener(this);
    17.         findViewById(R.id.btySend).setOnClickListener(this);
    18.     }
    19.     @Override
    20.     public void onClick(View view) {
    21.         switch (view.getId()) {
    22.             case R.id.btyStartService://启动服务
    23.                 intent.putExtra("data", editText.getText().toString());
    24.                 startService(intent);
    25.                 break;
    26.             case R.id.btyStopService://终止服务
    27.                 stopService(intent);
    28.                 break;
    29.             case R.id.btyBindService://绑定服务
    30.                 bindService(intent, this, Context.BIND_AUTO_CREATE);
    31.                 break;
    32.             case R.id.btyUnbindService://解除绑定
    33.                 unbindService(this);
    34.                 break;
    35.             case R.id.btySend://想MyService传递数据
    36.                 if (myBinder != null) {
    37.                     myBinder.setData(editText.getText().toString());//③
    38.                 }
    39.                 break;
    40.         }
    41.     }
    42.     //一旦绑定成功就会执行该函数
    43.     @Override
    44.     public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    45.         myBinder = (MyService.Binder) iBinder;//②
    46.     }
    47.     @Override
    48.     public void onServiceDisconnected(ComponentName componentName) {
    49.     }
    50. }
    复制代码
      

      第三种,监听服务中的进程的变化
      在MyService中
      (1)添加一个公开的接口Callback
    1. public static interface Callback{
    2.             void onDataChange(String data);
    3.     }
    复制代码
      (2)在MyService内部添加一个变量
    1. private Callback callback;
    2. public void setCallback(Callback callback) {
    3.     this.callback = callback;
    4. }
    5. public Callback getCallback() {
    6.     return callback;
    7. }
    复制代码
      (3)向外界派发信息
    1. if (callback != null){
    2.     callback.onDataChange(str);
    3. }
    复制代码
      (4)在Binder中返回一个当前的MyService对象,然外部可以添加事件的绑定
    1. public MyService getMyService(){
    2.     return MyService.this;
    3. }
    复制代码
      MyService
      
    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.     @Override
    9.     public IBinder onBind(Intent intent) {
    10.         Log.d(TAG, "服务器已绑定");
    11.        return new Binder();
    12.     }
    13.     public class Binder extends android.os.Binder{
    14.         public void setData(String data){
    15.             MyService.this.data = data;
    16.         }
    17.         public MyService getMyService(){
    18.             return MyService.this;
    19.         }
    20.     }
    21.     @Override
    22.     public void onCreate() {
    23.         super.onCreate();
    24.         myflags = true;
    25.         new Thread(){
    26.             @Override
    27.             public void run() {
    28.                 super.run();
    29.                 int i =1;
    30.                 while(myflags){
    31.                     //System.out.println("程序正在运行.....");
    32.                     try {
    33.                         String str = i + ":" +data;
    34.                         Log.d(TAG, str);
    35.                         if (callback != null){
    36.                             callback.onDataChange(str);
    37.                         }
    38.                         sleep(1000);
    39.                         i++;
    40.                     } catch (InterruptedException e) {
    41.                         e.printStackTrace();
    42.                         Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();
    43.                     }
    44.                 }
    45.                 Log.d(TAG, "服务器已停止");
    46.             }
    47.         }.start();
    48.     }
    49.     @Override
    50.     public int onStartCommand(final Intent intent, int flags, int startId) {
    51.         data = intent.getStringExtra("data");
    52.         return super.onStartCommand(intent, flags, startId);
    53.     }
    54.     @Override
    55.     public void onDestroy() {
    56.         super.onDestroy();
    57.         myflags = false;
    58.     }
    59.     @Override
    60.     public boolean onUnbind(Intent intent) {
    61.         return super.onUnbind(intent);
    62.     }
    63.     public void setCallback(Callback callback) {
    64.         this.callback = callback;
    65.     }
    66.     public Callback getCallback() {
    67.         return callback;
    68.     }
    69.     public static interface Callback{
    70.         void onDataChange(String data);
    71.     }
    72. }
    复制代码
      
      在MainActivity中我们可以通过onServiceConnected方法中的iBinder对象来实现MyService中Callback的接口,在Android中有一个安全机制,辅助线程是不能直接修改主线程中的数据的,因此我们需要再定义一个Hander对象。
    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. private Handler hander = new Handler(){
    17.     @Override
    18.     public void handleMessage(Message msg) {
    19.         super.handleMessage(msg);
    20.         textView.setText(msg.getData().getString("data"));
    21.     }
    22. };
    复制代码
      

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

      

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

      

      

      
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-24 04:58 , Processed in 0.370976 second(s), 37 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表