1

大家好,我对 android/glass 开发还很陌生,所以如果我错了,请纠正我。

我试图创建一个很好的高频 Live Card。但是,当我关闭应用程序时,函数 surfaceDestroyed() 没有触发并且 thread.quit() 没有被调用。

我尝试查看示例项目秒表/计时器,显然他们也没有停止线程。根据文档,surfaceDestroyed 在表面被破坏之前被调用,但我的表面是什么?我还读了一些叫做surfaceview的东西,它们是一样的吗?surfaceview 是我的 customview 还是 livecard?

https://developers.google.com/glass/develop/gdk/ui/live-cards#creating_high-frequency_live_cards

感谢任何形式的帮助!!!</p>

/ ***
  * LiveCardRender Class
*** /
public class LiveCardRender implements DirectRenderingCallback {
    private static final long FRAME_TIME_MILLIS = 33;
    private CustomView mCustomView;
    private SurfaceHolder mHolder;
    private boolean mPaused;
    private RenderThread mRenderThread;

    private class RenderThread extends Thread {
        private boolean mShouldRun;

        public RenderThread() {
            mShouldRun = true;
        }

        private synchronized boolean shouldRun() {
            return mShouldRun;
        }

        public synchronized void quit() {
            mShouldRun = false;
        }

        @Override
        public void run() {
            while (shouldRun()) {
                draw(mCustomView);
                SystemClock.sleep(FRAME_TIME_MILLIS);
            }
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mHolder = holder;
        updateRendering();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mHolder = null;
        updateRendering();
    }

    @Override
    public void renderingPaused(SurfaceHolder holder, boolean paused) {
        mPaused = paused;
        updateRendering();
    }

    private synchronized void updateRendering() {

        boolean shouldRender = (mHolder != null) && !mPaused;
        boolean rendering = mRenderThread != null;

        if (shouldRender != rendering) {
            if (shouldRender) {
                mRenderThread = new RenderThread();
                mRenderThread.start();
            } else {
                mRenderThread.quit();
                mRenderThread = null;
            }
        }
    }

    private void draw(View view) {

        Canvas canvas;
        try {
            canvas = mHolder.lockCanvas();
        } catch (Exception e) {
            return;
        }
        if (canvas != null) {
            view.draw(canvas);
            mHolder.unlockCanvasAndPost(canvas);
        }
    }
}

/ ***
  * LaunchService Class that uses LiveCardRender to update the live card
*** /
public class LaunchService extends Service {
    private static final String LIVE_CARD_TAG = "motion_card";
    private TimelineManager mTimelineManager;
    private LiveCard mLiveCard;
    private LiveCardRender mLiveCardRender;

    @Override
    public void onCreate() {
        mTimelineManager = TimelineManager.from(this);
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        if (mLiveCard == null) {
            mLiveCard = mTimelineManager.createLiveCard(LIVE_CARD_TAG);
            mLiveCardRender = new LiveCardRender(this);
            mLiveCard.setDirectRenderingEnabled(true);
            mLiveCard.getSurfaceHolder().addCallback(mLiveCardRender);
            mLiveCard.publish(PublishMode.REVEAL);
        }
        return START_STICKY;
    }

    @Override
    public void onDestroy(){
        if (mLiveCard != null && mLiveCard.isPublished()) {
            if (mLiveCardRender != null) {
                mLiveCard.getSurfaceHolder().removeCallback(mLiveCardRender);
            }
            mLiveCard.unpublish();
            mLiveCard = null;
        }
        super.onDestroy();
    }
}
4

1 回答 1

1

看起来错误就在这里,在里面onDestroy

if (mLiveCard != null && mLiveCard.isPublished()) {
    if (mLiveCardRender != null) {
        mLiveCard.getSurfaceHolder().removeCallback(mLiveCardRender);
    }
    mLiveCard.unpublish();

通过在调用方法之前移除回调unpublish,系统不再知道surfaceDestroyed在之后移除卡片时调用谁的方法。您实际上可以removeCallback完全删除调用;这是不必要的。

看起来这是我们的一些示例中的一个错误,随着 API 的发展,我们错过了这些错误。感谢您的关注,我们会尽快更新它们!

于 2014-01-30T18:58:53.990 回答