在Android中,Activity作为界面显示。google并不推荐在Activity中做耗时操作,如果Activity操作耗时超过5s时,会提示是否等待对话框。
一般耗时操作会在Service中处理,Service主要负责长期在后台运行。
自从google推出Fragment以来,中文翻译为碎片,使用的越来越广泛。在同一个Activity界面会插入几个Fragment,用来显示不同的功能界面。
在我们的实际项目中,总是会用到Activity、Service及Fragment。Activity与它们之间是怎么进行通信,完成UI更新。接下来,我们一一道来。
一、Activity与Activity之间的通信
当A Activity打开B Activity时,大家都知道通过调用startActivity(intent),由A启动B。如果希望A传递信息给B,只需如果在intent携带即可。如果携带的信息中包含自定义类,需要将类序列化,实现接口Parcelable或者Serializable。
A启动B:
Intent intent = new Intent(this, AtySecond_.class);
// 设置启动Activity时携带的参数信息 的Intent
Bundle bundle = new Bundle();
bundle.putString("AtySecond", "AtyCommActivity传递的消息,不需要返回值");
intent.putExtras(bundle);
startActivity(intent);
B中获取A传递的信息: // 获取出入的Budle
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
msg = bundle.getString("AtySecond", "");
这种方法,大家都很熟悉,如果在关闭B Activity时,A希望从B中获取操作结果,该如何做呢?在A启动B时只能使用另外一种启动方法——startActivityForResult。startActivityForResult(Intent intent,int requestCode,)的主要作用就是它可以回传数据,其中参数intent,就是启动Activity的意图,参数requestCode是启动Activity,获取返回值的请求码,在onActivityResult作返回值处理时使用,以便分别是哪一个返回值请求。 // 设置启动Activity时携带的参数信息 的Intent
Intent intent = new Intent(this, AtySecond_.class);
Bundle bundle = new Bundle();
bundle.putString("AtySecond", "AtyCommActivity传递的消息,需要返回值");
intent.putExtras(bundle);
// 参数 REQUEST_ONE :请求依据,作为在onActivityResult做处理时识别码
startActivityForResult(intent, REQUEST_ONE);
2.重写onActivityResult,来获取从BActivity返回的数据 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.i("123", "requestCode: " + requestCode);
if (requestCode == REQUEST_ONE) {
if (null != data) { // data为AtySecond返回的Intent
// msg即为回传的值
String msg = data.getStringExtra("AtySecond");
tv_msg.setText("返回的信息:" + msg);
}
}
}
3.在B Activity finish()之前,将传回数据时,使用setResult方法
// 携带返回值得Intent
Intent intent = new Intent();
intent.putExtra("AtySecond", "AtySecond返回值");
setResult(RESULT_OK, intent);
//此处一定要调用finish()方法
this.finish();
setResult方法什么时候调用。刚开始使用setResult,Result并 没有返回回去,获取的Intent是null.查阅了半天资料,才发现只有当前Activity被finish,结果才会被发送给parent的onActivityResult去处理。也就是说,setResult方法要在finish()之前调用,才能将数据返回。 public void onBackPressed() {
// 携带返回值得Intent
Intent intent = new Intent();
intent.putExtra("AtySecond", "AtySecond返回值");
setResult(RESULT_OK, intent);
//此处一定要调用finish()方法
super.onBackPressed();
}
二、Activity与Fragment之间的通信 FrmFirst mFrmFirst = new FrmFirst();
tv_frmShow.setText("Frm的信息:" + mFrmFirst.getInfo());
在Fragment中 public class FrmFirst extends Fragment {
TextView tv_xl;
public FrmFirst() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frm_first, container, false);
tv_xl = (TextView) view.findViewById(R.id.tv_xl);
return view;
}
// 权限修饰为public,以供外部调用
public String getInfo() {
return tv_xl.getText().toString();
}
}
2、如果Activity中没有Fragment实例,每个Fragment都有唯一的TAG或者ID,可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行1中的操作; // 获取Fragment ,调用Fragment中的Public方法,与Fragment通信
Fragment mFrm = mFManager.findFragmentByTag("fragmentTag");
if (mFrm instanceof FrmFirst) {
FrmFirst f = (FrmFirst) mFrm;
tv_frmShow.setText("Frm的信息:" + f.getInfo());
} else {
tv_frmShow.setText("Frm的信息:");
}
3.在Fragment中获取Actvity实例,然后进行操作 // 绑定当前Activity
// 可以调用当前Activity中的public 方法
public void onAttach(Activity activity) {
super.onAttach(activity);
mAtyFrms = (AtyFrms) activity;
}
// 通过getActivity获取Activity实例
public void onResume() {
super.onResume();
// 通过getActivity方法获取当前Activity
// 调用Activity中的public方法
AtyFrms atyFrms = (AtyFrms) getActivity();
// setInfo为Activity的public方法
atyFrms.setInfo("当前界面为QQ");
}
4.如果Activity向Fragment传递参数,在Activity通过setArguments传递,在Fragment通过getArguments获取 Bundle bundle = new Bundle();
bundle.putString("FrmFoure", "AtyFrms打开FrmFoure");
if (null == mFrmFoure) {
mFrmFoure = new FrmFoure_();
}
mFrmFoure.setArguments(bundle);
mFTransaction.replace(R.id.fl_content, mFrmFoure, "fragmentTag");
mFTransaction.commit();
在Fragment中
// 获取传递的参数 Bundle
Bundle bundle = getArguments();
String info = bundle.getString("FrmFoure", "未传递参数信息");
info即为Activity传递的参数 public class AtyFrms extends AppCompatActivity implements FrmThree.FrmChanedListener{
***...
public void setCururent(String str) {
tv_frmShow.setText("Frm的信息:" + str);
}
***...
}
在Fragment中,定义接口 // 定义接口
// 持有它的Activity必须实现这个回调方法
public interface FrmChanedListener {
void setCururent(String str);
}
//获取接口实例
FrmChanedListener mListener;
public void onAttach(Activity activity) {
super.onAttach(activity);
// 如果Activity没有实现这个接口,那么Fragment会抛出ClassCastException异常
// 如果成功,那么mListener成员就会拥有Activity实现的FrmChanedListener对象的引用,
// 以便Fragment FrmThree能够通过FrmChanedListener接口定义的回调方法和Activity共享事件
try {
mListener = (FrmChanedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}
//回调接口
public void onResume() {
super.onResume();
// Fragment FrmThree能够通过FrmChanedListener接口定义的回调方法和Activity共享事件
mListener.setCururent("微信页面使用回调通信");
}
6.通过广播通信。在Activity中注册广播并在onReive中对相应广播处理,在Fragment中发送广播。 ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.MyBinder mMyBinder = (MyService.MyBinder) service;
// 获取Service对象
mMyService = mMyBinder.getService();
}
}
// 通过bindService绑定Service
Intent intentBind = new Intent(this, MyService_.class);
bindService(intentBind, conn, BIND_AUTO_CREATE);
在Service中 public IBinder onBind(Intent intent) {
return new MyBinder();
}
// 创建内部类MyBinder继承于Binder,以便获取Service实例
public class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
}
2.通过回调的方式。如方法1,已经获取Service实例。在Actvity中实现接口,在Service中,设置接口实例 ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.MyBinder mMyBinder = (MyService.MyBinder) service;
mMyService = mMyBinder.getService();
// 通过匿名内部类实例化接口
mMyService.setListener(new MyService.onProgressChangedListener() {
@Override
public void setProgress(int progress) {
}
});
}
在Service中 public class MyService extends Service {
***...
onProgressChangedListener mListener;
// 定义接口
public interface onProgressChangedListener {
void setProgress(int progress);
}
***...
// 获取接口实例
public void setListener(onProgressChangedListener listener) {
this.mListener = listener;
}
***...
}
3.通过广播BroadcastReiceive通信。 public class AtyService extends AppCompatActivity {
***...
MyBroadcastReceive mReiver;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aty_service);
// 动态注册广播
mReiver = new MyBroadcastReceive();
IntentFilter filter = new IntentFilter("***");
registerReceiver(mReiver, filter);
}
protected void onDestroy() {
super.onDestroy();
// 在Activity销毁时,将广播注销
unregisterReceiver(mReiver);
}
***...
public class MyBroadcastReceive extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
***
}
}
***...
}
在Service中 // 需要更新UI时,发送一条广播
Intent intentBroad = new Intent("***");
intentBroad.putExtra("PROGRESS", pro);
sendBroadcast(intentBroad);
在stopService或unBindService时,需要调用unregisterReceiver,将广播注销掉。6.http://blog.csdn.net/sdlgxxy/article/details/6226127
源码下载地址:点击打开链接