gpt4 book ai didi

android - VideoView 安卓

转载 作者:行者123 更新时间:2023-11-30 02:44:43 27 4
gpt4 key购买 nike

我正在开发具有两个 View 的应用程序,一个是 UI,另一个是 VideoView。在某些事件发生之前使用 UI 线程,然后我想将 setContentView 设置为 VideoView,但是在将内容 View 从 UI 设置为 VideoView 时出现错误.对于 VideoView,我使用以下代码:

Java

setContentView(R.layout.videoview);
VideoView = (VideoView) findViewById(R.id.videoview);
String path= "android.resource://"+getPackageName()+"/"+R.raw.vid;
VideoView.setVideoURI(Uri.parse(path));
VideoView.start();

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<VideoView
android:id="@+id/videoview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

这是我遇到的错误:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

我做错了什么?

编辑 0:来自 UI 线程的代码:

public class View extends SurfaceView implements Runnable{

Thread Thread = null;
SurfaceHolder SurfaceHolder;
boolean Play;

public View(Context context){
super(context);
SurfaceHolder=getHolder();
}

@Override
public void run() {
while(Play){

if(!SurfaceHolder.getSurface().isValid())
continue;
//drawing
if(something)
Video();
}

public void Pause(){
//called from onPause()
Play=false;
while(true){
try {
if(Thread!=null)
Thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
Thread=null;
}

public void Resume(){
//called from onResume()
Play=true;
Thread = new Thread(this);
Thread.start();
}

public void Video(){
setContentView(R.layout.videoview);
VideoView = (VideoView) findViewById(R.id.videoview);
String path= "android.resource://"+getPackageName()+"/"+R.raw.vid;
VideoView.setVideoURI(Uri.parse(path));
VideoView.start();
}
}

最佳答案

您从非 UI 线程调用 setContentView()

public class View extends SurfaceView implements Runnable{  
@Override
public void run() {
while(Play){
if(!SurfaceHolder.getSurface().isValid())
continue;
//drawing
if(something)
Video();
}
}

public void Resume() {
//called from onResume()
Play=true;
Thread = new Thread(this);
Thread.start();
}

public void Video(){
setContentView(R.layout.videoview);
/* more code */
}
}

onResume 被调用,它创建一个新的 Thread (Thread = new Thread(this);),你开始,所以 void run() 被调用(记住,来自您刚刚创建的非 ui 线程)。 run() 调用 video(),后者又调用 setContentView()。瞧,您从非 UI 线程调用了 setContentView()

您不应该让 View 实现runnable,更不用说让 View 管理线程了。它由 UI 线程管理,没有其他。一种可能是从 View 中获取上下文并使用 runOnUiThread(Runnable r) 方法,但更好的是:让 UI 线程执行 UI 工作,例如显示视频。

// I think even this might work. Not 100% sure, I do this out of the top of my head.
public void onResume() {
if (condition)
getContext().runOnUiThread(new Runnable() {
public void run() {
video();
}
});
}

关于android - VideoView 安卓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25264497/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com