Bir Akıllı Telefon / Tablet uygulaması üzerinde çalışıyorum, yalnızca bir APK kullanıyorum ve ekran boyutuna bağlı olarak kaynakları gerektiği gibi yüklüyorum, en iyi tasarım seçeneği ACL aracılığıyla Fragments kullanıyor gibiydi.
Bu uygulama şu ana kadar sadece aktivite tabanlı olarak iyi çalışıyordu. Bu, ekran döndürüldüğünde veya iletişimin ortasında bir yapılandırma değişikliği meydana geldiğinde bile çalışmalarını sağlamak için Etkinliklerdeki AsyncTasks ve ProgressDialogs'u nasıl işlediğimin sahte bir sınıfıdır.
Faaliyetin yeniden yaratılmasını önlemek için manifestosu değiştirmeyeceğim, bunu yapmak istemememin birçok nedeni var, ancak esas olarak resmi belgeler tavsiye edilmediğini söylediği ve şimdiye kadar onsuz başardım, bu yüzden lütfen bunu rota.
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
}
}
}
}
Bu kod iyi çalışıyor, şikayet etmeden yaklaşık 10.000 kullanıcım var, bu yüzden bu mantığı yeni Parça Tabanlı Tasarım'a kopyalamak mantıklı görünüyordu, ama elbette çalışmıyor.
İşte 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
}
}
}
}
}
Parçadan onRetainNonConfigurationInstance()
değil, Etkinlikten çağrılması gerektiğinden kullanamıyorum, aynı şey geçerli getLastNonConfigurationInstance()
. Burada cevapsız benzer sorular okudum.
Bu şeyleri parçalar halinde düzgün bir şekilde organize etmek için biraz çalışma gerektirebileceğini anlıyorum, aynı temel tasarım mantığını korumak istiyorum.
Bir yapılandırma değişikliği sırasında AsyncTask'ı korumanın uygun yolu nedir ve hala çalışıyorsa, AsyncTask'ın Fragment için bir iç sınıf olduğunu ve AsyncTask.execute'u çağıran Fragment'in kendisi olduğunu dikkate alarak bir progressDialog gösterin. ()?