什么是通信?
通信 ,顾名思义,指的就是信息的传递或者交换
看完本文能收获什么?
按目录索引,你可以学习到
1. 组件间的通信,Activity,fragment,Service, Provider,Receiver
2. 进程间的通信,AIDL
3. 线程间的通信,Handler,AnsycTask,IntentService
4. 多个App间的通信
5. 使用大型开源框架完成组件通信,EventBus,otto
6. 网络通信基础篇:Google 课程–AnsycTask+HttpClient
7. 网络通信提高篇:开源框架Ansyc-Httpclient,okttp,Retrofit
建议阅读本文时遵循以下学习思路
1. 研究对象:Activity,fragment等组件
2. 信息存在形式:Intent,Bundle,静态变量,全局变量,还是点击事件,触摸事件的回调监听,或者文件形式(Sharepreference,SQLite,File , NetStream) ,本质就是信息源
3. 信息传递的形式:网路,回调监听,线程,Intent,全局Application
4. 相同形式的思路,不会出现第二次,请读者举一反三
5. 最后强调研究对象是单一的
Activity通信
Activity 和 Activity
1. 常规方式:Intent Bundle
通过Intent 启动另一个Activity时,有两种重载方式:
- startActivity(new Intent(),new Bundle());
- startActivityForResult(new Intent(),FLAG,new Bundle());
从参数列表就可以总结出来,有Intent,和Bundle,可以传递8种基本数据类型和可序列化的数据类型,比如字符串和字节数组。提到可序列化,就引发 Intent和Bundle 的局限性了:
- Intent Bundle 无法传递“不可序列化”的数据,比如Bitmap,InputStream,解决办法有很多种,最简单的就是将“不可序列化”的对象,转换成字节数组,这里因为主要是讲解通信,所以不展开讲了。
- Intent Bundle 能传递的数据大小在40K以内 。
PS : 很多人不理解为什么把Intent和Bundle放在一起谈,因为Intent 底层存储信息的原理也是通过Bundle存储!
2. 公有静态变量
比如 public static String flag=“中国”;
使用方式 比如 在其他Activity当中 FirstActivity.flag=“china”; 修改 静态变量的值
3. 基于物理形式:
比如 File,SQLite,Sharepreference 物理形式
4. 全局变量:
比如Application:Application是与Activity,Service齐名的组件,非常强大,它的特点是全局组件共用,单例形式存在,在其他组件中,我们只需要Context.getApplication()获得该对象的引用即可
Activity 和Fragment,Service,BrodcastReceiver
,首先都遵循,如何启动它们,就如何传递信息的原则:
1. Activity与Fragment
1. 通过构造函数传递 2.获取Fragment的实例对象
//CustFragment 是自定义的fragment,参数列表也可以自己定义咯,
getSupportFragmentManager().beginTransaction()
.add(new CustFragment(自定义的的参数列表),new String("参数"))
//------------------method two-----------------------
getSupportFragmentManager().findFragmentById(R.id.headlines_fragment);
//------------------method three----------------------
getSupportFragmentManager().findFragmentByTag("HeadLines");
聪明的读者可能会问Fragment如何与Activity通信类似的问题,这是个好问题,请注意我们的研究的原则是单一目标原则,在这节我研究的是Activity,你的疑惑在后面都会一一解答
2. Activity与Service
Activity启动Service的两种方式:
//CustomService 是自定义Service,完成一些后台操作
startService(new Intent(FirstActivity.this,CustomService.class));
bindService(new Intent(FirstActivity.this,CustomService.class)), new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//当前启动的service 一些数据就会回调回这里,我们在Activity中操作这些数据即可
get
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
},flags);
从启动方式就可以看出,通过Bundle对象的形式存储,通过Intent传输,来完成Activity向Service传递数据的操作
3. Activity与BroadcastReceiver
启动广播的形式也有两种:
//method one !!!-----------------------------------------------
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
}
},new IntentFilter(),"",new Handler());
//method two !!!-----------------------------------------------
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
}
},new IntentFilter());
关于method one 的第三个参数Handler很多人会很费解
参照registerReceiver中源码关于该Handler参数的解释:
Handler identifying the thread that will receive the Intent. If null, the main thread of the process will be used.
定义了一个用于接收Intent的子线程,如果不填或者默认为null,那么就会在主线程中完成接收Intent的操作
很明显,Activity与BroadcastReceiver通信时,用的也是Intent传递,Bundle存储
4. 通讯时的同步问题
这里的同步通讯问题,为下文Fragment通讯作铺垫,不是这个问题不重要,不值得引起你注意,只是我想把问题放在它最应该出现的位置。
以上只是基础的传递数据的形式,大部分都是静态的,现在有一种需求,用户操作Activity,发出了某些指令,比如按下,滑动,触摸等操作,如何完成这些信息传递呢?这就要求同步了。
同步传递消息也很简单,就是调用系统写好的回调接口
首先我们要知道,用户 点击,触摸 这些行为 也属于 通信的范畴—点击和触摸属于 信息源;
比如用户行为进行点击,那就实现 :
new Button(mCotext).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ImageView(mCotext).invalidate();
}
});
通过此招提示指定的ImageView:嘿!老兄,你该刷新了
又或者 当用户 进行触摸操作,我们需要实现放大缩小平移指定的区域:
new RelativeLayout(mCotext).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//缩放
v.setScaleX(1f);
v.setScaleY(1f);
//平移
v.setTranslationX(1f);
v.setTranslationY(1f);
v.setTranslationY(1f);
//旋转
v.setRotation(2f);
v.setRotationX(2f);
v.setRotationY(2f);
v.invalidate();
return true;
}
});
嘿,你看,当用户进行触摸操作,我们可以通过回调onTouchListenter来完成“触摸”这一操作
关于View重绘机制以及优化刷新UI的细节,不属于本文讨论范围。
Fragment
1. Fragment 与Activity通信