You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVVM架构下ExoPlayer初始化问题求助:ViewModel无法持有Context

解决ViewModel中初始化ExoPlayer的Context问题

嘿,这个问题我之前在项目里也踩过坑——ViewModel确实不能持有和UI组件绑定的Context,但ExoPlayer初始化又离不开它,给你两个符合MVVM规范且安全的解决方案,完全不会造成内存泄漏:

方案一:使用AndroidViewModel(最简单直接)

AndroidViewModel是ViewModel的子类,专门为Android场景设计,它本身就持有Application实例,不需要额外传参,非常省心。

代码示例(Java)

import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;

public class PlayerViewModel extends AndroidViewModel {
    private final ExoPlayer exoPlayer;

    public PlayerViewModel(@NonNull Application application) {
        super(application);
        // 初始化轨道选择器
        DefaultTrackSelector trackSelector = new DefaultTrackSelector(application);
        // 替代废弃的ExoPlayerFactory,用官方推荐的Builder创建实例
        exoPlayer = new ExoPlayer.Builder(application)
                .setTrackSelector(trackSelector)
                .build();
    }

    // 播放操作方法
    public void play() {
        exoPlayer.play();
    }

    public void pause() {
        exoPlayer.pause();
    }

    public void switchTrack(MediaItem mediaItem) {
        exoPlayer.setMediaItem(mediaItem);
        exoPlayer.prepare();
        exoPlayer.play();
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        // 务必在ViewModel销毁时释放播放器资源,避免内存泄漏
        exoPlayer.release();
    }
}

在Activity/Fragment中获取ViewModel

PlayerViewModel viewModel = new ViewModelProvider(this).get(PlayerViewModel.class);

方案二:自定义ViewModelFactory传入Application Context

如果不想用AndroidViewModel,也可以自定义ViewModelFactory,把Application Context传入普通的ViewModel中,这种方式灵活性更高。

自定义ViewModelFactory(Java)

import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

public class PlayerViewModelFactory implements ViewModelProvider.Factory {
    private final Application application;

    public PlayerViewModelFactory(Application application) {
        this.application = application;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        if (modelClass.isAssignableFrom(PlayerViewModel.class)) {
            return (T) new PlayerViewModel(application);
        }
        throw new IllegalArgumentException("Unknown ViewModel class");
    }
}

普通ViewModel实现(Java)

import android.app.Application;
import androidx.lifecycle.ViewModel;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;

public class PlayerViewModel extends ViewModel {
    private final ExoPlayer exoPlayer;

    public PlayerViewModel(Application application) {
        DefaultTrackSelector trackSelector = new DefaultTrackSelector(application);
        exoPlayer = new ExoPlayer.Builder(application)
                .setTrackSelector(trackSelector)
                .build();
    }

    // 播放操作方法和方案一一致
    public void play() {
        exoPlayer.play();
    }

    public void pause() {
        exoPlayer.pause();
    }

    public void switchTrack(MediaItem mediaItem) {
        exoPlayer.setMediaItem(mediaItem);
        exoPlayer.prepare();
        exoPlayer.play();
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        exoPlayer.release();
    }
}

在Activity/Fragment中获取ViewModel

PlayerViewModel viewModel = new ViewModelProvider(this, new PlayerViewModelFactory(getApplication()))
        .get(PlayerViewModel.class);

关键注意事项

  • 必须用Application Context:绝对不能传入Activity/Fragment的Context,因为ViewModel的生命周期比UI组件长,持有组件Context会导致严重的内存泄漏。
  • 及时释放资源:一定要在onCleared()方法中调用exoPlayer.release(),这是ViewModel被销毁时的回调,用来清理播放器占用的系统资源。
  • 废弃API替换:你代码里用的ExoPlayerFactory已经被官方废弃,现在推荐使用ExoPlayer.Builder来创建实例,兼容最新版本的ExoPlayer,功能更完善。

内容的提问来源于stack exchange,提问作者Muhamed Raafat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:41:12