开发过程中有时候会遇到这样的需求,在这个Activity里面拿到了某个数据,然后需要用这个数据去更新另一个Activity的UI。这里通过一个Demo,讲解一下实现这个需求的三种方法。首先说一下这个demo的需求,很简单,两个Activity,OneActivity中有一个TextView,里面有原始值,还有一个按钮用来跳转到SecondActivity。SecondActivity中有两个按钮,一个按钮通知OneActivity更新UI,另一个返回OneActivity。
一.接口回调
接口回调大家用过都很熟悉,我们约定一个接口,在SecondActivity中进行注册,在OneActivity中实现。例如我们常见的点击事件就是典型的接口回调。当我们在SecondActivity中注册了接口时,就会通知实现了该接口的OneActivity去做自己该做的事情。代码也很简单,先看一下我们约定的接口。
public interface ChangeValueCallBack {
void changevalue();
}
在SecondActivity我们要做的是,注册这个接口,并且提供实例化接口的方法。
public class SecondActivity extends Activity{
private Button change;
private Button back;
public static ChangeValueCallBack changeValueCallBack;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondactivity);
change= (Button) findViewById(R.id.change);
back= (Button) findViewById(R.id.back);
change.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (changeValueCallBack!=null){
//注册接口
changeValueCallBack.changevalue();
}
}
});
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
//提供方法实例化接口
public void setChangeValueCallBack(ChangeValueCallBack changeValueCallBack){
this.changeValueCallBack=changeValueCallBack;
}
}
接着在OneActivity中实现这个接口,同时要通过一个SecondActivity对象去实例化接口对象。
public class OneActivity extends Activity implements ChangeValueCallBack{
private TextView value;
private Button next;
private SecondActivity secondActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.oneactivity);
value = (TextView) findViewById(R.id.value);
next = (Button) findViewById(R.id.next);
secondActivity=new SecondActivity();
secondActivity.setChangeValueCallBack(this);
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(OneActivity.this, SecondActivity.class));
}
});
}
@Override
public void changevalue() {
value.setText(getResources().getString(R.string.value_changed));
}
}
这样,当点击SecondActivity中的change按钮时,会去注册这个接口,并通知OneActivity调用接口中定义的方法。我在这里没有携带任何参数,当然是可以带参数的过去的。也就实现了数据的传递,在Fragment通信中也可以使用。
二.共享Handler
之前我们常用Handler来解决子线程无法更新UI的问题,在这里我们引用一个公用的Handler,同样是上一个demo的情况,我们用同一个Handler,在SecondActivity中特定条件下发送消息,在OneActivity中处理相应消息。原理很简单,下面来看一下代码。
//全局共享Handler
private Handler mHandler = null;
public Handler getmHandler() {
return mHandler;
}
public void setmHandler(Handler mHandler) {
this.mHandler = mHandler;
}
我把这个Handler定义在Application中,因为Application是全局只存在唯一实例的,所以这个Application的这个Handler实例也是全局唯一存在的,为所有Activity所共享。在OneActivity中,自定义一个Handler处理消息并更新UI,并新建一个自定义Hanlder对象赋给Application中的Hanlder。
public class OneActivity extends Activity {
private TextView value;
private Button next;
private MyApplication myApplication;
private MyHandler myHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.oneactivity);
value = (TextView) findViewById(R.id.value);
next = (Button) findViewById(R.id.next);
myApplication= (MyApplication) getApplication();//取得Applicaiton实例
myHandler= new MyHandler();
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myApplication.setmHandler(myHandler);//为Application中共享Handler赋值
startActivity(new Intent(OneActivity.this, SecondActivity.class));
}
});
}
//自定义Handler,处理消息,更新UI
final class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what== Constants.CHANGED_VALUE){
value.setText(getResources().getString(R.string.value_changed));
}
}
}
}
在SecondActivity中,我们通过Applicaiton实例取得共享的Handler,在特定条件下发送消息更新OneActivity的UI。
public class SecondActivity extends Activity{
private Button change;
private Button back;
private OneActivity.MyHandler myHandler;
private MyApplication myApplication;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondactivity);
change= (Button) findViewById(R.id.change);
back= (Button) findViewById(R.id.back);
myApplication= (MyApplication) getApplication();//取得Applicaiton实例
myHandler= (OneActivity.MyHandler) myApplication.getmHandler();//取得共享Handler
change.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myHandler.sendEmptyMessage(Constants.CHANGED_VALUE);//发送消息
}
});
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
三.发送广播
这个方法就很简单了,在SecondActivity中发送广播,在OneActivity中接收广播并更新UI。这个方法就不贴代码具体分析了,实际中也没有这个必要去特地注册一个广播。