【问题标题】:Method loadVideoFromAsset must be called from UI thread必须从 UI 线程调用方法 loadVideoFromAsset
【发布时间】:2017-06-27 03:25:35
【问题描述】:

我正在尝试在我的项目中实现 360 视频查看器,但我收到以下行错误:

mVrVideoView.loadVideoFromAsset("sea.mp4", options);

这是错误

Method loadVideoFromAsset must be called from the UI thread, currently inferred 
thread is worker

以下是我的代码:

package com.example.jal.jp;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;

import com.google.vr.sdk.widgets.video.VrVideoEventListener;
import com.google.vr.sdk.widgets.video.VrVideoView;

import java.io.IOException;

public abstract class VR_Video extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {

    private VrVideoView mVrVideoView;
    private SeekBar mSeekBar;
    private Button mVolumeButton;

    private boolean mIsPaused;
    private boolean mIsMuted;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vr__video);

        initViews();

    }
    public void onPlayPausePressed() {

    }

    public void onVolumeToggleClicked() {

    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {

    }

    private void initViews() {
        mVrVideoView = (VrVideoView) findViewById(R.id.video_view);
        mSeekBar = (SeekBar) findViewById(R.id.seek_bar);
        mVolumeButton = (Button) findViewById(R.id.btn_volume);
        mVrVideoView.setEventListener(new ActivityEventListener());
        mSeekBar.setOnSeekBarChangeListener(this);
        mVolumeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onVolumeToggleClicked();
            }
        });
    }
    class VideoLoaderTask extends AsyncTask<Void, Void, Boolean> {

        @Override
        protected Boolean doInBackground(Void... voids) {
            try {
                VrVideoView.Options options = new VrVideoView.Options();
                options.inputType = VrVideoView.Options.TYPE_MONO;
                mVrVideoView.loadVideoFromAsset("sea.mp4", options);
            } catch( IOException e ) {
                //Handle exception
            }

            return true;
        }
    }
    public void playPause() {

    }
    @Override
    protected void onPause() {
        super.onPause();
        mVrVideoView.pauseRendering();
        mIsPaused = true;
    }

    @Override
    protected void onResume() {
        super.onResume();
        mVrVideoView.resumeRendering();
        mIsPaused = false;
    }

    @Override
    protected void onDestroy() {
        mVrVideoView.shutdown();
        super.onDestroy();
    }
    private class ActivityEventListener extends VrVideoEventListener {
        @Override
        public void onLoadSuccess() {
            super.onLoadSuccess();
        }

        @Override
        public void onLoadError(String errorMessage) {
            super.onLoadError(errorMessage);
        }

        @Override
        public void onClick() {
            super.onClick();
        }

        @Override
        public void onNewFrame() {
            super.onNewFrame();
        }

        @Override
        public void onCompletion() {
            super.onCompletion();
        }
    }
}

请帮忙。我尽力了,但无法修复。

【问题讨论】:

  • 调用这个 VrVideoView.Options options = new VrVideoView.Options(); options.inputType = VrVideoView.Options.TYPE_MONO; mVrVideoView.loadVideoFromAsset("sea.mp4", options);在 AsyncTask 之外。不要在 doInBackground 中调用它。
  • 在哪里写外面?我试过但没有成功。我是Android新手,正在努力学习。如果您可以将其添加到我的代码中并显示,那就太好了。非常感谢。
  • 您在哪里调用 VideoLoaderTask.execute()?在“mVrVideoView.setEventListener(new ActivityEventListener());”之后立即尝试这三行调用。不在后台做。
  • 我按照你说的做了,但是它显示了一个错误。 “未处理的异常 Java.io.IOException”
  • 你必须像这样把它放在 try 和 catch 中 try { VrVideoView.Options options = new VrVideoView.Options(); options.inputType = VrVideoView.Options.TYPE_MONO; mVrVideoView.loadVideoFromAsset("sea.mp4", options); } catch( IOException e ) { //处理异常 }

标签: android virtual-reality 360-degrees 360-virtual-reality


【解决方案1】:

从 UI 线程中移除 AsyncTask 实现和调用所需方法

使用下面的代码:

private void initViews() {
    mVrVideoView = (VrVideoView) findViewById(R.id.video_view);
    mSeekBar = (SeekBar) findViewById(R.id.seek_bar);
    mVolumeButton = (Button) findViewById(R.id.btn_volume);
    mVrVideoView.setEventListener(new ActivityEventListener());
    try {
            VrVideoView.Options options = new VrVideoView.Options();
            options.inputType = VrVideoView.Options.TYPE_MONO;
            mVrVideoView.loadVideoFromAsset("sea.mp4", options);
        } catch( IOException e ) {
            //Handle exception
        }
    mSeekBar.setOnSeekBarChangeListener(this);
    mVolumeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            onVolumeToggleClicked();
        }
    });
}

【讨论】:

    【解决方案2】:

    我对 videoview 了解不多,但我在您的代码中显示您正在尝试访问 doInbackground 方法中的一些功能。 doINbackground 方法在与 UI 线程不同的线程上运行,因此复杂的 ant 耗时任务不会阻塞 UI 线程。您可以在 onCreate 方法中实现您在 doINbackground 方法中实现的功能,或者如果您仍需要使用 doInbackground,您可以使用 runOnUiThread 访问 doInbackground 中的 UI 线程,如下所示

    runOnUiThread(new Runnable() { @Override public void run() { //your code here } });

    【讨论】:

    • 谢谢。你能告诉我把你给的代码块放在哪里吗?
    • protected Boolean doInBackground(Void... voids) { try { runOnUiThread(new Runnable() { public void run() { //你的代码在这里 VrVideoView.Options options = new VrVideoView.Options() ; options.inputType = VrVideoView.Options.TYPE_MONO; mVrVideoView.loadVideoFromAsset("sea.mp4", options); } 我收到一个错误。未处理的异常 Java.io.IOException。
    • 无法为您提供这么多信息。您需要提供您的代码和日志错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多