Aplikasi mungkin melakukan terlalu banyak pekerjaan pada utas utamanya

379

Saya baru mengenal lingkungan Android SDK / API. Ini pertama kali saya mencoba menggambar plot / grafik. Saya mencoba menjalankan berbagai jenis kode sampel emulator menggunakan 3 perpustakaan gratis yang berbeda, tidak ada yang ditampilkan di layar tata letak. Logcat mengulangi pesan berikut:

 W / Lacak (1378): Nilai tak terduga dari nativeGetEnabledTags: 0
 I / Koreografer (1378): Dilewati 55 frame! Aplikasi mungkin melakukan terlalu banyak pekerjaan pada utas utamanya.

Masalahnya tidak berlanjut dan bagan bekerja ketika saya menjalankan kode sampel yang berkaitan dengan salinan evaluasi perpustakaan berlisensi.

pengguna2038135
sumber
2
Apakah Anda menggambar grafik Anda di utas terpisah?
Areks
Terima kasih atas komentar Anda, saya mengedit pertanyaan untuk membuatnya lebih jelas. Aktivitas saat menjalankan menunjukkan bahwa saya menjalankan aktivitas yang tidak memiliki desain tata letaknya => menampilkan layar putih.
user2038135
1
@Areks Tidak, saya tidak menggunakan utas terpisah.
user2038135
1
Saya pikir Anda harus, tidak disarankan sama sekali untuk melakukan operasi panjang pada utas utama, karena itu membekukan seluruh aplikasi, Anda dapat membaca cara menggunakan utas di sini: stackoverflow.com/questions/3391272/… Abaikan "kode yang harus dilakukan permintaan HTTP "dan jalankan operasi berpotensi lama Anda di sana.
Areks
1
Mengapa Anda tidak mencoba mencari, Anda akan menemukan informasi tentang koreografer. Saya sarankan Anda untuk membaca jawaban ini: stackoverflow.com/questions/11266535/…
Gabriel Esteban

Jawaban:

479

diambil dari: Android UI: Memperbaiki bingkai yang dilewati

Siapa pun yang mulai mengembangkan aplikasi android melihat pesan ini di logcat “Koreografer (abc): Melewati bingkai xx! Aplikasi mungkin melakukan terlalu banyak pekerjaan pada utas utamanya. " Jadi apa artinya sebenarnya, mengapa Anda harus khawatir dan bagaimana menyelesaikannya.

Apa artinya ini adalah bahwa kode Anda butuh waktu lama untuk diproses dan frame dilewati karena itu, Mungkin karena beberapa proses berat yang Anda lakukan di jantung aplikasi Anda atau akses DB atau hal lain yang menyebabkan utas berhenti sebentar.

Berikut ini penjelasan yang lebih rinci:

Koreografer memungkinkan aplikasi untuk menghubungkan diri mereka dengan vsync, dan mengatur waktu dengan tepat untuk meningkatkan kinerja.

Animasi tampilan Android secara internal menggunakan Koreografer untuk tujuan yang sama: untuk menentukan waktu animasi dengan tepat dan mungkin meningkatkan kinerja.

Karena Koreografer diberitahu tentang setiap peristiwa vsync, saya dapat mengetahui apakah salah satu Runnables dilewatkan oleh Choreographer.post * apis tidak selesai dalam waktu satu frame, menyebabkan frame dilewati.

Dalam pemahaman saya Koreografer hanya dapat mendeteksi bingkai yang dilompati. Tidak ada cara untuk mengatakan mengapa ini terjadi.

Pesan "Aplikasi mungkin melakukan terlalu banyak pekerjaan pada utas utamanya." bisa menyesatkan.

sumber: Makna pesan Koreografer di Logcat

Kenapa harus khawatir?

