- 获取视频数据:通过网络请求将视频文件下载到本地,或者直接提供一个网络地址。
- 播放视频数据:使用 Android 的媒体播放器组件来解析并播放这些数据。
下面我将介绍三种最主流的实现方式,并附上代码示例。

使用 VideoView (最简单、最推荐)
VideoView 是 Android 提供的一个高级组件,它封装了 MediaPlayer 的复杂操作,使用起来非常简单,适合快速实现视频播放功能。
添加网络权限
在 AndroidManifest.xml 文件中,必须添加访问网络的权限。
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application ...>
...
</application>
</manifest>
布局文件 activity_main.xml
在布局文件中添加 VideoView 控件。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
</RelativeLayout>
逻辑代码 MainActivity.java
在 Activity 中,通过 VideoView 的 setVideoPath() 方法设置网络视频 URL,然后调用 start() 开始播放。

import androidx.appcompat.app.AppCompatActivity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.MediaController;
import android.widget.VideoView;
public class MainActivity extends AppCompatActivity {
private VideoView videoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoView = findViewById(R.id.videoView);
// 设置视频控制器(播放/暂停、进度条、音量等)
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
// 网络视频URL (这里使用一个示例视频)
String videoUrl = "https://www.learningcontainer.com/wp-content/uploads/2025/05/sample-mp4-file.mp4";
// 设置视频路径
videoView.setVideoURI(Uri.parse(videoUrl));
// 开始播放
videoView.start();
// 可选:监听播放完成事件
videoView.setOnCompletionListener(mp -> {
// 视频播放完毕后的操作
System.out.println("Video finished playing.");
});
// 可选:监听加载错误事件
videoView.setOnErrorListener((mp, what, extra) -> {
// 视频加载或播放出错时的操作
System.out.println("Error playing video: " + what + ", " + extra);
return true;
});
}
}
优点:
- 简单易用:几行代码就能实现播放功能。
- 自带控制器:
MediaController提供了标准的播放控制界面。
缺点:
- 功能有限:无法进行高度定制化的播放控制。
- 性能一般:对于需要快速seek(跳转)或处理非常规格式的视频,性能可能不佳。
使用 ExoPlayer (Google官方推荐,功能强大)
ExoPlayer 是 Google 官方推出的媒体播放器,是 MediaPlayer 的现代替代品,它功能更强大、更灵活、性能更好,并且支持更广泛的媒体格式(特别是 DASH 和 HLS 等自适应流媒体协议)。
添加依赖
在 app/build.gradle 文件中添加 ExoPlayer 的依赖。

