2014-12-14 2 views
0

У меня есть приложение, в котором пользователь может выбрать картинку из своей галереи.Основная тема делает слишком много работы, хотя я использую async thread (laggy UI)

Он ставит изображение в поле ImageView, и есть несколько полей EditText, которые необходимо заполнить.

После изображения выбрано, это занимает несколько секунд, чтобы открыть клавиатуру, через несколько секунд, чтобы отобразить ввод текста и т.д.

Я делаю все графические манипуляции и т.д. в AsyncTask следующим образом:

Вызвать AsyncTask:

protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if(resultCode == RESULT_OK) { 
     try { 

      new SetPathAsync(data.getData()).execute(); 

     }catch (Exception e){ 
      Log.e("Error", "Error with setting the image. See stack trace."); 
      e.printStackTrace(); 
     } 
    } 
} 

Выполните задание:

общественного класса SetPathAsync расширяет AsyncTask {

Uri uri; 

    // override this to set uri for bitmap 
    public SetPathAsync(Uri uriPass){ 
     super(); 
     uri = uriPass; 
    } 

    @Override 
    protected Boolean doInBackground(String... params) { 

     String[] projection = { MediaStore.Images.Media.DATA }; 
     Cursor cursor = getContentResolver().query(uri, projection, null, null, null); 

     cursor.moveToFirst(); 
     filePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); 
     cursor.close(); 

     // Convert file path into bitmap image using below line. 

     bitmap = BitmapFactory.decodeFile(filePath); 

     filePathForUpload = filePath; 

     Log.i("Test", filePath); 

     try { 
      ExifInterface exif = new ExifInterface(filePath); 
      int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); 
      bitmap = rotateBitmap(bitmap, orientation); 
     }catch (Exception e) { 
      Log.d("Error", "error with bitmap!"); 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    public Bitmap rotateBitmap(Bitmap bitmap, int orientation) { 
     Matrix matrix = new Matrix(); 
     switch (orientation) { 
      case ExifInterface.ORIENTATION_NORMAL: 
       return bitmap; 
      case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: 
       matrix.setScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_180: 
       matrix.setRotate(180); 
       break; 
      case ExifInterface.ORIENTATION_FLIP_VERTICAL: 
       matrix.setRotate(180); 
       matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_TRANSPOSE: 
       matrix.setRotate(90); 
       matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_90: 
       matrix.setRotate(90); 
       break; 
      case ExifInterface.ORIENTATION_TRANSVERSE: 
       matrix.setRotate(-90); 
       matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_270: 
       matrix.setRotate(-90); 
       break; 
      default: 
       return bitmap; 
     } 

     Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
     bitmap.recycle(); 
     return bmRotated; 
    } 


    @Override 
    protected void onPostExecute(Boolean aBoolean) { 
     super.onPostExecute(aBoolean); 

     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       imageView.setImageBitmap(bitmap); 
       button.setEnabled(false); 
      } 
     }); 
    } 
} 

Все остальное в коде - это обычные задачи пользовательского интерфейса.

Любая причина, по которой все еще существует отставание от того, что она находится в потоке Async?

+2

Позаботьтесь о утечке памяти! AsyncTask и сильные ссылочные растровые изображения могут легко привести к памяти. Просто намек. – Mike

+0

'runOnUiThread' в' onPostExecute() 'немного перебор, так как' onPostExecute() 'работает в потоке пользовательского интерфейса в любом случае. – Ridcully

ответ

1

Не очевидно. Вам нужно будет профилировать его.

Кроме того, нет необходимости вызывать super() в конструкторе SetPathAsync, и нет необходимости запускать runOnUiThread-onPostExecute в потоке пользовательского интерфейса.

+0

Спасибо за отзыв. Я расскажу об этом в DDMS и посмотрю, что я получаю –

1

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

Я заметил это, когда я получал ошибки в logcat, такие как: Grow heap (frag case).

Чтобы это исправить, я масштабируется вниз изображение как так:

BitmapFactory.Options bmpOpts = new BitmapFactory.Options(); 
bmpOpts.inSampleSize = 3; 

bitmap = BitmapFactory.decodeFile(filePath, bmpOpts); 

И это проходит гладко сейчас

Смежные вопросы