2013-06-26 2 views
11

У меня есть приложение, в котором я использую устройства камеры.Android-камера заблокирована после силы close

Теперь я выпускаю камеру только в нормальном режиме.

@Override 
public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 
    if(camera != null) { 
     camera.stopPreview(); 
     camera.release(); 
    } 
} 

Таким образом, то приложение завершает работа в режиме камеры в неожиданном образе - то есть Force Close (из-за OutOfMemoryError) - камеру блокируется. И единственный способ ее освободить - перезапустить устройство.

И после запуска приложения я получаю: RuntimeException: Fail to connect to camera service

Как я мог убедиться, что камера выпускается в любом случае?

+0

Вы пытались удалить приложение? Если я правильно помню, это помогло мне в прошлом. – vRallev

+0

Это не то, что я спросил. Мне нужно убедиться, что «Камера» будет выпущена в любом случае. Без удаления приложения или перезапуска устройства. –

+5

Я предполагаю, что вам нужно будет использовать 'Thread.setDefaultUncaughtExceptionHandler()', чтобы организовать контроль над такими сбоями, чтобы закрыть камеру. – CommonsWare

ответ

3

Поскольку лучший способ сохранить часть кода, так что вы нашли его позже, чтобы опубликовать его в «сети,

private UnexpectedTerminationHelper mUnexpectedTerminationHelper = new UnexpectedTerminationHelper(); 
private class UnexpectedTerminationHelper { 
    private Thread mThread; 
    private Thread.UncaughtExceptionHandler mOldUncaughtExceptionHandler = null; 
    private Thread.UncaughtExceptionHandler mUncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() { 
     @Override 
     public void uncaughtException(Thread thread, Throwable ex) { // gets called on the same (main) thread 
      XXXX.closeCamera(); // TODO: write appropriate code here 
      if(mOldUncaughtExceptionHandler != null) { 
       // it displays the "force close" dialog 
       mOldUncaughtExceptionHandler.uncaughtException(thread, ex); 
      } 
     } 
    }; 
    void init() { 
     mThread = Thread.currentThread(); 
     mOldUncaughtExceptionHandler = mThread.getUncaughtExceptionHandler(); 
     mThread.setUncaughtExceptionHandler(mUncaughtExceptionHandler); 
    } 
    void fini() { 
     mThread.setUncaughtExceptionHandler(mOldUncaughtExceptionHandler); 
     mOldUncaughtExceptionHandler = null; 
     mThread = null; 
    } 
} 

и, в соответствующих местах на главной теме:

mUnexpectedTerminationHelper.init(); 

и

mUnexpectedTerminationHelper.fini(); 
+0

Нужен ли этот код? Где бы я запустил код, чтобы закрыть камеру? Почему это не так в коде обработчика ошибок? У вас есть ссылка на дополнительную информацию об этом? – msj121

+0

@ msj121 ООП - это разделение обязанностей. Этот помощник отвечает за реакцию на неперехваченные исключения. Другой помощник должен отвечать за материал камеры (вы видите, что 'XXXX.closeCamera();' строка). В простейшем случае одного действия вы помещаете 'XXXX.openCamera()' и 'mUnexpectedTerminationHelper.init();' в _onResume() _ и помещаете закрывающий материал в _onPause() _. Обратите внимание, что вы вызываете 'XXXX.closeCamera();' как из помощника, так и из _onPause() _. Приложения реального мира обычно сложнее, чем одно действие, и включают в себя материал, который нелегко объяснить. – 18446744073709551615

+0

Извините, я пропустил линию для близкой камеры. благодаря – msj121

-3
private void stopPreviewAndFreeCamera() { 

if (mCamera != null) { 
    /* 
     Call stopPreview() to stop updating the preview surface. 
    */ 
    mCamera.stopPreview(); 

    /* 
     Important: Call release() to release the camera for use by other applications. 
     Applications should release the camera immediately in onPause() (and re-open() it in 
     onResume()). 
    */ 
    mCamera.release(); 

    mCamera = null; 
}} 

сделать это следующим образом.

+0

Как она отличается от кода в моем вопросе? –

+0

Я думаю, вы не поместили это в свой код i.e mCamera = null; –

+1

Удаление ссылки на объект не означает, что эта камера была отпущена. –

0

Ошибка памяти, потому что изображение, которое вы пытались сохранить, превзошло предел, обычно возникает при попытке обработать растровое изображение.

Вы можете попробовать эти методы, чтобы избежать попадания камеры в неактивную.

Камера myCamera;

Используйте журналы и Fing, где происходит ошибка и Добавить попытка поймать блок и в блоке поймать добавить myCamera.stopPreview(); и myCamera.release(); также переопределить OnDestroy и OnPause метода и add myCamera.stopPreview(); и myCamera.release();

Надеется, что это помогает вам или по крайней мере дал вам идею.

+1

Я использую ведение журнала, чтобы определить, где происходит 'OutOfMemoryError', но проблема все еще остается - пользователь не должен страдать из-за моих ошибок. Я буду обрабатывать все ошибки в долгосрочной перспективе, но я хочу освободить камеру, даже несмотря на сбой приложений. –

3

Как предложено @CommonsWare, если вы хотите убедиться, что ваше приложение освобождает камеру перед сбоем, вы должны использовать Thread.setDefaultUncaughtExceptionHandler().

Или, если вы используете Bugsense:

private class MyCameraActivity extends Activity implements SurfaceHolder.Callback, ExceptionCallback { 

    @Override 
    protected void onCreate(Bundle sSavedInstanceState) { 
     super.onCreate(sSavedInstanceState); 

     BugSenseHandler.setExceptionCallback(this); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     this.camera = open(); 

     try { 
      camera.setPreviewDisplay(holder); 
     } catch (IOException e) { 
      Log.e(TAG, e.getMessage(), e); 
     } 

     // other camera stuff 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 
     releaseCamera(); 
    } 

    @Override 
    public void lastBreath() { 
     releaseCamera(); 
    } 

    private void releaseCamera() { 
     if (camera != null) { 
      camera.stopPreview(); 
      camera.release(); 
     } 
    } 
}