Estoy trabajando en una aplicación para teléfono inteligente / tableta, usando solo un APK y cargando recursos según sea necesario según el tamaño de la pantalla, la mejor opción de diseño parecía ser usar Fragmentos a través de ACL.
Esta aplicación ha funcionado bien hasta ahora y solo se basa en actividades. Esta es una clase simulada de cómo manejo AsyncTasks y ProgressDialogs en las actividades para que funcionen incluso cuando se gira la pantalla o se produce un cambio de configuración en medio de la comunicación.
No cambiaré el manifiesto para evitar la recreación de la Actividad, hay muchas razones por las que no quiero hacerlo, pero principalmente porque los documentos oficiales dicen que no se recomienda y me las he arreglado sin él hasta ahora, así que por favor no lo recomiendo. ruta.
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
}
}
}
}
Este código funciona bien, tengo alrededor de 10.000 usuarios sin quejas, por lo que parecía lógico copiar esta lógica en el nuevo Diseño Basado en Fragmentos, pero, por supuesto, no funciona.
Aquí está el 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
}
}
}
}
}
No puedo usarlo onRetainNonConfigurationInstance()
ya que debe llamarse desde la Actividad y no desde el Fragmento, lo mismo ocurre con getLastNonConfigurationInstance()
. He leído algunas preguntas similares aquí sin respuesta.
Entiendo que podría requerir algo de trabajo para organizar estas cosas correctamente en fragmentos, dicho esto, me gustaría mantener la misma lógica de diseño básica.
¿Cuál sería la forma correcta de retener AsyncTask durante un cambio de configuración y, si aún se está ejecutando, mostrar un progressDialog, teniendo en cuenta que AsyncTask es una clase interna del Fragmento y es el Fragmento en sí quien invoca el AsyncTask.execute? ()?