Android之 Activity间通信总结
来源:互联网 发布:东莞人工智能公司 编辑:程序博客网 时间:2024/06/06 03:20
在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:
<span style="font-size:14px;"> Intent intent = new Intent(this, AtySecond_.class); // 设置启动Activity时携带的参数信息 的Intent Bundle bundle = new Bundle(); bundle.putString("AtySecond", "AtyCommActivity传递的消息,不需要返回值"); intent.putExtras(bundle); startActivity(intent);</span>B中获取A传递的信息:
<span style="font-size:14px;">// 获取出入的Budle Intent intent = getIntent(); Bundle bundle = intent.getExtras(); msg = bundle.getString("AtySecond", "");</span>这种方法,大家都很熟悉,如果在关闭B Activity时,A希望从B中获取操作结果,该如何做呢?在A启动B时只能使用另外一种启动方法——startActivityForResult。startActivityForResult(Intent intent,int requestCode,)的主要作用就是它可以回传数据,其中参数intent,就是启动Activity的意图,参数requestCode是启动Activity,获取返回值的请求码,在onActivityResult作返回值处理时使用,以便分别是哪一个返回值请求。
1.A在启动B时,再使用startActivity()而是使用startActivityForResult
<span style="font-size:14px;">// 设置启动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);</span>2.重写onActivityResult,来获取从BActivity返回的数据
<span style="font-size:14px;"> 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);}}}</span>3.在B Activity finish()之前,将传回数据时,使用setResult方法
<span style="font-size:14px;"> // 携带返回值得Intent Intent intent = new Intent(); intent.putExtra("AtySecond", "AtySecond返回值"); setResult(RESULT_OK, intent); //此处一定要调用finish()方法 this.finish();</span>setResult方法什么时候调用。刚开始使用setResult,Result并 没有返回回去,获取的Intent是null.查阅了半天资料,才发现只有当前Activity被finish,结果才会被发送给parent的onActivityResult去处理。也就是说,setResult方法要在finish()之前调用,才能将数据返回。
按BACK键从一个Activity退出来的,一按BACK,android就会自动调用Activity的finish()方法,然后设置resultCode为RESULT_CANCELED,同时设置intent为NULL并没有调用setResult()也就不会返回任何数据了.解决方法就是在Activity里面捕获按BACK的事件,捕获到之后先setResult,然后自己来调用finish().
<span style="font-size:14px;"> public void onBackPressed() { // 携带返回值得Intent Intent intent = new Intent(); intent.putExtra("AtySecond", "AtySecond返回值"); setResult(RESULT_OK, intent); //此处一定要调用finish()方法 super.onBackPressed(); }</span>二、Activity与Fragment之间的通信
使用Fragment可以完成在同一Activity完成不同界面的转换。在界面转换时,Activity与Fragment之间的通信成了重中之重。Activity与Frament之间有以下通信方式:
1、如果Activity中有Fragment实例,可以通过直接调用Fragment中的public方法
在Activity中
<span style="font-size:14px;">FrmFirst mFrmFirst = new FrmFirst();tv_frmShow.setText("Frm的信息:" + mFrmFirst.getInfo());</span>在Fragment中
<span style="font-size:14px;">public class FrmFirst extends Fragment {TextView tv_xl;public FrmFirst() {// Required empty public constructor}@Overridepublic 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();}}</span>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实例,然后进行操作
在Fragment中
AtyFrms mAtyFrms;
在onAttach中获取Activity实例
<span style="font-size:14px;">// 绑定当前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"); }</span>4.如果Activity向Fragment传递参数,在Activity通过setArguments传递,在Fragment通过getArguments获取
官方文档推荐,在每个Frament里必须有一个空的构造函数,以便其可以实例化,但是不推荐含有带参的构造方法,用来传递参数,因为这些构造函数,并不能在调用Fragment时,将Fragment重新实例化,如果需要传递参数,可以通过setArguments传递,在Fragment通过getArguments。
在Activity中
<span style="font-size:14px;">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中// 获取传递的参数 BundleBundle bundle = getArguments();String info = bundle.getString("FrmFoure", "未传递参数信息");</span>info即为Activity传递的参数
5.通过回调听信。在Activity中实现接口,在Fragment中回调接口
在Activity中
<span style="font-size:14px;">public class AtyFrms extends AppCompatActivity implements FrmThree.FrmChanedListener{***... public void setCururent(String str) {tv_frmShow.setText("Frm的信息:" + str);}***...}</span>在Fragment中,定义接口
<span style="font-size:14px;"> // 定义接口 // 持有它的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("微信页面使用回调通信"); }</span>6.通过广播通信。在Activity中注册广播并在onReive中对相应广播处理,在Fragment中发送广播。
广播实例见Service通信。
三、Activity与Service之间通信
Activity启动服务Service时,通过Intent启动。若Activity向Service传递参数可以通过Intent传递。而当Service某些操作更新UI时,我们该如何操作呢?启动Service又有startService和bindService两种方式,不同的启动方式又该如何通信?以下有几种通信方式:
1.在Activity中,通过bindService方式启动Service,获取Service实例,然后进行操作
在Activity中
<span style="font-size:14px;">ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { MyService.MyBinder mMyBinder = (MyService.MyBinder) service;// 获取Service对象 mMyService = mMyBinder.getService(); }}// 通过bindService绑定ServiceIntent intentBind = new Intent(this, MyService_.class); bindService(intentBind, conn, BIND_AUTO_CREATE);</span>在Service中
<span style="font-size:14px;">public IBinder onBind(Intent intent) { return new MyBinder(); }// 创建内部类MyBinder继承于Binder,以便获取Service实例 public class MyBinder extends Binder { public MyService getService() { return MyService.this; } }</span>2.通过回调的方式。如方法1,已经获取Service实例。在Actvity中实现接口,在Service中,设置接口实例
并调用。
在Activity中
<span style="font-size:14px;">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) { } }); }</span>在Service中
<span style="font-size:14px;">public class MyService extends Service {***...onProgressChangedListener mListener;// 定义接口public interface onProgressChangedListener {void setProgress(int progress);}***...// 获取接口实例public void setListener(onProgressChangedListener listener) {this.mListener = listener;}***...}</span>3.通过广播BroadcastReiceive通信。
通过starService启动Service时,并不能够获取Service,意味着方式1和2,都不可再实现。我们可以这样做,在Service需要更新UI时,发送一条广播。在Activity中注册广播并接受广播处理。此种方式,只需要发送广播,并不需要获取Service实例,那么问题迎刃而解。
在Activity中
<span style="font-size:14px;">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 {@Overridepublic void onReceive(Context context, Intent intent) {***}}***...}</span>在Service中
<span style="font-size:14px;"><span style="white-space:pre"></span>// 需要更新UI时,发送一条广播Intent intentBroad = new Intent("***");intentBroad.putExtra("PROGRESS", pro);sendBroadcast(intentBroad);</span>在stopService或unBindService时,需要调用unregisterReceiver,将广播注销掉。
一点心得,大家分享!
集思广益、坚持不懈的总结,总会进步!
参考资料:
1.Android Developers
2.Android 中文API
3.http://www.cnblogs.com/lijunamneg/archive/2013/02/05/2892616.html
4.http://blog.csdn.net/lmj623565791/article/details/37970961
5.http://segmentfault.com/a/1190000002400391
6.http://blog.csdn.net/sdlgxxy/article/details/6226127
源码下载地址:点击打开链接
0 0
- Android之 Activity间通信总结
- Android之activity总结
- Android之activity总结
- Android之activity总结
- Android之activity总结
- Android之Activity总结
- android的一些总结——service(二)之activity与service之间的通信
- Android之Activity与Service通信
- Android之Activity与Service通信
- Android之Activity与Service通信
- Android之Activity与Service通信
- Android之Activity与Service通信
- Android中跨进程通信之Activity
- Android之Activity与Service通信
- Android之Activity与Service通信
- android笔记之activity使用intent通信
- android笔记之activity与broadreceiver通信
- Android之Service与Activity通信机制
- Oracle 11.2.0.4 RAC上调整SCAN 及 遇到的问题 on Oracle Linux 6
- 关于*R的那些概念科普:VR、MR、CR、AR AR/VR技术红利时代 再一次全行业集体踏空?
- rgb32编程写为bmp文件
- jquery设置radio选中
- linux下mysql命令(授权用户 基本操作)
- Android之 Activity间通信总结
- 设计模式——状态模式(有限状态机)
- misc_register
- gcc在x64体系中如何传递参数
- 测试用二叉树生成代码
- Tomcat热部署方法(3种)
- 学习Makefile笔记
- Castor实现XML与Java的互转
- android SAX解析XML学习笔记