Ketika pesan ini muncul di emulator android dan jumlah bingkai yang dilompati cukup kecil (<100) maka Anda dapat bertaruh dengan aman bahwa emulator lambat - yang terjadi hampir setiap saat. Tetapi jika jumlah bingkai dilewati dan besar dan dalam urutan 300+ maka akan ada masalah serius dengan kode Anda. Perangkat Android memiliki beragam perangkat keras yang berbeda dengan perangkat iOS dan Windows. RAM dan CPU bervariasi dan jika Anda ingin kinerja yang wajar dan pengalaman pengguna di semua perangkat maka Anda perlu memperbaiki hal ini. Ketika bingkai dilewati, UI lambat dan lamban, yang bukan pengalaman pengguna yang diinginkan.

Bagaimana memperbaikinya

Memperbaiki ini membutuhkan mengidentifikasi node di mana ada atau mungkin dapat terjadi durasi pemrosesan yang lama. Cara terbaik adalah melakukan semua pemrosesan terlepas dari seberapa kecil atau besar suatu utas terpisah dari utas UI utama. Jadi itu mengakses data dari SQLite Database atau melakukan beberapa matematika hardcore atau hanya menyortir array - Lakukan di utas yang berbeda

Sekarang ada tangkapan di sini, Anda akan membuat Thread baru untuk melakukan operasi ini dan ketika Anda menjalankan aplikasi Anda, itu akan crash mengatakan "Hanya utas asli yang membuat hierarki tampilan yang dapat menyentuh pandangannya". Anda perlu mengetahui fakta bahwa UI di android dapat diubah oleh utas utama atau utas UI saja. Utas lain yang mencoba melakukannya, gagal dan macet dengan kesalahan ini. Yang perlu Anda lakukan adalah membuat Runnable baru di dalam runOnUiThread dan di dalam runnable ini Anda harus melakukan semua operasi yang melibatkan UI. Temukan contoh di sini .

Jadi kami memiliki Thread dan Runnable untuk memproses data dari Thread utama, apa lagi? Ada AsyncTask di android yang memungkinkan melakukan proses waktu yang lama pada utas UI. Ini adalah yang paling berguna ketika aplikasi Anda didorong oleh data atau web api-driven atau menggunakan UI kompleks seperti yang dibuat menggunakan Canvas. Kekuatan AsyncTask adalah memungkinkan melakukan hal-hal di latar belakang dan setelah Anda selesai melakukan pemrosesan, Anda dapat dengan mudah melakukan tindakan yang diperlukan pada UI tanpa menyebabkan efek lagging. Ini dimungkinkan karena AsyncTask berasal dari utas UI Activity - semua operasi yang Anda lakukan pada UI melalui AsyncTask dilakukan adalah utas berbeda dari utas UI utama, Tidak ada halangan bagi interaksi pengguna.

Jadi ini yang perlu Anda ketahui untuk membuat aplikasi android yang lancar dan sejauh yang saya tahu setiap pemula mendapatkan pesan ini di konsolnya.

