저는 스마트 폰 / 태블릿 앱에서 작업 중이며 하나의 APK 만 사용하고 화면 크기에 따라 필요한 리소스를로드하는 중입니다. 최상의 디자인 선택은 ACL을 통해 프래그먼트를 사용하는 것 같습니다.
이 앱은 지금까지 활동 기반으로 만 잘 작동했습니다. 이것은 화면이 회전하거나 통신 중에 구성 변경이 발생하는 경우에도 작동하도록 활동에서 AsyncTasks 및 ProgressDialogs를 처리하는 방법에 대한 모의 클래스입니다.
나는 활동의 재현을 피하기 위해 매니페스트를 변경하지 않을 것입니다. 내가 원하지 않는 이유는 여러 가지가 있지만 주로 공식 문서가 권장하지 않는다고 말하고 지금까지 그것을 관리하지 않았기 때문에 권장하지 마십시오 노선.
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
}
}
}
}
이 코드는 잘 작동하고 있으며 불만없이 약 10.000 명의 사용자가 있으므로이 로직을 새로운 Fragment Based Design에 복사하는 것이 논리적으로 보였지만 물론 작동하지 않습니다.
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
}
}
}
}
}
onRetainNonConfigurationInstance()
Fragment가 아닌 Activity에서 호출해야하므로 사용할 수 없습니다 getLastNonConfigurationInstance()
. 나는 여기에서 답이없는 유사한 질문을 읽었습니다.
나는이 물건을 조각으로 올바르게 구성하기 위해 약간의 작업이 필요할 수 있음을 이해합니다. 즉, 동일한 기본 디자인 논리를 유지하고 싶습니다.
구성 변경 중에 AsyncTask를 유지하는 적절한 방법은 무엇이며, 여전히 실행중인 경우 AsyncTask가 Fragment의 내부 클래스이고 AsyncTask.execute를 호출하는 것은 Fragment 자체임을 고려하여 progressDialog를 표시합니다. ()?