Saya sedang mengerjakan aplikasi Smartphone / Tablet, hanya menggunakan satu APK, dan memuat sumber daya yang diperlukan tergantung pada ukuran layar, pilihan desain terbaik tampaknya menggunakan Fragmen melalui ACL.
Aplikasi ini telah berfungsi dengan baik sampai sekarang hanya berdasarkan aktivitas. Ini adalah kelas tiruan tentang cara saya menangani AsyncTasks dan ProgressDialogs dalam Aktivitas agar dapat berfungsi bahkan saat layar diputar atau perubahan konfigurasi terjadi di tengah komunikasi.
Saya tidak akan mengubah manifes untuk menghindari rekreasi Aktivitas, ada banyak alasan mengapa saya tidak ingin melakukannya, tetapi terutama karena dokumen resmi mengatakan itu tidak direkomendasikan dan saya sudah berhasil tanpanya sejauh ini, jadi tolong jangan rekomendasikan itu rute.
public class Login extends Activity {
static ProgressDialog pd;
AsyncTask<String, Void, Boolean> asyncLoginThread;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.login);
//SETUP UI OBJECTS
restoreAsyncTask();
}
@Override
public Object onRetainNonConfigurationInstance() {
if (pd != null) pd.dismiss();
if (asyncLoginThread != null) return (asyncLoginThread);
return super.onRetainNonConfigurationInstance();
}
private void restoreAsyncTask();() {
pd = new ProgressDialog(Login.this);
if (getLastNonConfigurationInstance() != null) {
asyncLoginThread = (AsyncTask<String, Void, Boolean>) getLastNonConfigurationInstance();
if (asyncLoginThread != null) {
if (!(asyncLoginThread.getStatus()
.equals(AsyncTask.Status.FINISHED))) {
showProgressDialog();
}
}
}
}
public class LoginThread extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... args) {
try {
//Connect to WS, recieve a JSON/XML Response
//Place it somewhere I can use it.
} catch (Exception e) {
return true;
}
return true;
}
protected void onPostExecute(Boolean result) {
if (result) {
pd.dismiss();
//Handle the response. Either deny entry or launch new Login Succesful Activity
}
}
}
}
Kode ini berfungsi dengan baik, saya memiliki sekitar 10.000 pengguna tanpa keluhan, jadi sepertinya logis untuk hanya menyalin logika ini ke Desain Berbasis Fragmen yang baru, tetapi, tentu saja, ini tidak berfungsi.
Berikut adalah LoginFragment:
public class LoginFragment extends Fragment {
FragmentActivity parentActivity;
static ProgressDialog pd;
AsyncTask<String, Void, Boolean> asyncLoginThread;
public interface OnLoginSuccessfulListener {
public void onLoginSuccessful(GlobalContainer globalContainer);
}
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
//Save some stuff for the UI State
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setRetainInstance(true);
//If I setRetainInstance(true), savedInstanceState is always null. Besides that, when loading UI State, a NPE is thrown when looking for UI Objects.
parentActivity = getActivity();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
loginSuccessfulListener = (OnLoginSuccessfulListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnLoginSuccessfulListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RelativeLayout loginLayout = (RelativeLayout) inflater.inflate(R.layout.login, container, false);
return loginLayout;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//SETUP UI OBJECTS
if(savedInstanceState != null){
//Reload UI state. Im doing this properly, keeping the content of the UI objects, not the object it self to avoid memory leaks.
}
}
public class LoginThread extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... args) {
try {
//Connect to WS, recieve a JSON/XML Response
//Place it somewhere I can use it.
} catch (Exception e) {
return true;
}
return true;
}
protected void onPostExecute(Boolean result) {
if (result) {
pd.dismiss();
//Handle the response. Either deny entry or launch new Login Succesful Activity
}
}
}
}
}
Saya tidak dapat menggunakan onRetainNonConfigurationInstance()
karena harus dipanggil dari Aktivitas dan bukan Fragmen, begitu juga dengan getLastNonConfigurationInstance()
. Saya telah membaca beberapa pertanyaan serupa di sini tanpa jawaban.
Saya mengerti bahwa mungkin diperlukan beberapa pekerjaan untuk mengatur barang-barang ini dengan benar dalam fragmen, yang dikatakan, saya ingin mempertahankan logika desain dasar yang sama.
Apa cara yang tepat untuk mempertahankan AsyncTask selama perubahan konfigurasi, dan jika masih berjalan, tunjukkan progressDialog, dengan mempertimbangkan bahwa AsyncTask adalah kelas dalam ke Fragmen dan Fragmen itu sendiri yang memanggil AsyncTask.execute ()?