gpt4 book ai didi

Android SurfaceView 不在纵向模式下创建

转载 作者:行者123 更新时间:2023-11-29 02:08:21 27 4
gpt4 key购买 nike

我有一个带有自定义 SurfaceView 类和一些按钮的简单 LinearLayout。以前我在 Manifest 的 Activity 标签中强制将方向设置为 Landscape,但现在我需要将其设置为纵向。出于某种原因,当我强制使用方向肖像时,不会创建 SurfaceView。我通过仅使用单个 FrameLayout 并在其中使用我的 SurfaceView 类的单个实例来测试布局,但它仍然无法正确创建。

我得到的错误取决于 SurfaceView 中 Thread 的第一个实例是什么。通常是我的 UI 线程在 onCreate 中请求线程句柄导致 NullPointerException。

知道为什么我的代码可以横向运行而不是纵向运行吗?如果我不选择方向然后将其从横向旋转为纵向,也会出现同样的问题。

编辑:这是我的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<stu.test.project.DrawingSurface
android:layout_width="fill_parent"
android:layout_height="700dp"
android:id="@+id/drawingSurface"/>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/ButtonRow1"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/ButtonRow2"/>
</LinearLayout>
</LinearLayout>

这里是调用surfaceView的Activity的onCreate,错误位于最后一行获取线程句柄的地方

public void onCreate(Bundle savedInstanceState) {  
super.onCreate(savedInstanceState);
setContentView(R.layout.drawing_layout);



// Retrieve STATE and patient number from intent
bundle = this.getIntent().getExtras();
STATE = bundle.getInt("state");
patientString = bundle.getString("patientString");

//retrieveViews();
showButtons();

System.out.println("IN ONCREATE");

// Setup initial stuff if creating rather than resuming
if (savedInstanceState==null){
System.out.println("IN ONCREATE AND NO SIS");
switch(STATE){
case STATE_DRAW:
setupDraw();
break;
case STATE_LOAD:
setupLoad();
drawLoad();
break;
}
}

/* Should put Else in here
* to maybe resume data from savedInstanceState
* rather than using onSurfaceCreated as do at moment
*/

// Retrieve handle to thread
mThread = drawingSurface.getThread();

}

这里是 SurfaceView 类,不确定什么是相关的所以全部复制:

public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {
private boolean _run;
private Object mPauseLock = new Object();
private boolean mPaused;
private int STATE;
private static final int STATE_DRAW=1;
private static final int STATE_LOAD=2;
private static final int STATE_PAUSED=4;
private static final int STATE_RESUME_DRAWING=5;
private boolean finishDrawing;
private boolean startedDrawing=true;
private int resetCanvas=0;
private boolean threadRunning;
protected DrawThread thread;
boolean loaded;

public DrawingSurface(Context context, AttributeSet attrs) {
super(context, attrs);

getHolder().addCallback(this);
thread = new DrawThread(getHolder());
}


class DrawThread extends Thread{
private SurfaceHolder mSurfaceHolder;
private List<DrawingPath> mDrawingPaths;
private List<MyLine> mMyLines, backupLines;
private Paint mPaint;

public DrawThread(SurfaceHolder surfaceHolder){
mSurfaceHolder = surfaceHolder;
mDrawingPaths = Collections.synchronizedList(new ArrayList<DrawingPath>());
mMyLines = Collections.synchronizedList(new ArrayList<MyLine>());
}

public void setRunning(boolean run) {
_run = run;
}

public void setBackupLine(List<MyLine> l){
backupLines = l;
System.out.println("SETUP BACKLINE SIZE IS: "+backupLines.size());
}

// Two methods for your Runnable/Thread class to manage the Thread properly.
public void onPause() {
synchronized (mPauseLock) {
// Only pause if not finished drawing, if finished want to exit thread
if (!finishDrawing){
mPaused = true;
loaded=false;
}
}
System.out.println("Set mPaused = true");
}

public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
System.out.println("Set mPaused = false");
// // Load the saved drawings or reload
// if (STATE == STATE_DRAW)
// setState(STATE_RESUME_DRAWING);
// // If loading then dont change state and instead just restart thread
// else if (STATE == STATE_LOAD){
//// resumeDrawing();
// setRunning(true);
// }

}

public boolean needToWait(){
return finishDrawing||mPaused;
}

public void setFinishDrawing(boolean b){
finishDrawing=b;
}

public void setReset(int reset){
resetCanvas=reset;
}

public void addMyLines(List<MyLine> lines){
mMyLines = lines;
}

public void addDrawingPath(DrawingPath drawingPath){

mDrawingPaths.add( drawingPath );
}

public int getSizeDrawingPaths(){
return mDrawingPaths.size();
}

public void setLoadPaint(Paint p){
mPaint = p;
}

public DrawingPath getDrawingPath(int index){
return mDrawingPaths.get(index);
}

@Override
public void run() {
while (_run){
// Set variable for running
threadRunning=true;
Canvas canvas = null;

// This code pauses the thread
synchronized (mPauseLock) {
while (mPaused) {
try {
mPauseLock.wait();
System.out.println("IN PAUSE LOOP");
} catch (InterruptedException e) {
}
}
}

try{
canvas = mSurfaceHolder.lockCanvas(null);

// Split into DRAW and LOAD

// DRAW IMAGE FROM PATHS
if (STATE == STATE_DRAW){
synchronized(mDrawingPaths) {
// If not finished drawing or resetthen draw onto canvas
if (!finishDrawing&&resetCanvas==0){
// // Draw screen white
// if (startedDrawing){
// startedDrawing=false;
// canvas.drawColor(Color.WHITE);
// System.out.println("DRAWING CANVAS WHITE");
//
// }
doDraw(canvas);
}
}
if (resetCanvas>0){
System.out.println("Resetting canvas");
if (canvas!=null)
canvas.drawColor(Color.WHITE);
resetCanvas--;
}
}

// DRAW IMAGE FROM POINTS
else if (STATE == STATE_LOAD){
doLoad(canvas, mMyLines);
// Then close the thread
setRunning(false);
}

// IF RESUMING FROM DRAWING PAUSE
else if (STATE == STATE_RESUME_DRAWING){
if (!loaded) {
doLoad(canvas, backupLines);
System.out.println("DID LOAD OF RESUME");
setState(STATE_DRAW);
loaded=true;
//setRunning(false);
}
}
}
finally {
if (canvas!=null){
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
} // While run
}

public void doDraw(Canvas c){
@SuppressWarnings("rawtypes")
Iterator i = mDrawingPaths.iterator();
while (i.hasNext()){
final DrawingPath drawingPath = (DrawingPath) i.next();
if (c==null)
System.out.println("CANVAS IS NULL");
else if (drawingPath.path==null)
System.out.println("PATH IS NULL");
else if (drawingPath.paint==null)
System.out.println("PAINT IS NULL");
if (c!=null) // Only draw to canvas if it isnt null
c.drawPath(drawingPath.path, drawingPath.paint);
}
}

public void doLoad(Canvas c, List<MyLine> lines){
// Loop through the List of lines
@SuppressWarnings("rawtypes")
Iterator i = lines.iterator();
while(i.hasNext()){
// Get the current line
final MyLine lineIt = (MyLine) i.next();
// Create new array of floating points to hold the PointFs from MyLine to draw
float prevX=0, prevY=0;
for (int j=0;j<lineIt.getSize()-1;j=j+2){
if (c==null)
System.out.println("CANVAS IS NULL");
if (j!=0&&c!=null){
c.drawLine(prevX, prevY, lineIt.getPoint(j).x, lineIt.getPoint(j+1).y, mPaint);
}
prevX = lineIt.getPoint(j).x;
prevY = lineIt.getPoint(j+1).y;
}
}
}

public void remove(int i) {
mDrawingPaths.remove(i);

}

public void clearAllPaths(){
mDrawingPaths.clear();
}

public void setState(int s){
STATE = s;
}

}


public void addDrawingPath (DrawingPath drawingPath){
thread.addDrawingPath(drawingPath);
}

public int getSizeDrawingPaths(){
return thread.getSizeDrawingPaths();
}

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}

public void surfaceCreated(SurfaceHolder holder) {
// only create thread if doesnt exist
if (!threadRunning){
thread.setRunning(true);
thread.setFinishDrawing(false);
thread.setReset(2); // Set reset to colour screen white
thread.start();
}
// // Resuming is handled in DrawingActivity's onPause override
// else {
// thread.onResume();
// }
}

public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
// If finished drawing then close thread
// Else just want to pause thread
// if (finishDrawing){
// thread.setRunning(false);
// while (retry) {
// try {
// thread.join();
// retry = false;
// threadRunning = false; // Set threadRunning to false so creates new thread when rejoins
// } catch (InterruptedException e) {
// // we will try it again and again...
// }
// }
// }
// else {
// thread.onPause();
// System.out.println("Paused thread in SurfaceDestroyed");
// System.out.println("threadRunning is :"+threadRunning);
// }


}

public void remove(int i) {
thread.remove(i);

}

public void getDrawingPath(int i){
thread.getDrawingPath(i);
}

public void clearAllPaths(){
thread.clearAllPaths();
}

public void resetScreen(){
thread.setReset(2);
}

public void addMyLines(List<MyLine> lines){
thread.addMyLines(lines);
}

public void finishDrawing(){
thread.setFinishDrawing(true);
}

public DrawThread getThread(){
return thread;
}

public void resumeDrawing(){
thread.setFinishDrawing(false);
}

public void setState(int s){
thread.setState(s);
}

public void setLoadPaint(Paint p){
thread.setLoadPaint(p);
}

public void pauseThread(){
thread.onPause();
}

public void resumeThread(){
thread.onResume();
}

public boolean getThreadRunning(){
return threadRunning;
}
}

最佳答案

纵向和横向是否有相同的布局文件?

今天我遇到了一个类似的问题,我在纵向布局文件中有 surfaceView,但在横向布局文件中没有。由于某种原因它运行了但是当我旋转设备时 surfaceCreated|Changed|Destroyed 不再发生。旋转回来,一切又是快乐的。

关于Android SurfaceView 不在纵向模式下创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8746693/

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