Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android surfaceview冻结_Java_Android_Surfaceview - Fatal编程技术网

Java Android surfaceview冻结

Java Android surfaceview冻结,java,android,surfaceview,Java,Android,Surfaceview,我想在surfaceview上创建动画。 下面是一个表面视图: public class AnimationSurfaceView extends SurfaceView implements SurfaceHolder.Callback{ private AnimationWorker animationWorker; private GestureDetectorCompat mGestureDetector; private OverScroller mScroller; private

我想在surfaceview上创建动画。 下面是一个表面视图:

public class AnimationSurfaceView extends SurfaceView implements SurfaceHolder.Callback{

private AnimationWorker animationWorker;
private GestureDetectorCompat mGestureDetector;
private OverScroller mScroller;
private Cursor mCursor;
private int pIndexA, pIndexB;
private int dir;

private float posX=0;

public AnimationSurfaceView(Context context, Cursor cursor) {
    super(context);
    getHolder().addCallback(this);
    mCursor = cursor;
    mGestureDetector = new GestureDetectorCompat(context, mGestureListener);
    mScroller = new OverScroller(context);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    animationWorker = new AnimationWorker(getHolder(), getContext(), null);
    animationWorker.setRunning(true);
    animationWorker.run();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    animationWorker.setRunning(false);
    animationWorker.postTask(null);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.e("sfsfsfdf", "Работает1!!!!!!!!!!!!!!!!!!!");
    boolean retVal = mGestureDetector.onTouchEvent(event);
    return retVal || super.onTouchEvent(event);

}

@Override
public void computeScroll() {
    super.computeScroll();
    if(mCursor != null){
        int i1 = Math.max(0,Math.min(mCursor.getCount()-1, (int)Math.floor(posX/720f)));
        int i2 = Math.max(0,Math.min(mCursor.getCount()-1, (int)Math.ceil(posX/720f)));
        if(i1 != pIndexA){
            dir = i1-pIndexA;
            pIndexA = i1;
            pIndexB = i2;
        }
    }
}

private void updateWorker(){
    animationWorker.postTask(new AnimationTask(posX, dir));
    AnimationWorker.syncObj.notifyAll();
}

private final GestureDetector.SimpleOnGestureListener mGestureListener
        = new GestureDetector.SimpleOnGestureListener() {


    @Override
    public boolean onDown(MotionEvent e) {
        mScroller.forceFinished(true);
        animationWorker.cancelTaskQueue();
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        return true;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
                            float distanceX, float distanceY) {
        posX += -distanceX;
        updateWorker();
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                           float velocityY) {
        velocityX = - velocityX;
        fling(velocityX);
        return true;
    }

    private void fling(float velocity){
        mScroller.forceFinished(true);
        mScroller.fling((int) posX, 0, (int) -velocity, 0, 0, 720 * (mCursor != null ? mCursor.getCount() : 1), 0, 0);
        updateWorker();
    }
};
下面是一位工人:

public class AnimationWorker extends Thread {

private static final String LOG_TAG = AnimationWorker.class.getSimpleName();
public static final Object syncObj = new Object();

private boolean runFlag = false;
private SurfaceHolder surfaceHolder;
private Context context;
private BlockingQueue<AnimationTask> queue;
private Cursor mCursor;
private AnimationImageCacheHelper animationImageCacheHelper;
private final String ASSET_SUFFIX = "assets://";
private final String FILE_SUFFIX = "file://";

Rect clipRect;
Rect bitmapRect;
Paint paint;
Pair<Bitmap, Bitmap> bitmaps;
int mLeftIndex;
int mRightIndex;

private final Float TRACK_LENTH = 720f;
private final Float MAX_ALPHA = 255f;

public AnimationWorker(
        SurfaceHolder surfaceHolder,
        Context context,
        Cursor cursor){
    super();
    this.surfaceHolder = surfaceHolder;
    this.animationImageCacheHelper = new AnimationImageCacheHelper();
    bitmapRect = new Rect();
    paint = new Paint();
    clipRect = new Rect();
    queue = new LinkedBlockingDeque<AnimationTask>();
}

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

public void postTask(AnimationTask task){
    try {
        queue.put(task);
    }catch (Exception e){
        //do nothing
    }
}

public void cancelTaskQueue(){
    queue.clear();
}

@Override
public void run() {

    while(runFlag){
        Log.e(LOG_TAG, "running");
        try {
            AnimationTask task = queue.remove();
            if(task != null) {
                processTask(task);
            }
        }catch(Exception e){
            try {
                synchronized (syncObj) {
                    syncObj.wait();
                }
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            Log.e(LOG_TAG, "exception");
            e.printStackTrace();
        }
    }
}

private void processTask(AnimationTask task){
    int leftIndex = Math.max(0,Math.min(mCursor.getCount()-1, (int)Math.floor(task.currentPosition/TRACK_LENTH.intValue())));
    int rightIndex = Math.max(0,Math.min(mCursor.getCount()-1, (int)Math.ceil(task.currentPosition/TRACK_LENTH.intValue())));
    if(mLeftIndex != leftIndex || mRightIndex != rightIndex){
        bitmaps = getBitmaps(leftIndex, rightIndex, task.direction);
    }
    float alpha = (MAX_ALPHA / TRACK_LENTH * task.currentPosition) % MAX_ALPHA;
    draw(bitmaps.first, bitmaps.second, alpha);
}

private Pair<Bitmap, Bitmap> getBitmaps(int leftIndex, int rightIndex, int direction){
    final Bitmap foregroundBitmap;
    final Bitmap backgroundBitmap;
    final Pair<Bitmap, Bitmap> result;
    if(direction == 1) {
        //right on top
        if(mCursor.moveToPosition(leftIndex)){
            String backgroundImageUrl = mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
            backgroundBitmap = loadImage(backgroundImageUrl);
        }else{
            backgroundBitmap = null;
        }
        if (mCursor.moveToPosition(rightIndex)){
            String foregroundImageUrl = mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
            foregroundBitmap = loadImage(foregroundImageUrl);
        }else{
            foregroundBitmap = null;
        }
    } else {
        //left on top
        if(mCursor.moveToPosition(rightIndex)){
            String backgroundImageUrl = mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
            backgroundBitmap = loadImage(backgroundImageUrl);
        }else{
            backgroundBitmap = null;
        }
        if (mCursor.moveToPosition(leftIndex)){
            String foregroundImageUrl = mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
            foregroundBitmap = loadImage(foregroundImageUrl);
        }else{
            foregroundBitmap = null;
        }
    }
    result = new Pair<Bitmap, Bitmap>(foregroundBitmap, backgroundBitmap);
    return result;
}

private Bitmap loadImage(String uri){
    if(animationImageCacheHelper.isImageContains(uri)){
        return animationImageCacheHelper.getBitmap(uri);
    }
    if (uri.startsWith(ASSET_SUFFIX)) {
        Bitmap bitmap = ImageLoader.getInstance().loadImageSync(uri);
        animationImageCacheHelper.put(uri, bitmap);
        return bitmap;
    } else {
        Bitmap bitmap = ImageLoader.getInstance().loadImageSync("file://" + uri);
        animationImageCacheHelper.put(uri, bitmap);
        return bitmap;
    }
}

private void draw(Bitmap foreground, Bitmap background, float alpha){
    Canvas canvas;
    canvas = null;
    try {
        canvas = surfaceHolder.lockCanvas(null);
        canvas.getClipBounds(clipRect);
        synchronized (surfaceHolder) {
            //draw background
            paint.setAlpha(255);
            bitmapRect.set(0, 0, background.getWidth(), background.getHeight());
            canvas.drawBitmap(background, bitmapRect, clipRect, paint);

            //draw foreground
            paint.setAlpha((int)alpha);
            bitmapRect.set(0, 0, foreground.getWidth(), foreground.getHeight());
            canvas.drawBitmap(foreground, bitmapRect, clipRect, paint);
        }
    }finally {
        if (canvas != null) {
            surfaceHolder.unlockCanvasAndPost(canvas);
        }
    }
}
public类AnimationWorker扩展线程{
私有静态最终字符串LOG_TAG=AnimationWorker.class.getSimpleName();
公共静态最终对象syncObj=新对象();
私有布尔runFlag=false;
私人地勤人员地勤人员;
私人语境;
私有阻塞队列;
私有游标mCursor;
私有AnimationImageCacheHelper AnimationImageCacheHelper;
私有最终字符串ASSET_SUFFIX=“assets://”;
私有最终字符串FILE_SUFFIX=“FILE://”;
直截了当;
Rect-bitmapRect;
油漆;
成对位图;
int mLeftIndex;
int-mRightIndex;
专用最终浮动轨道长度=720f;
私人最终浮动最大值α=255f;
公共动画工作者(
浮雕浮雕浮雕,
语境,
光标(光标){
超级();
this.surfaceHolder=surfaceHolder;
this.animationImageCacheHelper=新的animationImageCacheHelper();
bitmapRect=new Rect();
油漆=新油漆();
clipRect=new Rect();
队列=新的LinkedBlockingDeque();
}
公共void setRunning(布尔运行){
runFlag=run;
}
public void postTask(AnimationTask任务){
试一试{
queue.put(任务);
}捕获(例外e){
//无所事事
}
}
public void cancelTaskQueue(){
queue.clear();
}
@凌驾
公开募捐{
while(runFlag){
Log.e(Log_标签,“running”);
试一试{
AnimationTask=queue.remove();
如果(任务!=null){
processTask(任务);
}
}捕获(例外e){
试一试{
已同步(syncObj){
syncObj.wait();
}
}捕捉(中断异常e1){
e1.printStackTrace();
}
Log.e(Log_标签,“异常”);
e、 printStackTrace();
}
}
}
私有void处理任务(AnimationTask任务){
int leftIndex=Math.max(0,Math.min(mCursor.getCount()-1,(int)Math.floor(task.currentPosition/TRACK_LENTH.intValue());
int rightIndex=Math.max(0,Math.min(mCursor.getCount()-1,(int)Math.ceil(task.currentPosition/TRACK_LENTH.intValue());
如果(mLeftIndex!=左索引| | mRightIndex!=右索引){
位图=获取位图(leftIndex、rightIndex、task.direction);
}
float alpha=(MAX_alpha/TRACK_LENTH*task.currentPosition)%MAX_alpha;
绘制(位图。第一,位图。第二,alpha);
}
私有对GetBitmap(int-leftIndex、int-rightIndex、int-direction){
最终位图前景位图;
最终位图背景位图;
最终配对结果;
如果(方向==1){
//正上方
if(mCursor.moveToPosition(leftIndex)){
String backgroundImageUrl=mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
backgroundBitmap=loadImage(backgroundImageUrl);
}否则{
背景位图=空;
}
if(mCursor.moveToPosition(右索引)){
String foregroundImageUrl=mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
foregroundBitmap=loadImage(foregroundImageUrl);
}否则{
foregroundBitmap=null;
}
}否则{
//左上角
if(mCursor.moveToPosition(右索引)){
String backgroundImageUrl=mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
backgroundBitmap=loadImage(backgroundImageUrl);
}否则{
背景位图=空;
}
if(mCursor.moveToPosition(leftIndex)){
String foregroundImageUrl=mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
foregroundBitmap=loadImage(foregroundImageUrl);
}否则{
foregroundBitmap=null;
}
}
结果=新的一对(前景位图、背景位图);
返回结果;
}
私有位图加载图像(字符串uri){
if(animationImageCacheHelper.isImageContains(uri)){
返回animationImageCacheHelper.getBitmap(uri);
}
if(uri.startsWith(资产后缀)){
位图位图=ImageLoader.getInstance().loadImageSync(uri);
animationImageCacheHelper.put(uri,位图);
返回位图;
}否则{
位图位图=ImageLoader.getInstance().loadImageSync(“文件:/”+uri);
animationImageCacheHelper.put(uri,位图);
返回位图;
}
}
专用空心绘制(位图前景、位图背景、浮点alpha){
帆布;
canvas=null;
试一试{
canvas=surfaceHolder.lockCanvas(null);
canvas.getClipBounds(clipRect);
已同步(surfaceHolder){
//画背景
油漆。setAlpha(255);
bitmapRect.set(0,0,background.getWidth(),background.getHeight());
画布.drawBitmap(背景、bitmapRect、clipRect、绘画);
//画前景
paint.setAlpha((int)alpha);
bitmapRect.set(0,0,前台.getWidth(),前台.getHeight());
画布.drawBitmap(前景、位图矩形、clipRect、绘制);
}
}最后{
if(canvas!=null){
surfaceHolder.unlockCanvasAndPost(画布);
}
}
}
}

我正在收听“接触”事件,并为员工添加任务(当前位置和方向)。工作者必须从队列中获取任务并绘制当前状态。 在我的版本中,什么都没有发生。Surfaceview freeezes,我需要从我的设备中拔出电池来解锁它


*注意:我尝试使用
队列。take()
-但我得到了相同的结果

如果您必须从设备中取出电池,您的问题不会浮出水面查看。“主页”按钮应始终有效。你使用的是什么设备,什么版本的Android?(另一方面,为什么要在surfaceHolder上同步…?)@