2011-12-17 3 views
3

У меня есть две кнопки в главном меню. Я вызываю камеру, когда нажимаю 1-ю кнопку. Здесь у меня не было никаких проблем. Камера работает правильно. Сделав снимок, я возвращаюсь в главное меню и снова нажимаю 1-ю кнопку. Здесь я получил вопрос. Правильно подключена камера. Но я получил ANR error (Reason: keyDispatchingTimedOut), пока я снимаю. Как решить эту проблему?Как разрешить ошибку ANR при вызове камеры?

Edit ::

Я использую следующий код,

Кнопка Слушатель,

Button imageButton = (Button) findViewById(R.id.button1); 
imageButton.setOnClickListener(new View.OnClickListener() { 

    public void onClick(View arg0) { 
    Intent intent = new Intent(); 
    intent.setClass(activity, ImageActivity.class); 
    startActivity(intent); 
    } 
}); 

ImageActivity.java

public class ImageActivity extends Activity implements SurfaceHolder.Callback { 
    private Camera camera = null; 
    private SurfaceHolder surfaceHolder = null; 
    private boolean previewRunning = false; 
    private Button btnDone, btnCapture, btnRetake; 
    private Bitmap mBitmap; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     getWindow().setFormat(PixelFormat.TRANSLUCENT); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     setContentView(R.layout.surface_screen); 
     SurfaceView surfaceView = (SurfaceView) findViewById(R.id.camerapreview); 
     surfaceHolder = surfaceView.getHolder(); 
     surfaceHolder.addCallback(this); 
     surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
     surfaceHolder.setFixedSize(getWindow().getWindowManager() 
       .getDefaultDisplay().getWidth(), getWindow().getWindowManager() 
       .getDefaultDisplay().getHeight()); 
     LayoutInflater controlInflater = LayoutInflater.from(getBaseContext()); 

     final View viewControl = controlInflater.inflate(R.layout.control, null); 
     LayoutParams layoutParamsControl = new LayoutParams(
       LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 
     activity.addContentView(viewControl, layoutParamsControl); 

     btnCapture = (Button) findViewById(R.id.takepicture); 

     btnDone = (Button) findViewById(R.id.send); 

     btnCapture.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       camera.takePicture(null, picCalBac, picCalBac); 
      } 
     }); 


    Camera.PictureCallback picCalBac = new PictureCallback() { 

     public void onPictureTaken(byte[] data, Camera camera) { 
      if (data != null) { 
       mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length); 
      } 
     } 
    }; 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     if (previewRunning) { 
      camera.stopPreview(); 
     } 
     try { 
      camera.setPreviewDisplay(surfaceHolder); 
     } catch (IOException e) { 
      Log.d("IOException", e.getMessage()); 
     } 
     camera.startPreview(); 
     previewRunning = true; 
    } 

    public void surfaceCreated(SurfaceHolder arg0) { 
     camera = Camera.open(0); 
    } 

    public void surfaceDestroyed(SurfaceHolder arg0) { 
     camera.stopPreview(); 
     previewRunning = false; 
     camera.release(); 
    } 
} 
+1

Опубликовать свой код .. – user370305

+0

Можете ли вы разместить свой источник, чтобы мы могли видеть, где вы застряли ....это звучит так, будто вы, возможно, не отпускаете камеру после первого раза, когда вы снимаете pic –

+0

Посмотрите на обновление. – bharath

ответ

8

Вы могли бы прошли через this link при поиске ошибок.

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

Описание:

ANR или ошибка приложения не отвечает происходит, когда процесс в главном потоке занимает слишком много времени (что-то вроде> 5 секунд). Android убивает этот процесс и любые связанные с ним проекты, чтобы сэкономить ресурсы устройства .

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

Смотреть Это: Android ANR keyDispatchingTimedOut

Так что в вашем случае вы можете быть конфликтующие две разные темы от той, что продолжают работать в течение длительного времени и Android убивает их. Следующий связанный код также затронут.

Так что лучше классифицируйте свой код, напишите каждую новую задачу в разных Thread,Handler, и если вы выполняете задачу пользовательского интерфейса, используйте runOnUIThread. Async Task также очень удобный.

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

Я считаю, что ошибка связана с вашим стилем кодирования, а не из-за какой-либо конкретной ошибки в вашем коде.

Вы должны улучшить свой этот конкретный код для выполнения эффективно и что увидеть эти 2 ссылки:

  1. Design for Responsiveness
  2. Painless Threading

EDIT:

Это я прочитал где-то и нашел эффективным,

Как исследовать ANR?

Во-первых, перейдите по своему коду и найдите призрачные места и длительные операции. Примеры могут включать использование сокетов, блокировок, спальных потоков и других операций блокировки из потока событий. Вы должны убедиться, что все это происходит в отдельных потоках. Если ничего не возникает, используйте DDMS и включите просмотр потока. Это показывает все потоки в вашем приложении, похожие на трассировку. Воспроизводите ANR и одновременно обновите основной поток. Это должно показать вам, что именно происходит во время ANR

Также если ANR вызван потоками?

