ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Android 广播 - 组件通信

Android 广播 - 组件通信

一、Service 通知 Activity 更新 UI

1、Service
publicclassBroadcastConstants{publicstaticfinalStringACTION_UPDATE_UI="com.example.ACTION_UPDATE_UI";publicstaticfinalStringEXTRA_DATA="extra_data";}
publicclassMyServiceextendsService{@OverridepublicintonStartCommand(Intentintent,intflags,intstartId){// 模拟后台任务newThread(()->{try{Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}// 发送广播通知 ActivityIntentbroadcastIntent=newIntent(BroadcastConstants.ACTION_UPDATE_UI);broadcastIntent.putExtra(BroadcastConstants.EXTRA_DATA,"来自 Service 的数据");sendBroadcast(broadcastIntent);}).start();returnSTART_NOT_STICKY;}@Nullable@OverridepublicIBinderonBind(Intentintent){returnnull;}}
2、Activity
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".communication.WorkActivity"><TextViewandroid:id="@+id/tv_result"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/></androidx.constraintlayout.widget.ConstraintLayout>
publicclassWorkActivityextendsAppCompatActivity{privateTextViewtvResult;privatefinalBroadcastReceiveruiReceiver=newBroadcastReceiver(){@OverridepublicvoidonReceive(Contextcontext,Intentintent){if(BroadcastConstants.ACTION_UPDATE_UI.equals(intent.getAction())){Stringdata=intent.getStringExtra(BroadcastConstants.EXTRA_DATA);tvResult.setText(data);}}};@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_work);tvResult=findViewById(R.id.tv_result);IntentFilterfilter=newIntentFilter(BroadcastConstants.ACTION_UPDATE_UI);if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.TIRAMISU){registerReceiver(uiReceiver,filter,Context.RECEIVER_NOT_EXPORTED);}else{registerReceiver(uiReceiver,filter);}startService(newIntent(this,MyService.class));}@OverrideprotectedvoidonDestroy(){super.onDestroy();unregisterReceiver(uiReceiver);}}

二、Fragment 与 Activity 通信(双向)

1、Fragment
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#EEEEEE"android:orientation="vertical"android:padding="16dp"><TextViewandroid:id="@+id/tv_fragment_msg"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingBottom="12dp"android:text="Fragment 收到 Activity 的消息:无"android:textSize="16sp"/><Buttonandroid:id="@+id/btn_send_to_activity"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Fragment 发消息给 Activity"/></LinearLayout>
publicclassChildFragmentextendsFragment{privateTextViewtvFragmentMsg;@Nullable@OverridepublicViewonCreateView(@NonNullLayoutInflaterinflater,@NullableViewGroupcontainer,@NullableBundlesavedInstanceState){Viewview=inflater.inflate(R.layout.fragment_child,container,false);tvFragmentMsg=view.findViewById(R.id.tv_fragment_msg);view.findViewById(R.id.btn_send_to_activity).setOnClickListener(v->{Intentintent=newIntent(ParentActivity.ACTION_FROM_FRAGMENT);intent.putExtra(ParentActivity.EXTRA_MSG_FROM_FRAGMENT,"你好,我是 Fragment");LocalBroadcastManager.getInstance(requireContext()).sendBroadcast(intent);});returnview;}privatefinalBroadcastReceiveractivityReceiver=newBroadcastReceiver(){@OverridepublicvoidonReceive(Contextcontext,Intentintent){if(ParentActivity.ACTION_FROM_ACTIVITY.equals(intent.getAction())){Stringmsg=intent.getStringExtra(ParentActivity.EXTRA_MSG_FROM_ACTIVITY);tvFragmentMsg.setText("Fragment 收到 Activity 的消息:"+msg);}}};@OverridepublicvoidonStart(){super.onStart();// 注册接收 Activity 的广播IntentFilterfilter=newIntentFilter(ParentActivity.ACTION_FROM_ACTIVITY);LocalBroadcastManager.getInstance(requireContext()).registerReceiver(activityReceiver,filter);}@OverridepublicvoidonStop(){super.onStop();// 注销接收 Activity 的广播LocalBroadcastManager.getInstance(requireContext()).unregisterReceiver(activityReceiver);}}
2、Activity
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><TextViewandroid:id="@+id/tv_activity_msg"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingBottom="12dp"android:text="Activity 收到 Fragment 的消息:无"android:textSize="16sp"/><Buttonandroid:id="@+id/btn_send_to_fragment"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Activity 发消息给 Fragment"/><FrameLayoutandroid:id="@+id/container"android:layout_width="match_parent"android:layout_height="0dp"android:layout_marginTop="16dp"android:layout_weight="1"/></LinearLayout>
publicclassParentActivityextendsAppCompatActivity{// Activity -> Fragment 的广播publicstaticfinalStringACTION_FROM_ACTIVITY="com.example.ACTION_FROM_ACTIVITY";publicstaticfinalStringEXTRA_MSG_FROM_ACTIVITY="extra_msg_from_activity";// Fragment -> Activity 的广播publicstaticfinalStringACTION_FROM_FRAGMENT="com.example.ACTION_FROM_FRAGMENT";publicstaticfinalStringEXTRA_MSG_FROM_FRAGMENT="extra_msg_from_fragment";privateTextViewtvActivityMsg;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_parent);tvActivityMsg=findViewById(R.id.tv_activity_msg);findViewById(R.id.btn_send_to_fragment).setOnClickListener(v->{Intentintent=newIntent(ACTION_FROM_ACTIVITY);intent.putExtra(EXTRA_MSG_FROM_ACTIVITY,"你好,我是 Activity");LocalBroadcastManager.getInstance(this).sendBroadcast(intent);});if(savedInstanceState==null){getSupportFragmentManager().beginTransaction().replace(R.id.container,newChildFragment()).commit();}}privatefinalBroadcastReceiverfragmentReceiver=newBroadcastReceiver(){@OverridepublicvoidonReceive(Contextcontext,Intentintent){if(ACTION_FROM_FRAGMENT.equals(intent.getAction())){Stringmsg=intent.getStringExtra(EXTRA_MSG_FROM_FRAGMENT);tvActivityMsg.setText("Activity 收到 Fragment 的消息:"+msg);}}};@OverrideprotectedvoidonStart(){super.onStart();// 注册接收 Fragment 的广播IntentFilterfilter=newIntentFilter(ACTION_FROM_FRAGMENT);LocalBroadcastManager.getInstance(this).registerReceiver(fragmentReceiver,filter);}@OverrideprotectedvoidonStop(){super.onStop();// 注销接收 Fragment 的广播LocalBroadcastManager.getInstance(this).unregisterReceiver(fragmentReceiver);}}
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进