Android Fragments Service和Fragment之间的通信

jutyujz0  于 11个月前  发布在  Android
关注(0)|答案(2)|浏览(139)

我们如何在服务和片段之间通信/传递数据
我正在尝试创建一个服务,我正在其中执行一些操作,我想根据通过服务执行的操作更新我的片段ui状态,但我不知道如何执行

wj8zmpe1

wj8zmpe11#

有很多方法可以做到这一点
1.第一个简单的方法是你可以直接在片段中获取服务变量,如下所示:

lateinit var sessionService: SessionService
    var isBound = false

    val connection = object : ServiceConnection {     
    override fun onServiceConnected(className: ComponentName, service: IBinder){

    val binder = service as SessionService.SessionBinder
    sessionService = binder.getService()
    sessionService.exoPlayer = activity.exoPlayer
    isBound = true

    if (!mViewModel.prefManager.sessionCompleted) {
        collectServiceStates()
        collectServiceProgress()
    }
}

override fun onServiceDisconnected(arg0: ComponentName) {
    isBound = false
}
}

val progress = sessionService.progress

字符串
1.接下来,你可以在service中使用stateflow或livedata,并像这样在片段中收集/观察它:
服务文件:

fun stopSession(){
        **curretState.value = SessionState.Stopped**
        resetValues()
        countDownTimer.cancel()
        if (isPlaying) {
            pauseAudio()
        }
    }


片段文件:

fun collectServiceStates(){
        viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
            sessionService.curretState.collectLatest {
                when(it){
                    SessionState.Paused -> {
                        pauseSession()
                    }
                    SessionState.Started -> {
                        startSession()
                    }
                    SessionState.Stopped -> {
                        stopSession()
                    }
                    SessionState.Completed -> {
                        updateMainViews(true)
                        mViewModel.prefManager.sessionCompleted=true
                    }

                    SessionState.Resumed -> {
                        resumeSession()
                    }
                    SessionState.Idle -> {

                    }
                }
            }
        }
    }


1.另一种方法是使用本地广播接收器在服务和片段之间进行通信

z6psavjg

z6psavjg2#

您可以访问官方文档页面https://developer.android.com/guide/fragments/communicate#java
但基本上有一个例子,从页面:

public class ListViewModel extends ViewModel {
private final MutableLiveData<Set<Filter>> filters = new MutableLiveData<>();

private final LiveData<List<Item>> originalList = ...;
private final LiveData<List<Item>> filteredList = ...;

public LiveData<List<Item>> getFilteredList() {
    return filteredList;
}

public LiveData<Set<Filter>> getFilters() {
    return filters;
}

public void addFilter(Filter filter) { ... }

public void removeFilter(Filter filter) { ... }
}

public class ListFragment extends Fragment {
private ListViewModel viewModel;

@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    viewModel = new ViewModelProvider(requireActivity()).get(ListViewModel.class);
    viewModel.getFilteredList().observe(getViewLifecycleOwner(), list -> {
        // Update the list UI.
    });
}
}

public class FilterFragment extends Fragment {
private ListViewModel viewModel;

@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
    viewModel = new ViewModelProvider(requireActivity()).get(ListViewModel.class);
    viewModel.getFilters().observe(getViewLifecycleOwner(), set -> {
        // Update the selected filters UI.
    });
}

public void onFilterSelected(Filter filter) {
    viewModel.addFilter(filter);
}

public void onFilterDeselected(Filter filter) {
    viewModel.removeFilter(filter);
}
}

字符串
这两个片段都使用它们的宿主Activity作为ViewModelProvider的作用域。因为这两个片段使用相同的作用域,所以它们接收相同的ViewModel示例,这使它们能够来回通信。

相关问题