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

基于NanoHTTPD Android库实现YouTube播放的功能整合问题咨询

问题核心原因

  • NanoHTTPD的serve回调运行在独立后台线程,安卓不允许在非UI线程操作View相关逻辑,你直接在serve中调用youtube方法操作YouTubePlayerView属于UI操作,会抛出线程异常
  • 每次提交表单都调用YouTubePlayerView的initialize方法重复初始化,不需要多次初始化,只需初始化一次后缓存播放器实例直接调用loadVideo即可
  • MainActivity中ytPlayer变量重复声明,成员变量未赋值的冗余问题也可同步优化

修复代码

1. 修改MainActivity.class

提前初始化播放器,提供主线程执行的播放方法供WebServer调用

package com.martin.androidwebplayer;

import android.os.Bundle;
import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerView;

public class MainActivity extends YouTubeBaseActivity {

    private AndroidWebServer aws;
    // 缓存初始化完成的播放器实例
    private YouTubePlayer mYouTubePlayer;
    // 替换为你自己的YouTube API密钥
    private static final String API_KEY = "你的实际YouTube API密钥";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        YouTubePlayerView ytPlayer = findViewById(R.id.ytPlayer);
        // 提前一次性初始化播放器
        ytPlayer.initialize(API_KEY, new YouTubePlayer.OnInitializedListener() {
            @Override
            public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) {
                mYouTubePlayer = youTubePlayer;
            }

            @Override
            public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
                // 可自行添加初始化失败的提示逻辑
            }
        });
        aws = new AndroidWebServer(8180, MainActivity.this);
    }

    // 提供给WebServer调用的播放方法,自动切到UI线程执行操作
    public void playYoutubeVideo(String videoId) {
        if (mYouTubePlayer == null || videoId == null || videoId.trim().isEmpty()) return;
        runOnUiThread(() -> {
            mYouTubePlayer.loadVideo(videoId);
            mYouTubePlayer.play();
        });
    }
}

2. 修改AndroidWebServer.class

删掉原有重复初始化播放器的逻辑,收到POST参数后直接调用MainActivity的播放方法即可

package com.martin.androidwebplayer;

import android.content.Context;
import fi.iki.elonen.NanoHTTPD;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class AndroidWebServer extends NanoHTTPD {

    private static final String TAG = "HTTPServer";
    private Context ctx;

    public AndroidWebServer(int port, Context ctx) {
        super(port);
        this.ctx = ctx;
        try {
            Log.d(TAG, "Starting web server..");
            start();
        } catch(IOException ioe) {
            Log.e(TAG, "Unable to start the server");
            ioe.printStackTrace();
        }
    }

    @Override
    public Response serve(IHTTPSession session) {
        Map<String, String> parms = session.getParms();
        String content = readFile().toString();
        if (session.getMethod() == Method.POST) {
            Map<String, String> files = new HashMap<>();
            try {
                session.parseBody(files);
            } catch (IOException | ResponseException e) {
                e.printStackTrace();
            }
            String videoId = parms.get("fname");
            // 调用MainActivity的播放方法
            if (ctx instanceof MainActivity) {
                ((MainActivity) ctx).playYoutubeVideo(videoId);
            }
            return newFixedLengthResponse("播放请求已提交,视频ID:" + videoId);
        }
        return newFixedLengthResponse(content);
    }

    private StringBuffer readFile() {
        BufferedReader reader = null;
        StringBuffer buffer = new StringBuffer();
        try {
            reader = new BufferedReader(new InputStreamReader(ctx.getAssets().open("index.html"), "UTF-8"));
            String mLine;
            while ((mLine = reader.readLine()) != null) {
                buffer.append(mLine);
                buffer.append("\n");
            }
        } catch(IOException ioe) {
            ioe.printStackTrace();
        } finally {
            if (reader != null)
                try {
                    reader.close();
                } catch (IOException ioe) {}
        }
        return buffer;
    }

    public void stopServer() {
        this.stop();
    }
}

3. 可选优化assets/index.html

避免IP变动导致请求失败,可把ajax的请求地址改为相对路径,将原代码中url: "http://192.168.100.42:8180",修改为url: "/",即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:45:08