Jorgesys
sumber
41
Saya hanya memiliki aplikasi di mana jika saya mengklik tombol, gambar latar belakang tombol berubah dan tombol tidak dapat diklik. Bagaimana saya melakukan terlalu banyak pekerjaan :(
Remian8985
1
@ Remian8985 - Perubahan gambar latar belakang untuk tombol (dengan anggapan bahwa Anda mengunduh gambar ini) harus dilakukan dalam AsyncTask - artinya melakukan operasi pengunduhan latar belakang itu dan mempublikasikan hasilnya pada utas UI (menyediakan kembali gambar). Lihat tautan
BenJaminSila
11
@BenJaminSila mengubah latar belakang di AsyncTask? Betulkah?
user25
11
@ user25 "dengan asumsi Anda mengunduh gambar ini"
forresthopkinsa
"Ketika pesan ini muncul di emulator android dan jumlah bingkai yang dilewati cukup kecil (<100) maka Anda dapat bertaruh dengan aman bahwa emulator sedang lambat" Apakah ini masih berlaku hari ini? Emulator semakin cepat bukan?
Robin Dijkhof
243

Seperti yang lain menjawab di atas, "Melompati 55 frame!" berarti beberapa proses berat ada di aplikasi Anda.

Untuk kasus saya, tidak ada proses yang berat dalam aplikasi saya. Saya melakukan double dan triple memeriksa semuanya dan menghapus proses yang menurut saya agak berat.

Saya menghapus Fragmen, Aktivitas, Perpustakaan sampai hanya kerangka yang tersisa. Namun tetap saja masalahnya tidak hilang. Saya memutuskan untuk memeriksa sumber daya dan menemukan beberapa ikon dan latar belakang yang saya gunakan cukup besar karena saya lupa memeriksa ukuran sumber daya tersebut.

Jadi, saran saya adalah jika tidak ada jawaban di atas yang membantu, Anda juga dapat memeriksa ukuran file sumber daya Anda.

Sithu
sumber
1
Bekerja untuk saya juga. Saya memiliki aplikasi yang hanya melakukan sedikit pekerjaan tetapi lambat dan lamban. Saya terus mendapatkan frame log yang dilewati. Setelah saya menghapus latar belakang dari aktivitas saya, semuanya baik-baik saja. Terima kasih!
akrabi
Jawaban yang bagus, saya yakin ini adalah masalah saya. Saya mencoba banyak solusi lain (yang cukup terlibat) dan aplikasinya lambat. Saya mengambil semua layanan web, dan mencoba untuk mengoptimalkan kode saya sampai ke tulang. Tidak berhasil, maka saya melihat ini. Segera setelah saya menghapus gambar latar belakang (gambar terbesar yang saya miliki) aplikasi bekerja secepat Anda bisa mengklik barang, bahkan dengan kode "lambat" yang lama.
M Barbosa
kamu membuat hariku!
Nicolas Mastromarino
:) Anda adalah seorang jenius absulute.
Metin Ilhan
@ batsheva tidak perlu 1 KB. Itu tergantung pada kebutuhan Anda, katakanlah Anda membutuhkan gambar yang lebih jelas, Anda dapat menggunakan resolusi yang lebih tinggi, tetapi pastikan Anda membagi ukuran yang berbeda ke dalam folder sumber daya yang berbeda.
Sithu
61

Saya juga punya masalah yang sama.
Milik saya adalah kasus di mana saya menggunakan gambar latar belakang yang ada di drawables. Gambar khusus itu kira-kira 130kB dan digunakan selama layar splash dan beranda di aplikasi android saya.

Solusi - Saya baru saja menggeser gambar tersebut ke folder drawables-xxx dari drawables dan dapat membebaskan banyak memori yang ditempati di latar belakang dan bingkai skipping tidak lagi dilewati.

Perbarui Gunakan folder sumber daya yang dapat digulung 'nodp' untuk menyimpan file latar belakang yang dapat digambar.
Apakah kepadatan folder drawable berkualitas atau drawable-nodpi diutamakan?

Prakhar1001
sumber
7
Saya memindahkan gambar latar belakang saya yang besar dari drawable ke mimap-xxxhdpi dan berhasil!
bgplaya
Anda banyak membantu. Terima kasih
N.Droid
2
Solusi ini sedang melakukan trik. Saya menggunakan folder, drawable-xxxhdpibukan drawableapa yang secara dramatis mengurangi memori yang digunakan (~ 70 persen lebih sedikit). Juga baik untuk diketahui, layar dengan ukuran yang sama bervariasi dalam ukuran DPI. Rasio dalam piksel antara mereka adalah ldpi = 1:0.75, mdpi = 1:1, hdpi = 1:1.5, xhdpi = 1:2, xxhdpi = 1:3, xxxhdpi = 1:4. Dengan menggunakan drawable-xxxhdpifolder, Anda dapat menurunkan skala gambar ke screensize perangkat Anda yang mengurangi konsumsi memori dan CPU.
Timo Bähr
2
Memindahkan gambar dari drawableuntuk drawable-nodpimencegah aplikasi dari mendapatkan Out of Memory Error.
Shruti
Ya Tuhan ... terima kasih! Saya memiliki gambar di dalam folder yang dapat digambar dan ini membuat aplikasi saya sangat lambat (walaupun gambarnya hanya 100kb !!!). Setelah membuat file drawable-xxx (saya menggunakan Android Drawable Importir) aplikasi saya sangat cepat. Terima kasih banyak!
error1337
20

