Android Async Task State -
i using asynctask
in fragment
doing background operations. able handle state of async task in fragments using setretaininstance(true)
i.e., during orientation changes.
the problem is, want save status of async task(whether pending or finished) when call activity fragment. because when come activity fragment async task not being retained.
note:
setretaininstance(true)
works during orientation changes, onsaveinstancestate(bundle bundle)
wont work if setretaininstance(true)
written. onsaveintancestate(bundle bundle)
works when fragment or activity called.
this example straight api demos retains progress on orientation changes. please use , modify per need. code simple , once understand it, piece of cake handle progress on orientation changes. can ignore mthread
, implement asynctask
there, have look:
import com.example.android.apis.r; import android.app.activity; import android.app.fragment; import android.app.fragmentmanager; import android.os.bundle; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.view.view.onclicklistener; import android.widget.button; import android.widget.progressbar; /** * example shows how can use fragment propagate state * (such threads) across activity instances when activity needs * restarted due to, example, configuration change. lot * easier using raw activity.onretainnonconfiguratininstance() api. */ public class fragmentretaininstance extends activity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // first time init, create ui. if (savedinstancestate == null) { getfragmentmanager().begintransaction().add(android.r.id.content, new uifragment()).commit(); } } /** * fragment showing ui updated work done * in retained fragment. */ public static class uifragment extends fragment { retainedfragment mworkfragment; @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view v = inflater.inflate(r.layout.fragment_retain_instance, container, false); // watch button clicks. button button = (button)v.findviewbyid(r.id.restart); button.setonclicklistener(new onclicklistener() { public void onclick(view v) { mworkfragment.restart(); } }); return v; } @override public void onactivitycreated(bundle savedinstancestate) { super.onactivitycreated(savedinstancestate); fragmentmanager fm = getfragmentmanager(); // check see if have retained worker fragment. mworkfragment = (retainedfragment)fm.findfragmentbytag("work"); // if not retained (or first time running), need create it. if (mworkfragment == null) { mworkfragment = new retainedfragment(); // tell working with. mworkfragment.settargetfragment(this, 0); fm.begintransaction().add(mworkfragment, "work").commit(); } } } /** * fragment implementation retained across * activity instances. represents ongoing work, here thread * have sits around incrementing progress indicator. */ public static class retainedfragment extends fragment { progressbar mprogressbar; int mposition; boolean mready = false; boolean mquiting = false; /** * thread our work. sits in loop running * progress until has reached top, stops , waits. */ final thread mthread = new thread() { @override public void run() { // we'll figure real value out later. int max = 10000; // thread runs forever. while (true) { // update our shared state ui. synchronized (this) { // our thread stopped if ui not ready // or has completed work. while (!mready || mposition >= max) { if (mquiting) { return; } try { wait(); } catch (interruptedexception e) { } } // update progress. note important // touch progress bar lock held, // doesn't disappear on us. mposition++; max = mprogressbar.getmax(); mprogressbar.setprogress(mposition); } // doing work, put kludge // here pretend are. synchronized (this) { try { wait(50); } catch (interruptedexception e) { } } } } }; /** * fragment initialization. way want retained , * start our thread. */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // tell framework try keep fragment around // during configuration change. setretaininstance(true); // start worker thread. mthread.start(); } /** * called when fragment's activity ready go, after * content view has been installed; called both after * initial fragment creation , after fragment re-attached * new activity. */ @override public void onactivitycreated(bundle savedinstancestate) { super.onactivitycreated(savedinstancestate); // retrieve progress bar target's view hierarchy. mprogressbar = (progressbar)gettargetfragment().getview().findviewbyid( r.id.progress_horizontal); // ready our thread go. synchronized (mthread) { mready = true; mthread.notify(); } } /** * called when fragment going away. not called * when fragment being propagated between activity instances. */ @override public void ondestroy() { // make thread go away. synchronized (mthread) { mready = false; mquiting = true; mthread.notify(); } super.ondestroy(); } /** * called right before fragment detached * current activity instance. */ @override public void ondetach() { // fragment being detached activity. need // make sure thread not going touch activity // state after returning function. synchronized (mthread) { mprogressbar = null; mready = false; mthread.notify(); } super.ondetach(); } /** * api our ui restart progress thread. */ public void restart() { synchronized (mthread) { mposition = 0; mthread.notify(); } } } }
Comments
Post a Comment