I have a class BaseDialog extends DialogFragment
After a while, i found out that the default DialogFragment.show() can cause some problems - if the activity is being shutdown, or destroyed etc...
After looking at the decompiled(?) source of DialogFragment, i stumble on this piece of code:
public void show(FragmentManager manager, String tag) {
mDismissed = false;
mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
}
And i figure to try a small 'hack' of my own to get rid of bugs relating to showing/dismissing dialogs after Activity has passed it's onSaveInstanceState()
call.
I came up with this:
public void showAllowingStateLoss(FragmentManager manager, String tag) {
try {
Class thiz = super.getClass();
Field dismissed = thiz.getField("mDismissed");
dismissed.setAccessible(true);
dismissed.set(thiz, false);
} catch(NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} //mDismissed = false;
try {
Class thiz = super.getClass();
Field shown = thiz.getField("mShownByMe");
shown.setAccessible(true);
shown.set(thiz, true);
} catch(IllegalAccessException e) {
e.printStackTrace();
} catch(NoSuchFieldException e) {
e.printStackTrace();
} //mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commitAllowingStateLoss();
}
Which works quite alright.
The problem I have now is this, i can't seem to access some of DialogFragment's fields to set them to their proper expected values like the original source does.
W/System.err( 2510): java.lang.NoSuchFieldException: mDismissed
W/System.err( 2510): at java.lang.Class.getField(Class.java:1048)
W/System.err( 2510): at com.dpd.navigator.ui.dialogs.BaseDialog.showAllowingStateLoss(BaseDialog.java:70)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin.openConfirmationDialog(ActivityLogin.java:250)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin.access$600(ActivityLogin.java:45)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin$SOAPListener_getUserLogin.onSOAPSuccess(ActivityLogin.java:306)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin$SOAPListener_getUserLogin.onSOAPSuccess(ActivityLogin.java:262)
W/System.err( 2510): at com.dpd.navigator.backend.soap.SOAPHelper$20.onPostExecute(SOAPHelper.java:1290)
W/System.err( 2510): at android.os.AsyncTask.finish(AsyncTask.java:632)
W/System.err( 2510): at android.os.AsyncTask.access$600(AsyncTask.java:177)
W/System.err( 2510): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
W/System.err( 2510): at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err( 2510): at android.os.Looper.loop(Looper.java:155)
W/System.err( 2510): at android.app.ActivityThread.main(ActivityThread.java:5696)
W/System.err( 2510): at java.lang.reflect.Method.invoke(Native Method)
W/System.err( 2510): at java.lang.reflect.Method.invoke(Method.java:372)
W/System.err( 2510): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
W/System.err( 2510): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
W/System.err( 2510): java.lang.NoSuchFieldException: mShownByMe
W/System.err( 2510): at java.lang.Class.getField(Class.java:1048)
W/System.err( 2510): at com.dpd.navigator.ui.dialogs.BaseDialog.showAllowingStateLoss(BaseDialog.java:81)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin.openConfirmationDialog(ActivityLogin.java:250)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin.access$600(ActivityLogin.java:45)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin$SOAPListener_getUserLogin.onSOAPSuccess(ActivityLogin.java:306)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin$SOAPListener_getUserLogin.onSOAPSuccess(ActivityLogin.java:262)
W/System.err( 2510): at com.dpd.navigator.backend.soap.SOAPHelper$20.onPostExecute(SOAPHelper.java:1290)
W/System.err( 2510): at android.os.AsyncTask.finish(AsyncTask.java:632)
W/System.err( 2510): at android.os.AsyncTask.access$600(AsyncTask.java:177)
W/System.err( 2510): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
W/System.err( 2510): at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err( 2510): at android.os.Looper.loop(Looper.java:155)
W/System.err( 2510): at android.app.ActivityThread.main(ActivityThread.java:5696)
W/System.err( 2510): at java.lang.reflect.Method.invoke(Native Method)
W/System.err( 2510): at java.lang.reflect.Method.invoke(Method.java:372)
W/System.err( 2510): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
W/System.err( 2510): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
W/System.err( 2510): java.lang.NoSuchFieldException: mViewDestroyed
W/System.err( 2510): at java.lang.Class.getField(Class.java:1048)
W/System.err( 2510): at com.dpd.navigator.ui.dialogs.BaseDialog.showAllowingStateLoss(BaseDialog.java:95)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin.openConfirmationDialog(ActivityLogin.java:250)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin.access$600(ActivityLogin.java:45)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin$SOAPListener_getUserLogin.onSOAPSuccess(ActivityLogin.java:306)
W/System.err( 2510): at com.dpd.navigator.ui.activities.ActivityLogin$SOAPListener_getUserLogin.onSOAPSuccess(ActivityLogin.java:262)
W/System.err( 2510): at com.dpd.navigator.backend.soap.SOAPHelper$20.onPostExecute(SOAPHelper.java:1290)
W/System.err( 2510): at android.os.AsyncTask.finish(AsyncTask.java:632)
W/System.err( 2510): at android.os.AsyncTask.access$600(AsyncTask.java:177)
W/System.err( 2510): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
W/System.err( 2510): at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err( 2510): at android.os.Looper.loop(Looper.java:155)
W/System.err( 2510): at android.app.ActivityThread.main(ActivityThread.java:5696)
W/System.err( 2510): at java.lang.reflect.Method.invoke(Native Method)
W/System.err( 2510): at java.lang.reflect.Method.invoke(Method.java:372)
W/System.err( 2510): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
W/System.err( 2510): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
And I'm wondering why can't I access those fields.... they're not static, so getField() should work. I've tried getDeclaredField()
as well - no dice.
So I'm starting to wonder - is it even feasible to try and access those fields using reflection? I know that some Android code (SDK code) is there "just for show" because we can't touch it - it runs in the AndroidRuntime
process which is why reflection can't do anything there.
Which is why i'm asking the question: am I not finding these fields because they're running in the AndroidRuntime process OR because i'm doing something wrong?
I can live with the first case. I would really like to set them to their expected values if it's the second case.
P.S. I'm really not interested in preachings about why using commitAllowingStateLoss
is wrong and/or bad. The focus of the question isn't that. The focus of the question is why can't I find these fields?
Thanks for help in advance :)
Aucun commentaire:
Enregistrer un commentaire