Penyebab umum lain dari keterlambatan utas UI adalah akses SharedPreferences. Saat Anda memanggil a PreferenceManager.getSharedPreferencesdan metode serupa lainnya untuk pertama kalinya, file .xml yang terkait segera dimuat dan diuraikan dalam utas yang sama .

Salah satu cara yang baik untuk mengatasi masalah ini adalah memicu beban SharedPreference pertama dari utas latar belakang, dimulai sedini mungkin (misalnya dari onCreatekelas Aplikasi Anda). Dengan cara ini objek preferensi mungkin sudah dibangun pada saat Anda ingin menggunakannya.

Sayangnya, terkadang membaca file preferensi diperlukan selama fase awal startup (misalnya dalam Aktivitas awal atau bahkan Aplikasi itu sendiri). Dalam kasus seperti itu, masih mungkin untuk menghindari penghentian UI dengan menggunakan MessageQueue.IdleHandler. Lakukan segala hal lain yang perlu Anda lakukan pada utas utama, lalu instal IdleHandler untuk mengeksekusi kode setelah Aktivitas Anda sepenuhnya ditarik. Dalam Runnable itu Anda harus dapat mengakses SharedPreferences tanpa menunda terlalu banyak operasi menggambar dan membuat Koreografer tidak senang.

pengguna1643723
sumber
1
Untuk kasus ini, Anda harus memilih metode apply () daripada commit (). metode apply () tidak dapat memblokir UI. Anda dapat melihat dari sini developer.android.com/training/data-storage/share-preferences
Emre Gürses
16

Cobalah untuk menggunakan strategi berikut untuk meningkatkan kinerja aplikasi Anda:

  • Gunakan pemrograman multi-threading jika memungkinkan. Manfaat kinerja sangat besar, bahkan jika ponsel pintar Anda memiliki satu inti (utas dapat berjalan di inti yang berbeda, jika prosesor memiliki dua atau lebih). Ini berguna untuk membuat logika aplikasi Anda terpisah dari UI. Gunakan utas Java, AsyncTask atau IntentService. Lihat ini .
  • Baca dan ikuti tips kinerja misc situs web pengembangan Android. Periksa di sini .
MigDus
sumber
3
Tautan pertama Anda mengharuskan Anda "... memiliki akun yang divalidasi ..." untuk mengaksesnya.
chornge
9

Saya memiliki masalah yang sama. Android Emulator bekerja dengan sempurna di Android <6.0. Ketika saya menggunakan emulator Nexus 5 (Android 6.0), aplikasi bekerja sangat lambat dengan I/Choreographer: Skipped framesdi log.

Jadi, saya memecahkan masalah ini dengan mengubah hardwareAcceleratedopsi file Manifest menjadi trueseperti ini:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapplication">

    <application android:hardwareAccelerated="true">
        ...
    </application>
</manifest>
fen0menon
sumber
8

Saya bukan ahli, tetapi saya mendapat pesan debug ini ketika saya ingin mengirim data dari aplikasi android saya ke server web. Meskipun saya menggunakan kelas AsyncTask dan melakukan transfer data di latar belakang, untuk mendapatkan data hasil kembali dari server saya menggunakan metode get () dari kelas AsyncTask yang membuat UI sinkron yang berarti bahwa UI Anda akan menunggu terlalu lama. Jadi saran saya adalah membuat aplikasi Anda melakukan setiap tugas yang berorientasi jaringan pada utas terpisah.

saba
sumber
6

Optimalkan gambar Anda ... Jangan gunakan gambar yang lebih besar dari 100KB ... Memuat gambar terlalu banyak menggunakan CPU dan menyebabkan aplikasi Anda hang.

HarshitG
sumber
4
Kurangi ukuran gambar baik dengan kode java atau gunakan photoshop untuk memotong gambar .. juga kompres gambar menggunakan compressor.io
HarshitG
5

