Tôi đang làm việc trên ứng dụng Điện thoại thông minh / Máy tính bảng, chỉ sử dụng một APK và tải tài nguyên khi cần thiết tùy thuộc vào kích thước màn hình, lựa chọn thiết kế tốt nhất dường như là sử dụng Fragment qua ACL.
Ứng dụng này đã hoạt động tốt cho đến bây giờ chỉ dựa trên hoạt động. Đây là một lớp mô phỏng về cách tôi xử lý AsyncTasks và ProgressDialogs trong Hoạt động để chúng hoạt động ngay cả khi màn hình được xoay hoặc thay đổi cấu hình xảy ra giữa giao tiếp.
Tôi sẽ không thay đổi tệp kê khai để tránh tái tạo Hoạt động, có nhiều lý do khiến tôi không muốn làm điều đó, nhưng chủ yếu là do các tài liệu chính thức nói rằng nó không được khuyến khích và tôi đã quản lý mà không có nó cho đến nay, vì vậy vui lòng không khuyến nghị điều đó lộ trình.
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
}
}
}
}
Mã này đang hoạt động tốt, tôi có khoảng 10.000 người dùng mà không có khiếu nại, vì vậy có vẻ hợp lý khi chỉ sao chép logic này vào Thiết kế dựa trên phân mảnh mới, nhưng tất nhiên, nó không hoạt động.
Đây là 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
}
}
}
}
}
Tôi không thể sử dụng onRetainNonConfigurationInstance()
vì nó phải được gọi từ Activity chứ không phải Fragment, điều tương tự cũng xảy ra getLastNonConfigurationInstance()
. Tôi đã đọc một số câu hỏi tương tự ở đây mà không có câu trả lời.
Tôi hiểu rằng nó có thể yêu cầu một số hoạt động xung quanh để sắp xếp thứ này một cách hợp lý trong các phân đoạn, điều đó đang nói, tôi muốn duy trì cùng một logic thiết kế cơ bản.
Đâu sẽ là cách thích hợp để giữ lại AsyncTask trong quá trình thay đổi cấu hình và nếu nó vẫn chạy, hãy hiển thị một processDialog, lưu ý rằng AsyncTask là một lớp bên trong của Fragment và chính Fragment sẽ gọi AsyncTask.execute ()?