Activity 组件间的通信

Activity 与 Activity 、Fragment、Service间的通信

1. Activity->Activity

  1. Intent/Bundle
    这种方式多用于Activity之间传递数据。示例代码如下:

    //首先创建一个Bundle对象
    Bundle bundle = new Bundle();
    bundle.putString("data_string","数据");
    bundle.putInt("data_int",10);
    bundle.putChar("da_char",'a');
    
    //然后创建一个Intent对象
    Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
    intent.putExtras(bundle);
    startActivity(intent);
    
  2. 类静态变量
    在Activity内部定义静态的变量,这种方式见于少量的数据通信,如果数据过多,还是使用第一种方式。示例代码如下:

    public class FirstActivity extends AppCompatActivity {
    
    	//声明为静态
    	static boolean isFlag = false;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_first);
    
    		//首先创建一个Bundle对象
    		Bundle bundle = new Bundle();
    		bundle.putString("data_string","数据");
    		bundle.putInt("data_int",10);
    		bundle.putChar("da_char",'a');
    		//然后创建一个Intent对象
    		Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
    		intent.putExtras(bundle);
    		startActivity(intent);
    	}
    }
    
  3. 全局变量
    定义一批静态变量,Activity之间通信都可以访问这个类里面的静态变量,这就是全局变量。

2. Activity->Service

  1. 绑定服务的方式,利用 ServiceConnection 这个接口。首先我们需要在要绑定的服务中声明一个Binder类

    public class MyService1 extends Service {
    
    	public String data = "";
    
    	public MyService1() {
    	}
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO: Return the communication channel to the service.
    		return new Binder();
    	}
    
    
    	public class Binder extends android.os.Binder{
    		public void sendData(String data){
    			MyService1.this.data = data;
    		}
    	}
    }
    

    然后让Activity实现 ServiceConnection 这个接口,并且在 onServiceConnected 方法中获取到 Service 提供给 Activity 的 Binder 实例对象,通过这个对象我们就可以与Service进行通信可以通过上述代码的Binder类中的sendData()方法进行通信。

    public class ServiceBindActivity extends AppCompatActivity implements ServiceConnection,View.OnClickListener {
    
    	private Button bt0,bt1,bt2;
    
    	public MyService1.Binder binder = null;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_service_bind);
    
    		bt0 = findViewById(R.id.bt0);
    		bt1 = findViewById(R.id.bt1);
    		bt2 = findViewById(R.id.bt2);
    
    		bt0.setOnClickListener(this);
    		bt1.setOnClickListener(this);
    		bt2.setOnClickListener(this);
    	}
    
    	@Override
    	protected void onDestroy() {
    		super.onDestroy();
    		unbindService(this);
    	}
    
    	//这个是服务绑定的时候调用
    	@Override
    	public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    		binder = (MyService1.Binder) iBinder;
    	}
    
    	//这个是服务解绑的时候调用
    	@Override
    	public void onServiceDisconnected(ComponentName componentName) {
    
    	}
    
    	@Override
    	public void onClick(View view) {
    
    		switch (view.getId()){
    
    			case R.id.bt0:
    
    				//绑定服务
    				Intent intent = new Intent(ServiceBindActivity.this,MyService1.class);
    				bindService(intent,this, Context.BIND_AUTO_CREATE);
    			break;
    			case R.id.bt1:
    				//通过binder对象来和Service进行通信
    				if(binder != null)
    					binder.sendData("bt1");
    			break;
    			case R.id.bt2:
    				//通过binder对象来和Service进行通信
    				if(binder != null)
    					binder.sendData("bt2");
    			break;
    		}
    	}
    }
    
  2. Intent
    这种方式很简单,我们在启动和停止Service时所调用的方法都需要传入一个Intent实例对象,通过这个传入的Intent对象,我们就可以与Service进行通信。
    Activity代码是这样的:

    public class ServiceStartActivity extends AppCompatActivity implements View.OnClickListener {
    	private Button bt0,bt1;
    	private Intent intent ;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_service_start);
    
    		intent = new Intent(this, MyService2.class);
    		bt0 = findViewById(R.id.bt0);
    		bt1 = findViewById(R.id.bt1);
    
    		bt0.setOnClickListener(this);
    		bt1.setOnClickListener(this);
    	}
    
    	@Override
    	public void onClick(View view) {
    		switch (view.getId()){
    			case R.id.bt0:
    				//开启服务并且传递数据
    				intent.putExtra("data_stirng","string数据");
    				startActivity(intent);
    			break;
    			case R.id.bt1:
    				//结束服务
    				stopService(intent);
    			break;
    		}
    	}
    }
    //Service中的代码:
    public class MyService2 extends Service {
    	public String data = "";
    	public MyService2() {
    	}
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO: Return the communication channel to the service.
    		return null;
    	}
    
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		//得到Activity传递过来的数据
    		data = intent.getStringExtra("data_string");
    		return super.onStartCommand(intent, flags, startId);
    	}
    }
    

    这种通信方式的缺点:只能传递少量的数据

  3. CallBack + Handler,监听服务的进程变化

    //Service中:
    public class MyService3 extends Service {
    
    	//在Service中如果要进行耗时任务,可以通过CallBack接口提供的方法与Activity进行通信
    	public Callback callback;
    
    	public MyService3() {
    	}
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO: Return the communication channel to the service.
    		return new Binder();
    	}
    	public void setCallBack(CallBack callBack){
    		this.callback = callback;
    	}
    
    	public Callback getCallback() {
    		return callback;
    	}
    
    	public interface CallBack{
    		void onDataChange(String data);
    	}
    
    	public class Binder extends android.os.Binder{
    		public MyService3 getMyService3(){
    			return MyService3.this;
    		}
    	}
    }
    //Activity中:
    public class ServiceBind2Activity extends AppCompatActivity implements ServiceConnection{
    	public MyService3.Binder binder = null;
    	private Handler handler = new Handler(){
    		@Override
    		public void handleMessage(Message msg) {
    			super.handleMessage(msg);
    			Bundle bundle = msg.getData();
    			String data_string = bundle.getString("data_string");
    			//接下来就是更新ui
    		}
    	};
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_service_bind2);
    	}
    
    	@Override
    	public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    
    		binder = (MyService3.Binder) iBinder;
    		binder.getMyService3().setCallBack(new MyService3.CallBack() {
    			//此方法提供给MyService3在子线程中调用
    			@Override
    			public void onDataChange(String data) {
    				Message message = new Message();
    				Bundle bundle = new Bundle();
    				bundle.putString("data_string","String数据");
    				message.setData(bundle);
    				//通过Handler进行异步通信,不过耗时操作放在MyService3中
    				handler.sendMessage(message);
    			}
    		});
    	}
    	@Override
    	public void onServiceDisconnected(ComponentName componentName) {
    	
    	}
    }
    

    当ServiceBind2Activity去绑定服务MyService3的时候,那么在Activity中的onServiceConnected()方法被调用,此时位于MySerivce3的CallBack接口引用被实例化,并且onDataChange()方法被实现,可以看到里面是一段Handler通信的代码,;
    这个方法是为MyService3做耗时操作调用的,没有在MyService3 中写耗时操作的代码,
    这种通信方式的好处:监听服务的进程变化。

