Habr рдкрд░ рдПрдХ рдЕрдЪреНрдЫрд╛
рд▓реЗрдЦ рдкрд╣рд▓реЗ рд╣реА рдкреНрд░рдХрд╛рд╢рд┐рдд рд╣реЛ рдЪреБрдХрд╛ рд╣реИ рдЬреЛ ProgressDialog рдФрд░ AsyncTask рдХреЗ рд╕рдВрдпреБрдХреНрдд рдЙрдкрдпреЛрдЧ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ, рдпрд╣рд╛рдБ рдореИрдВ рд╡рд░реНрдгрди рдХрд░реВрдБрдЧрд╛ рдХрд┐ рд╕рдорд╛рди рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рд▓реЗрдХрд┐рди рдЯреБрдХрдбрд╝реЛрдВ рдкрд░, рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ
DialogFragment рдФрд░
AsyncTaskLader рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗред
рддреЛ рд▓рдХреНрд╖реНрдп:
- рдкреНрд░реЛрдЧреНрд░реЗрд╕рдбрд┐рдУрд▓реЙрдЧ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ рдЬрдм рдПрдХ рд▓рдВрдмрд╛ рдСрдкрд░реЗрд╢рди рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рд╕рдВрджреЗрд╢ рдкрд╛рда рдХрд╛рд░реНрдп рдХреА рдкреНрд░рдЧрддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ;
- рдЕрдиреБрдкреНрд░рдпреЛрдЧ рджреНрд╡рд╛рд░рд╛ рдЕрднрд┐рд╡рд┐рдиреНрдпрд╛рд╕ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╕рдорд░реНрдердиред

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
1. рд╣рдо рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рд╕рдВрджреЗрд╢ рдХреЛ AbstractTaskLoader рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ, AsyncTaskLoader рдХреЗ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА рд╕реЗ рднреЗрдЬ рджреЗрдВрдЧреЗ:
public abstract class AbstractTaskLoader extends AsyncTaskLoader<Object> {
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдорд╛рд░рд╛ рд╡рд░реНрдЧ рдЬреЛ рдХреБрдЫ рд▓рдВрдмрд╛ рдСрдкрд░реЗрд╢рди рдХрд░рддрд╛ рд╣реИ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИ рдФрд░ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ:
@Override public Object loadInBackground() { тАж publishMessage(result); тАж }
2. рдЕрдЧрд▓рд╛ рдХрджрдо рд╕реНрдХреНрд░реАрди рдУрд░рд┐рдПрдВрдЯреЗрд╢рди рдХреЛ рдмрджрд▓рддреЗ рд╕рдордп рд╣рдорд╛рд░реЗ рд▓реЛрдбрд░ рдХреЗ рд╕рд╣реА рд╢реБрд░реБрдЖрдд / рдкреБрдирдГ рдЖрд░рдВрдн рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдкреНрд░реЛрдЧреНрд░реЗрд╕рдбрд╛рдпрд▓реЙрдЧ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдФрд░ рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдХрдХреНрд╖рд╛ рдореЗрдВ рд▓реЛрдбрд░ рдФрд░ рд╕рдВрд╡рд╛рдж рдХреЗ рд▓рд┐рдП рдХреЙрд▓рдмреИрдХ рд╣реИрдВрдбрд▓рд░ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:
public abstract class AbstractTaskProgressDialogFragment extends DialogFragment implements LoaderCallbacks<Object>, OnCancelListener { private ProgressDialog progressDialog; private final AbstractTaskLoader loader; protected abstract void onLoadComplete(Object data); protected abstract void onCancelLoad(); protected AbstractTaskProgressDialogFragment(AbstractTaskLoader loader,String message){ loader.setHandler(handler); this.loader = loader; Bundle args = new Bundle(); args.putString("message", message); setArguments(args); } @Override public ProgressDialog onCreateDialog(Bundle savedInstanceState) { String message = getArguments().getString("message"); progressDialog = new ProgressDialog(getActivity()); progressDialog.setMessage(message); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.setOnCancelListener(this); progressDialog.show(); return progressDialog; } private final Handler handler = new Handler() { public void handleMessage(Message msg) { if(msg.what == AbstractTaskLoader.MSGCODE_MESSAGE){ String message = AbstractTaskLoader.getMessageValue(msg); if(message!=null){
рд╡рд░реНрдЧ рдХреЛ рднреА рд╕рд╛рд░ рдмрдирд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдХрдо рд╕реЗ рдХрдо рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд▓реНрдкреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рдХреЗрд╡рд▓ рдХрд╛рдо рдХреЗ рдкрд░рд┐рдгрд╛рдо рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИрдВ:
onLoadComplete (рдСрдмреНрдЬреЗрдХреНрдЯ рдбреЗрдЯрд╛);
onCancelLoad ();
рдФрд░ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА рдореЗрдВ рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (рдореИрдВрдиреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд┐рдпрд╛ рдерд╛, рдиреАрдЪреЗ рджреЗрдЦреЗрдВ)ред
рдпрд╣рд╛рдВ, рд▓реЛрдбрд░ рдХреЛ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рд╕рдВрджреЗрд╢ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рддреБрд░рдВрдд рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдЧрд╛ред рд╣реИрдВрдбрд▓рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдкреНрд░рдЧрддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЛрдбрд░ рд╕реЗ рд╕реВрдЪрдирд╛ рд╕рдВрджреЗрд╢ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред OnCreateDialog рдореЗрдВ, рд╣рдорд╛рд░рд╛ рд╕рдВрд╡рд╛рдж рдмрдирд╛рдПрдВ рдФрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВред
рдЕрдЧрд▓рд╛, рд╣рдореЗрдВ рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд╕реНрдХреНрд░реАрди рдУрд░рд┐рдПрдВрдЯреЗрд╢рди рдмрджрд▓рддреЗ рд╕рдордп, рдпрд╣ рдЯреБрдХрдбрд╝рд╛ рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрд░рдХрд░рд╛рд░ рд░рдЦрддрд╛ рд╣реИред рдпрд╣
setRainainInstance (рдЯреНрд░реВ) рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ
onDestroy рддрдм рдирд╣реАрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдм рд╕реНрдХреНрд░реАрди рдУрд░рд┐рдПрдВрдЯреЗрд╢рди рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рдП, рдФрд░ рдбрд╛рдпрд▓реЙрдЧ рдмрдВрдж рдирд╣реАрдВ рд╣реЛрдЧрд╛ред
@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setRetainInstance(true);
рд╣рдо onActivityCreated рд╡рд┐рдзрд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдЕрдкрдиреЗ рд▓реЛрдбрд░ рдХреЛ рдкрд╣рд▓реА рдмрд╛рд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдореМрдЬреВрджрд╛ рдПрдХ рд╕реЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ (рдЬрдм рд╕реНрдХреНрд░реАрди рдУрд░рд┐рдПрдВрдЯреЗрд╢рди рдмрджрд▓рддреЗ рд╣реИрдВ)ред
рдПрдХ рдЫреЛрдЯрд╛ рд╡рд┐рд╖рдпрд╛рдВрддрд░:SetRetainInstance рдкрджреНрдзрддрд┐ рдбрд╛рдпрд▓реЙрдЧрдлреНрд░реЗрдЧреНрдореЗрдВрдЯ рдХреЗ рд▓рд┐рдП "
рд╕рдВрдЧрддрддрд╛-рд▓рд╛рдЗрдмреНрд░реЗрд░реА " рдХреЗ рд╕рд╛рде рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИ, рдЕрд░реНрдерд╛рдд рдСрдирд╕реНрдЯреНрд░реЗрд╕реНрдЯ рд╡рд┐рдзрд┐ рдХреЛ рдЕрднреА рднреА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ, рд╣рдорд╛рд░реЗ рд╕рдВрд╡рд╛рдж рдореЗрдВ рд╣рдо рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:
@Override public void onDestroyView() { if (getDialog() != null && getRetainInstance()) getDialog().setOnDismissListener(null); super.onDestroyView(); }
рдпрд╣рд╛рдБ рд╡рд┐рд╡рд░рдгред
рд▓реЛрдбрд░ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдФрд░ рд╢рдЯрдбрд╛рдЙрди рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг:
@Override public Loader<Object> onCreateLoader(int id, Bundle args) { loader.forceLoad(); return loader; } @Override public void onLoadFinished(Loader<Object> loader, Object data) { onLoadComplete(data); ((AbstractTaskLoader) loader).setHandler(null); hideDialog(); }
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд░рджреНрдж рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ - "рдмреИрдХ" рдмрдЯрди рджрдмрд╛рдХрд░:
@Override public void onCancel(DialogInterface dialog) { super.onCancel(dialog); loader.cancelLoad();
3. рдмреЗрд╕ рдлреНрд░реЗрдо рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЕрдм рд╣рдо рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреА рд╕реВрдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрдирд╛рдПрдБ:
public interface ITaskLoaderListener { void onLoadFinished(Object data); void onCancelLoad(); }
рд╣рдо рдмрдирд╛рдпрд╛ рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╣рдорд╛рд░реЗ ProgressDialog рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмрдирд╛рддреЗ рд╣реИрдВ:
public class TaskProgressDialogFragment extends AbstractTaskProgressDialogFragment { private ITaskLoaderListener taskLoaderListener; private final Handler handler = new Handler(); protected TaskProgressDialogFragment(AbstractTaskLoader loader, String message) { super(loader, message); } protected void setTaskLoaderListener(ITaskLoaderListener taskLoaderListener){ this.taskLoaderListener = taskLoaderListener; } @Override protected void onLoadComplete(final Object data) { if(taskLoaderListener!=null){ taskLoaderListener.onLoadFinished(data); } } @Override protected void onCancelLoad() { if (taskLoaderListener != null) { taskLoaderListener.onCancelLoad(); } } ...
рдФрд░ рд▓реЛрдбрд░ рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдмрдирд╛рдиреЗ рдФрд░ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд┐рд▓реНрдбрд░:
public static class Builder { FragmentActivity fa; AbstractTaskLoader loader; ITaskLoaderListener taskLoaderListener; Boolean cancelable; String progressMsg; public Builder(FragmentActivity fa, AbstractTaskLoader loader, String progressMsg) { this.fa = fa; this.loader = loader; this.progressMsg = progressMsg; } public Builder setTaskLoaderListener( ITaskLoaderListener taskLoaderListener) { this.taskLoaderListener = taskLoaderListener; return this; } public Builder setCancelable(Boolean cancelable) { this.cancelable = cancelable; return this; } public void show() { String TAG_FRAGMENT = UUID.randomUUID().toString();
4. рдЕрдВрдд рдореЗрдВ, рдпрд╣ рд╣рдорд╛рд░рд╛ рд▓реЛрдбрд░ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╕рд┐рд░реНрдл ProgreesDialog-e рдореЗрдВ рд╕рдВрджреЗрд╢ рдкрд░реАрдХреНрд╖рдг рдХреЛ рд╣рд░ рдкрд▓ рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛ рд╣реИ:
public class SampleTask extends AbstractTaskLoader { @Override public Object loadInBackground() { String result = ""; for(int i=0; i<10;i++){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } result = "Wait: " + String.valueOf(i); publishMessage(result); if(isCanselled()){ break; } Log.d(TAG, result); } return result; }
рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ:
public static void execute(FragmentActivity fa, ITaskLoaderListener taskLoaderListener) { SampleTask loader = new SampleTask(fa); new TaskProgressDialogFragment.Builder(fa, loader, "Wait...") .setCancelable(true) .setTaskLoaderListener(taskLoaderListener) .show(); }
5. рдЪреБрдиреМрддреА
public class SampleActivity extends FragmentActivity implements ITaskLoaderListener{ тАж SampleTask.execute(this, this); @Override public void onCancelLoad() { Log.d(TAG, "task canceled"); } @Override public void onLoadFinished(Object data) { if(data!=null && data instanceof String){ Log.d(TAG, "task result: " + data); } }
рдЙрджрд╛рд╣рд░рдг
рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ
рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ , рд░рдЪрдирд╛рддреНрдордХ рдЖрд▓реЛрдЪрдирд╛ рдФрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред
рд╕реВрддреНрд░реЛрдВ рдХрд╛ рдХрд╣рдирд╛ рд╣реИ:
1. рдПрд╡реЗрд▓рд┐рдирд╛ рд╡реНрд░рд╛рдмреА рдмреНрд▓реЙрдЧ, рд▓реЗрдЦ
'рдПрдВрдбреНрд░реЙрдЗрдб рдлреНрд░реЗрдЧрдореЗрдВрдЯреНрд╕, рд╕реЗрд╡рд┐рдВрдЧ рд╕реНрдЯреЗрдЯ рдПрдВрдб рд╕реНрдХреНрд░реАрди рд░реЛрдЯреЗрд╢рди'2. рдвреЗрд░ рдЕрддрд┐рдкреНрд░рд╡рд╛рд╣