在Android中跨进程通信是能够经常遇见的 ,像下载大文件需要更新下载进度这种东西,因为我们设置了下载的Service是在独立的进程里边,也就是说不是在默认的UI线程里边,传统的handler就无法实现了,跨进程通信的方法或许有好多,寡人知道的有三种分别为AIDL、Messenger、BroadCastReceiver.本文讲述第三种借助BroadCastReceiver实现跨进程通信。
roadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。
在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。
Android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。而作为应用开发者,就需要数练掌握Android系统提供的一个开发利器,那就是BroadcastReceiver。
本文举一个在开发中常见的应用场景
根据系统网络状况的变化情况,通过更新UI来通知用户网络状况的改变
上边提到,当网络状态改变时系统会产生一条广播,我们只需要注册这条广播就能实现对网络状况的监听
public class NetworkStateService extends Service{
private static final String tag="tag";
private ConnectivityManager connectivityManager;
private NetworkInfo info;
private BroadcastReceiver mReceiver=new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent intent) {
String action=intent.getAction();
if(action.equals(ConnectivityManager.CONNECTIVITY_ACTION)){
connectivityManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
info=connectivityManager.getActiveNetworkInfo();
Intent intent1 = new Intent();
intent1.setAction("NetStatus");
if(info!=null &&info.isAvailable()){
String name=info.getTypeName();
Log.e(tag, "当前的网络为" + name);
intent1.putExtra("CurrentLoading", "当前的网络为" + name);
}else{
Log.e(tag, "没有可用网络");
intent1.putExtra("CurrentLoading", "没有可用网络");
}
//当网络状况改变时,发广播更新UI
sendBroadcast(intent1);
}
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onCreate() {
super.onCreate();
IntentFilter mFilter = new IntentFilter();
//当网络变化时会产生一个ConnectivityManager.CONNECTIVITY_ACTION事件,只要监听这个事件就可以了。
mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mReceiver, mFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
connectivityManager = null;
info = null;
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
别忘了一条,既然是跨进程通信就要把Service设置在单独的进程中
<service android:enabled="true"
android:exported="true"
android:name=".NetworkStateService" />
监听网络状况还需要一个权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
最后是Activity界面的代码
public class MainActivity extends AppCompatActivity {
private Handler handler= new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
String currernt = (String) msg.obj;
tv.setText(currernt);
}
};
private Intent serviceIntent;
private TextView tv;
private String MYACTION= "NetStatus";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
serviceIntent = new Intent(MainActivity.this, NetworkStateService.class);
startService(serviceIntent);
}
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(MYACTION);
registerReceiver(receiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
stopService(serviceIntent);
unregisterReceiver(receiver);
handler = null;
serviceIntent = null;
}
//自定义广播接收器接收Service中发来的广播,然后通过handler更新UI
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (MYACTION.equals(intent.getAction())){
String current = intent.getStringExtra("CurrentLoading");
Message message = Message.obtain();
message.obj = current;
handler.sendMessage(message);
}
}
};
}