Saya mengunduh beberapa data dari internet di utas latar (saya menggunakan AsyncTask
) dan menampilkan dialog progres saat mengunduh. Perubahan orientasi, Aktivitas dimulai kembali dan kemudian AsyncTask saya selesai - Saya ingin mengabaikan dialog progess dan memulai Kegiatan baru. Tetapi memanggil dismissDialog terkadang mengeluarkan pengecualian (mungkin karena Aktivitas dihancurkan dan Aktivitas baru belum dimulai).
Apa cara terbaik untuk menangani masalah semacam ini (memperbarui UI dari utas latar belakang yang berfungsi bahkan jika pengguna mengubah orientasi)? Apakah seseorang dari Google memberikan beberapa "solusi resmi"?
Jawaban:
Langkah # 1: Membuat
AsyncTask
sebuahstatic
kelas bersarang, atau kelas yang sama sekali terpisah, hanya bukan (non-static bersarang) kelas batin.Langkah # 2: Memiliki
AsyncTask
pegangan keActivity
melalui anggota data, atur melalui konstruktor dan setter.Langkah # 3: Saat membuat
AsyncTask
, suplai arusActivity
ke konstruktor.Langkah # 4: Masuk
onRetainNonConfigurationInstance()
, kembalikanAsyncTask
, setelah melepaskannya dari aktivitas asli, yang sekarang sudah tidak ada.Langkah # 5: Di
onCreate()
, jikagetLastNonConfigurationInstance()
tidaknull
, serahkan keAsyncTask
kelas Anda dan panggil setter Anda untuk mengaitkan aktivitas baru Anda dengan tugas tersebut.Langkah # 6: Jangan merujuk ke data aktivitas anggota
doInBackground()
.Jika Anda mengikuti resep di atas, semuanya akan berhasil.
onProgressUpdate()
danonPostExecute()
ditangguhkan antara awalonRetainNonConfigurationInstance()
dan akhir berikutnyaonCreate()
.Berikut adalah contoh proyek yang menunjukkan teknik ini.
Pendekatan lain adalah dengan membuang
AsyncTask
dan memindahkan pekerjaan Anda ke sebuahIntentService
. Ini sangat berguna jika pekerjaan yang harus dilakukan mungkin lama dan harus berlanjut terlepas dari apa yang dilakukan pengguna dalam hal kegiatan (misalnya, mengunduh file besar). Anda dapat menggunakan siaran yang dipesanIntent
untuk meminta aktivitas merespons pekerjaan yang sedang dilakukan (jika masih di latar depan) atau menaikkan aNotification
untuk memberi tahu pengguna jika pekerjaan telah dilakukan. Berikut adalah posting blog dengan lebih banyak tentang pola ini.sumber
onRetainNonConfigurationInstance()
sudah usang dan alternatif yang disarankan adalah menggunakansetRetainInstance()
, tetapi tidak mengembalikan objek. Apakah mungkin untuk menanganiasyncTask
perubahan konfigurasi dengansetRetainInstance()
?Fragment
palkaAsyncTask
. MilikilahFragment
panggilansetRetainInstance(true)
itu sendiri. ApakahAsyncTask
hanya berbicara denganFragment
. Sekarang, pada perubahan konfigurasi,Fragment
itu tidak dihancurkan dan diciptakan kembali (meskipun aktivitasnya), dan dengan demikianAsyncTask
dipertahankan melalui perubahan konfigurasi.Jawaban yang diterima sangat membantu, tetapi tidak memiliki dialog kemajuan.
Untungnya bagi Anda, pembaca, saya telah membuat contoh AsyncTask yang sangat komprehensif dan berfungsi dengan dialog kemajuan !
sumber
Saya sudah bekerja keras selama seminggu untuk menemukan solusi untuk dilema ini tanpa harus mengedit file manifes. Asumsi untuk solusi ini adalah:
Penerapan
Anda perlu menyalin dua file yang ditemukan di bagian bawah posting ini ke ruang kerja Anda. Pastikan saja:
Semua milik Anda
Activity
harus diperluasBaseActivity
In
onCreate()
,super.onCreate()
harus dipanggil setelah Anda menginisialisasi anggota yang perlu diakses oleh anggota AndaASyncTask
. Juga, gantigetContentViewId()
untuk memberikan id tata letak formulir.Ganti
onCreateDialog()
seperti biasa untuk membuat dialog yang dikelola oleh aktivitas.Lihat kode di bawah ini untuk contoh kelas dalam statis untuk membuat AsyncTasks Anda. Anda dapat menyimpan hasil Anda di mResult untuk diakses nanti.
Dan akhirnya, untuk meluncurkan tugas baru Anda:
Itu dia! Saya harap solusi yang kuat ini akan membantu seseorang.
BaseActivity.java (mengatur impor sendiri)
SuperAsyncTask.java
sumber
Iya.
Solusinya lebih dari proposal arsitektur aplikasi daripada hanya beberapa kode .
Mereka mengusulkan 3 pola desain yang memungkinkan aplikasi untuk bekerja dalam sinkronisasi dengan server, terlepas dari keadaan aplikasi (itu akan bekerja bahkan jika pengguna menyelesaikan aplikasi, layar perubahan pengguna, aplikasi akan dihentikan, setiap keadaan yang mungkin lainnya di mana operasi data latar belakang dapat diinterupsi, ini meliputi itu)
Proposal tersebut dijelaskan dalam pidato aplikasi klien Android REST selama Google I / O 2010 oleh Virgil Dobjanschi. Panjangnya 1 jam, tetapi sangat layak untuk ditonton.
Dasarnya adalah abstrak operasi jaringan ke
Service
yang bekerja secara independen keActivity
dalam aplikasi. Jika Anda bekerja dengan database, penggunaanContentResolver
danCursor
akan memberi Anda pola Observer out-of-the-box yang nyaman untuk memperbarui UI tanpa logika tambahan, setelah Anda memperbarui database lokal Anda dengan data jarak jauh yang diambil. Kode setelah operasi lainnya akan dijalankan melalui callback yang diteruskan keService
(saya menggunakanResultReceiver
subkelas untuk ini).Pokoknya, penjelasan saya sebenarnya cukup kabur, Anda harus menonton pidato itu.
sumber
Meskipun jawaban Mark (CommonsWare) memang berfungsi untuk perubahan orientasi, namun gagal jika Aktivitas dihancurkan secara langsung (seperti dalam kasus panggilan telepon).
Anda dapat menangani perubahan orientasi DAN Peristiwa aktivitas yang jarang dihancurkan dengan menggunakan objek Aplikasi untuk referensi ASyncTask Anda.
Ada penjelasan yang sangat baik tentang masalah dan solusinya di sini :
Penghargaan sepenuhnya diberikan kepada Ryan untuk mengetahui yang satu ini.
sumber
Setelah 4 tahun Google menyelesaikan masalah dengan memanggil setRetainInstance (true) di Activity onCreate. Ini akan menjaga instance aktivitas Anda selama rotasi perangkat. Saya juga punya solusi sederhana untuk Android yang lebih lama.
sumber
Anda harus memanggil semua tindakan aktivitas menggunakan penangan aktivitas. Jadi jika Anda berada di utas Anda harus membuat Runnable dan memposting menggunakan Activitie's Handler. Kalau tidak, aplikasi Anda terkadang macet dengan pengecualian fatal.
sumber
Ini adalah solusi saya: https://github.com/Gotchamoh/Android-AsyncTask-ProgressDialog
Pada dasarnya langkah-langkahnya adalah:
onSaveInstanceState
untuk menyimpan tugas jika masih diproses.onCreate
saya mendapatkan tugas jika sudah disimpan.onPause
saya membuangProgressDialog
jika ditampilkan.onResume
saya tunjukkanProgressDialog
kalau tugas masih diproses.sumber