Saya memiliki masalah yang sama. Dalam kasus saya, saya memiliki 2 Layout Relatif Bersarang. RelativeLayout selalu harus melakukan dua operan ukur. Jika Anda membuat RelativeLayout, Anda akan mendapatkan algoritme pengukuran eksponensial.

Radoslav
sumber
4

ini biasanya terjadi ketika Anda menjalankan proses besar di utas utama. tidak apa-apa untuk melewatkan frame kurang dari 200. tetapi jika Anda memiliki lebih dari 200 frame yang dilewati, itu dapat memperlambat Anda utas aplikasi UI. apa yang dapat Anda lakukan adalah melakukan proses ini di utas baru yang disebut utas pekerja dan setelah itu, ketika Anda ingin mengakses dan melakukan sth dengan utas UI (mis: lakukan sesuatu dengan tampilan, findView dll ...) Anda dapat menggunakan penangan atau menjalankanOnUiThread (Saya lebih suka ini) untuk menampilkan hasil pemrosesan. ini benar-benar menyelesaikan masalah. menggunakan utas pekerja sangat berguna atau bahkan harus digunakan dalam hal ini.

Hossein Karami
sumber
1

Saya memiliki masalah yang sama. Ketika saya menjalankan kode di komputer lain, itu berfungsi dengan baik. Namun, pada saya, ini ditampilkan "Aplikasi mungkin melakukan terlalu banyak pekerjaan pada utas utamanya".

Saya memecahkan masalah saya dengan me-restart Android studio [File -> cache / Restart tidak valid -> klik pada "Validasi dan Restart"].

sonida
sumber
Saya tidak tahu mengapa solusi Anda berhasil. Bagaimanapun terima kasih.
Bhuvanesh BS
1

Dalam kasus saya, itu karena saya tidak sengaja menetapkan breakpoint pada suatu metode. Setelah saya menyelesaikannya, pesannya hilang dan kinerja meningkat banyak.

FractalBob
sumber
0

Aplikasi saya memiliki masalah yang sama. Tapi itu tidak melakukan selain menampilkan daftar kartu dan teks di atasnya. Tidak ada yang berjalan di latar belakang. Tetapi kemudian setelah beberapa penyelidikan menemukan bahwa gambar yang ditetapkan untuk latar belakang kartu menyebabkan hal ini, meskipun kecil (350kb). Kemudian saya mengkonversi gambar ke 9patch gambar menggunakan http://romannurik.github.io/AndroidAssetStudio/index.html .
Ini berhasil untuk saya.

naamadheya
sumber
0

Setelah melakukan banyak penelitian dan pengembangan untuk masalah ini, saya mendapat Solusi,

Dalam kasus saya, saya menggunakan Layanan yang akan berjalan setiap 2 detik dan dengan runonUIThread, saya bertanya-tanya masalahnya ada di sana tetapi tidak sama sekali. Masalah berikutnya yang saya temukan adalah bahwa saya menggunakan Gambar besar di App Mei dan itulah masalahnya.

Saya menghapus Gambar dan mengatur Gambar baru.

Kesimpulan: - Lihat kode Anda apakah ada file mentah yang Anda gunakan berukuran besar.

Hector Morris
sumber
0

Pertama baca peringatannya. Dikatakan lebih banyak memuat pada utas utama. Jadi yang harus Anda lakukan hanyalah menjalankan fungsi dengan lebih banyak pekerjaan dalam utas.

de_billa_
sumber
-1

Saya mendapat masalah yang sama ketika mengembangkan aplikasi yang menggunakan banyak file png yang dapat digambar pada tata letak kotak. Saya juga mencoba untuk mengoptimalkan kode saya sejauh mungkin .. tetapi tidak berhasil bagi saya .. Kemudian saya mencoba untuk mengurangi ukuran png itu .. dan kira itu berfungsi dengan sangat baik .. Jadi saran saya adalah untuk mengurangi ukuran sumber daya yang dapat ditarik jika ada ..

Shubham Ranakoti
sumber