ฉันกำลังทำงานกับแอปสมาร์ทโฟน / แท็บเล็ตโดยใช้ APK เพียงไฟล์เดียวและโหลดทรัพยากรตามความจำเป็นทั้งนี้ขึ้นอยู่กับขนาดหน้าจอตัวเลือกการออกแบบที่ดีที่สุดดูเหมือนจะใช้ Fragments ผ่าน ACL
แอปนี้ทำงานได้ดีจนถึงขณะนี้เป็นเพียงกิจกรรมเท่านั้น นี่เป็นคลาสจำลองของวิธีที่ฉันจัดการ AsyncTasks และ ProgressDialogs ใน Activities เพื่อให้ทำงานได้แม้จะหมุนหน้าจอหรือมีการเปลี่ยนแปลงการกำหนดค่าเกิดขึ้นระหว่างการสื่อสาร
ฉันจะไม่เปลี่ยนรายการเพื่อหลีกเลี่ยงการพักผ่อนหย่อนใจของกิจกรรมมีสาเหตุหลายประการที่ฉันไม่ต้องการทำ แต่ส่วนใหญ่เป็นเพราะเอกสารอย่างเป็นทางการบอกว่าไม่แนะนำและฉันได้จัดการโดยที่ยังไม่ได้ทำกิจกรรมนี้ดังนั้นโปรดอย่าแนะนำว่า เส้นทาง.
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 ใหม่ แต่แน่นอนว่ามันไม่ทำงาน
นี่คือ 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 getLastNonConfigurationInstance()
กันไปด้วย ฉันได้อ่านคำถามที่คล้ายกันที่นี่โดยไม่มีคำตอบ
ฉันเข้าใจว่าอาจต้องใช้ความพยายามในการจัดระเบียบสิ่งนี้อย่างถูกต้องในส่วนย่อยที่ถูกกล่าวว่าฉันต้องการคงตรรกะการออกแบบพื้นฐานเดิมไว้
อะไรคือวิธีที่เหมาะสมในการรักษา AsyncTask ในระหว่างการเปลี่ยนแปลงการกำหนดค่าและหากยังคงรันอยู่ให้แสดง progressDialog โดยคำนึงว่า AsyncTask เป็นคลาสภายในของ Fragment และเป็น Fragment เองที่เรียกใช้ AsyncTask.execute ()?