вы можете пользователю услуги для того, Так что ваше приложение может сделать много времени задач внутри service.onStart(), передачи данных (к примеру) в намерениях, используемой для запуска службы.

Однако службы выполняются в основной прикладной нити. Если требуется отдельный поток , он может быть создан службой внутри onStart().

Существует уже встроенный класс, который делает это: IntentService

нашел также один полезное применение библиотеки SalomonBrys/ANR-WatchDog

+1

Ссылка была разбита на blog. – dirtydexter

+0

@dirtydexter Спасибо за указатель, ссылка обновлена. – MKJParekh

5

Я думаю, вы уже знаете об этом,

единственная нить модель может дать плохую производительность в Android приложений, которые не считают последствия. Поскольку все происходит в одном потоке, выполняющем длительные операции, такие как запросы доступа к сети или базы данных, в этом потоке будет блокироваться весь пользовательский интерфейс. Событие не может быть отправлено, включая события рисования, в то время как длительная операция продолжается. * С точки зрения пользователя приложение отображается под напряжением *. Хуже того, если поток пользовательского интерфейса заблокирован более чем на несколько секунд (около 5 секунд в настоящее время), пользователю предоставляется печально известное диалоговое окно «приложение не отвечает» (ANR).

ANR происходит, когда в «основной» нити происходит некоторая длительная операция. Это поток цикла событий, и если он занят, Android не может обрабатывать какие-либо дополнительные события GUI в приложении и, таким образом, вызывает диалог ANR.

Какие триггеры ANR?

В Android отзывчивость приложений контролируется службами Activity Manager и Window Manager. Android отобразит диалоговое окно ANR для конкретного приложения при обнаружении одного из следующих условий:

* No response to an input event (e.g. key press, screen touch) within 5 seconds 
* A BroadcastReceiver hasn't finished executing within 10 seconds 

Как разрешить его, пожалуйста, смотрите на Designing for Responsiveness

EDIT:

Итак, попробуйте использовать другой отдельный рабочий поток, обработчик, AsyncTask или UIThread для вашего материала камеры (медиамагнитофон) вместо основного потока активности.

1). Сделайте "adb shell cat /data/anr/traces.txt", чтобы увидеть, что ваше приложение было занято, делая в этот момент. Это самый первый шаг, который вам нужно предпринять: поймите, что делает ваше приложение, вызывающее ANR.

Когда ANR происходит, все стеки процесса записываются в этот файл, , причем процесс обвиняется в ANR в первую очередь.Все это делает демпинг файла, чтобы вы могли посмотреть на него. Поэтому вы просто хотите посмотреть на него некоторое время после ANR, прежде чем произойдет другой ANR.

2). Если ничего не возникает, используйте DDMS и включите просмотр потока. Это показывает все потоки в вашем приложении, похожие на трассировку. Воспроизводите ANR, и обновите основной поток одновременно. Это должно показать вам, что именно происходит с во время ANR.

Фор более просто пройти через этот http://android-developers.blogspot.com/2009/05/painless-threading.html

+0

Я обновлю мой код. – bharath

+0

У меня эта проблема, пока я снимаю еще 1 фотографию. Например, если в первый раз я фотографирую, никаких проблем. Но если 2-й раз, эта проблема возникает. Как решить эту проблему? – bharath

1

Может быть, вы инициализации и запуска устройства записи на носитель в основном потоке самой либо в Oncreate() или в Onresume(), вместо запуска камеры в основной поток, использует separeate Handler запустить камеру для принимая фотографии, он будет действовать как дочерний поток основного пользовательского интерфейса.

Используя Handler, вы сокращаете время, и ANR не будет возникать.

5

Android applications normally run entirely on a single (i.e. main) thread. Это означает, что все, что делает ваше приложение в основном потоке, которое занимает long time, может вызвать ANR dialog, потому что ваше приложение не дает возможности обрабатывать input event или I ntent broadcast. Так что в этом случае вы можете использовать StrictMode, чтобы помочь найти потенциально длительные операции, такие как операции с сетью или базой данных, которые вы, возможно, случайно делаете в своем основном потоке. Если вы обнаружили нарушения, которые вы чувствуете, являются проблематичными, существует целый ряд инструментов, чтобы помочь решить их: threads, Handler, AsyncTask, IntentService, etc.Also помните, что он пришел из API Level 9

Пример кода для того, чтобы с самого начала в вашем Application, Activity или onCreate() метода другого приложения компонента:

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 
       .detectDiskReads() 
       .detectDiskWrites() 
       .detectNetwork() // or .detectAll() for all detectable problems 
       .penaltyLog() 
       .build()); 
     StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 
       .detectLeakedSqlLiteObjects() 
       .detectLeakedClosableObjects() 
       .penaltyLog() 
       .penaltyDeath() 
       .build()); 
1

кажется, что ресурс камеры не является выпуском, тем самым вызывая ANR.

Код выглядит немного грязным. Вы можете взглянуть на пример api для камеры preview:

Вам нужно будет реализовать и onResume, чтобы он работал надежно.