一、Service 通知 Activity 更新 UI
1、Service
public class BroadcastConstants {
public static final String ACTION_UPDATE_UI = "com.example.ACTION_UPDATE_UI";
public static final String EXTRA_DATA = "extra_data";
}
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 模拟后台任务
new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 发送广播通知 Activity
Intent broadcastIntent = new Intent(BroadcastConstants.ACTION_UPDATE_UI);
broadcastIntent.putExtra(BroadcastConstants.EXTRA_DATA, "来自 Service 的数据");
sendBroadcast(broadcastIntent);
}).start();
return START_NOT_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
2、Activity
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns: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">
<TextView
android: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>
public class WorkActivity extends AppCompatActivity {
private TextView tvResult;
private final BroadcastReceiver uiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (BroadcastConstants.ACTION_UPDATE_UI.equals(intent.getAction())) {
String data = intent.getStringExtra(BroadcastConstants.EXTRA_DATA);
tvResult.setText(data);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_work);
tvResult = findViewById(R.id.tv_result);
IntentFilter filter = new IntentFilter(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(new Intent(this, MyService.class));
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(uiReceiver);
}
}
二、Fragment 与 Activity 通信(双向)
1、Fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns: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">
<TextView
android: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" />
<Button
android:id="@+id/btn_send_to_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fragment 发消息给 Activity" />
</LinearLayout>
public class ChildFragment extends Fragment {
private TextView tvFragmentMsg;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = 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 -> {
Intent intent = new Intent(ParentActivity.ACTION_FROM_FRAGMENT);
intent.putExtra(ParentActivity.EXTRA_MSG_FROM_FRAGMENT, "你好,我是 Fragment");
LocalBroadcastManager.getInstance(requireContext()).sendBroadcast(intent);
});
return view;
}
private final BroadcastReceiver activityReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (ParentActivity.ACTION_FROM_ACTIVITY.equals(intent.getAction())) {
String msg = intent.getStringExtra(ParentActivity.EXTRA_MSG_FROM_ACTIVITY);
tvFragmentMsg.setText("Fragment 收到 Activity 的消息:" + msg);
}
}
};
@Override
public void onStart() {
super.onStart();
// 注册接收 Activity 的广播
IntentFilter filter = new IntentFilter(ParentActivity.ACTION_FROM_ACTIVITY);
LocalBroadcastManager.getInstance(requireContext()).registerReceiver(activityReceiver, filter);
}
@Override
public void onStop() {
super.onStop();
// 注销接收 Activity 的广播
LocalBroadcastManager.getInstance(requireContext()).unregisterReceiver(activityReceiver);
}
}
2、Activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android: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" />
<Button
android:id="@+id/btn_send_to_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Activity 发消息给 Fragment" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:layout_weight="1" />
</LinearLayout>
public class ParentActivity extends AppCompatActivity {
// Activity -> Fragment 的广播
public static final String ACTION_FROM_ACTIVITY = "com.example.ACTION_FROM_ACTIVITY";
public static final String EXTRA_MSG_FROM_ACTIVITY = "extra_msg_from_activity";
// Fragment -> Activity 的广播
public static final String ACTION_FROM_FRAGMENT = "com.example.ACTION_FROM_FRAGMENT";
public static final String EXTRA_MSG_FROM_FRAGMENT = "extra_msg_from_fragment";
private TextView tvActivityMsg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parent);
tvActivityMsg = findViewById(R.id.tv_activity_msg);
findViewById(R.id.btn_send_to_fragment).setOnClickListener(v -> {
Intent intent = new Intent(ACTION_FROM_ACTIVITY);
intent.putExtra(EXTRA_MSG_FROM_ACTIVITY, "你好,我是 Activity");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
});
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new ChildFragment())
.commit();
}
}
private final BroadcastReceiver fragmentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_FROM_FRAGMENT.equals(intent.getAction())) {
String msg = intent.getStringExtra(EXTRA_MSG_FROM_FRAGMENT);
tvActivityMsg.setText("Activity 收到 Fragment 的消息:" + msg);
}
}
};
@Override
protected void onStart() {
super.onStart();
// 注册接收 Fragment 的广播
IntentFilter filter = new IntentFilter(ACTION_FROM_FRAGMENT);
LocalBroadcastManager.getInstance(this).registerReceiver(fragmentReceiver, filter);
}
@Override
protected void onStop() {
super.onStop();
// 注销接收 Fragment 的广播
LocalBroadcastManager.getInstance(this).unregisterReceiver(fragmentReceiver);
}
}