在这里插入图片描述

3. Activity->Fragment

  1. Bundle
    在创建Fragment实例的时候,调用方法 setArguments 将一个 Bundle 对象传递给 Fragment ,然后在 Fragment 中先去判断是否和当前 Activity 绑定上了,如果绑定上了,就可以拿出这个 Bundle 中的数据啦。

    //在Activity中:首先创建一个Bundle对象
    Bundle bundle = new Bundle();
    bundle.putString("data_string","数据");
    bundle.putInt("data_int",10);
    bundle.putChar("da_char",'a');
    
    Fragment fragment = new MyFragment1();
    fragment.setArguments(bundle);
    //在MyFragment1中代码是这样的:
    if(isAdded()){
    //这里判断是否Fragment和Activity进行了绑定
    	Bundle bundle = getArguments();
    	String data_string = bundle.getString("data_string");
    	String data_int = bundle.getInt("data_int");
    	String data_char = bundle.getChar("data_char");
    }
    

    对于这个 isAdded() ;因为如果这个Fragment没有和Activity绑定的话,那么 Bundle 对象是无法从 Activity 传递给 Fragment 的,因此这种写法是必须的。

  2. 直接进行方法调用
    在Activity里通过Fragment的引用,可以直接调用Framgent中的定义的任何方法。

    MyFragment1 myFragment1 = new MyFragment1();
    myFragment.toString("传送的string数据");
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liusaisaiV1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值