dependencies {
// ExoPlayer 核心库
implementation 'androidx.media3:media3-exoplayer:1.3.1'
// ExoPlayer UI 库 (用于提供默认的控制器)
implementation 'androidx.media3:media3-ui:1.3.1'
// ExoPlayer 媒体会话库 (用于后台播放等)
implementation 'androidx.media3:media3-session:1.3.1'
}
注意:请务必使用最新的稳定版本号。
布局文件 activity_main.xml
使用 ExoPlayerView 替代 VideoView。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.media3.ui.PlayerView
android:id="@+id/playerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:use_controller="true" /> <!-- 设置为 true 显示控制器 -->
</FrameLayout>
逻辑代码 MainActivity.java
在 Activity 中初始化 ExoPlayer 并设置数据源。
import androidx.appcompat.app.AppCompatActivity;
import androidx.media3.common.MediaItem;
import androidx.media3.common.Player;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.ui.PlayerView;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private PlayerView playerView;
private ExoPlayer exoPlayer;
@Override
protected void void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerView = findViewById(R.id.playerView);
// 1. 创建 ExoPlayer 实例
exoPlayer = new ExoPlayer.Builder(this).build();
// 2. 将 PlayerView 的播放器设置为我们的 ExoPlayer 实例
playerView.setPlayer(exoPlayer);
// 3. 创建 MediaItem
String videoUrl = "https://www.learningcontainer.com/wp-content/uploads/2025/05/sample-mp4-file.mp4";
MediaItem mediaItem = MediaItem.fromUri(videoUrl);
// 4. 设置并准备播放
exoPlayer.setMediaItem(mediaItem);
exoPlayer.prepare();
// 5. 开始播放
exoPlayer.play();
// 监听播放状态变化
exoPlayer.addListener(new Player.Listener() {
@Override
public void onPlaybackStateChanged(int playbackState) {
if (playbackState == Player.STATE_ENDED) {
// 视频播放完毕
System.out.println("Video finished playing.");
}
}
});
}
@Override
protected void void onDestroy() {
super.onDestroy();
// 6. 释放播放器资源,防止内存泄漏
if (exoPlayer != null) {
exoPlayer.release();
exoPlayer = null;
}
}
}
优点:
- 功能强大:支持自适应流媒体、DRM、高级视频效果等。
- 性能优越:缓存机制好,启动快,seek 流畅。
- 高度可定制:可以完全自定义 UI 和播放行为。
- 持续更新:由 Google 维护,与 Android 生态结合紧密。
缺点:
- 相对复杂:比
VideoView需要更多的代码来初始化和配置。 - 包体积稍大:引入了额外的库。
使用 MediaPlayer + SurfaceView (最底层,灵活但复杂)
这是最底层的实现方式,它不提供任何 UI,你需要自己绘制视频画面和处理所有控制逻辑,它适用于需要完全自定义播放体验的场景。
布局文件 activity_main.xml
使用 SurfaceView 作为视频渲染的“画布”。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
逻辑代码 MainActivity.java
你需要手动管理 MediaPlayer 的生命周期,并将其与 SurfaceView 关联。
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
mediaPlayer = new MediaPlayer();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// SurfaceView 创建完成,可以在这里设置视频源并开始播放
try {
String videoUrl = "https://www.learningcontainer.com/wp-content/uploads/2025/05/sample-mp4-file.mp4";
mediaPlayer.setDataSource(this, Uri.parse(videoUrl));
mediaPlayer.setDisplay(surfaceHolder); // 将 MediaPlayer 的输出绑定到 SurfaceView
mediaPlayer.prepareAsync(); // 异步准备,避免阻塞UI线程
mediaPlayer.setOnPreparedListener(mp -> mp.start());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// SurfaceView 的缓冲区大小改变时调用
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// SurfaceView 销毁时,必须停止并释放 MediaPlayer
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 再次确保资源被释放
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
}
优点:
- 完全控制:对播放的每一个环节都有绝对的控制权。
- 轻量级:不依赖复杂的 UI 组件。
缺点:
- 非常复杂:需要手动处理 UI 绘制、播放控制、错误处理等所有事情。
- 开发成本高:代码量大,容易出错。
总结与选择建议
| 特性 | VideoView |
ExoPlayer |
MediaPlayer + SurfaceView |
|---|---|---|---|
| 易用性 | ⭐⭐⭐⭐⭐ (非常简单) | ⭐⭐⭐ (中等) | ⭐ (非常复杂) |
| 功能/定制性 | ⭐ (有限) | ⭐⭐⭐⭐⭐ (非常强大) | ⭐⭐⭐⭐⭐ (完全控制) |
| 性能 | 一般 | 优秀 | 优秀 |
| 适用场景 | 快速原型、简单播放 | 生产环境、绝大多数应用、流媒体播放 | 游戏、视频编辑器等需要深度定制的场景 |
如何选择?
- 新手或快速开发:直接使用
VideoView,它能满足 80% 的简单播放需求。 - 正式的商业项目或 App:强烈推荐使用
ExoPlayer,它是未来的趋势,功能、性能和可维护性都更好,Google 的官方 App(如 YouTube)也在使用它。 - 有特殊需求:如果你的应用需要将视频作为游戏背景、实现自定义的视频滤镜或特效,那么使用
MediaPlayer+SurfaceView是唯一的选择。
