2016-09-16 5 views
0

XMLで記述されたフラグメントで定義されたアクティビティがあります。活動では、私は、フラグメントへの参照を取得:XMLで定義されたAndroidフラグメントは、親アクティビティとは異なるフラグメント内のインスタンスです。

@Override 
public void onStart() { 
    super.onStart(); 

    FragmentManager manager = getSupportFragmentManager(); 
    mFragment = (DetailActivityFragment) manager.findFragmentById(R.id.fragment); 
    ... 
} 

私はフラグメントの(カスタム)のupdateUI()メソッドを呼び出し、それが活動中とは異なるIDを持っています

DetailActivity: tbm 440; got fragment: (0x038c6009) (invisible) 
DetailActivityFragment: tbm 162; fragment: (0x05f54af9) updating UI 

そして、断片が破壊される:

DetailActivityFragment: tbm 131; destroying fragment (0x038c6009) 

アクティビティ内に作成された同じ断片、及び異なるすなわち実フラグメントから。

それが重要場合は、ここで私は、フラグメントIDのログイン方法は次のとおりです。

Log.d(TAG, String.format("tbm 162; (0x%08x) updating UI", System.identityHashCode(this)); 

はまた、「TBM 162」ログ声明に示されているIDは常に同じであり、常に最初のIDと一致しますフラグメントがインスタンス化された時刻。

この奇妙な理由はありますか?フラグメントのim-memory IDは、インスタンス化されてからフラグメントが内部で参照されるまでの間にどのように変化しますか?もちろん、updateUIメソッドの中では、(今は隠された、分離された)元のフラグメントに含まれるUI要素が参照されるため、UIは実際には視覚的に変化することはありません。

TIA!

編集:

のupdateUI()メソッドは何もしませんが、いくつかのフィールドを表示するので、私はそれが関連しているとは思わないが、私は何か欠けている場合には要求されるように:

public void updateUi(final InformativeBean bean) { 
    Log.d(TAG, String.format("tbm 162; (0x%08x) (%s) updating UI", 
          System.identityHashCode(this), 
          this)); 

    if (mView == null || bean == null) { 
     return; 
    } 

    if (bean.getBattery() != null) { 
     TextView battery_info = (TextView) mView.findViewById(R.id.battery_field); 
     battery_info.setText(String.format("%s%%", bean.getBattery().getPercentage())); 
    } 

    ImageView burnin_view = (ImageView) mView.findViewById(R.id.burnin_flag_image); 
    if (bean.isBurninComplete()) { 
     burnin_view.setImageResource(R.drawable.ic_flag_burnin_complete); 

    } else { 
     burnin_view.setImageResource(R.drawable.ic_flag_burnin_incomplete); 

    } 

    Program program = bean.getProgram(); 
    Program new_program = bean.getPendingProgram(); 

    TextView current_program_view = (TextView) mView.findViewById(R.id.current_program_field); 
    current_program_view.setBackgroundColor(mTransparentColor); 

    if (new_program == null) { 
     if (program == null) { 
      return; 
     } 

     current_program_view.setText(program.toString()); 

    } else if (program == null || program.equals(new_program)) { 
     current_program_view.setText(new_program.toString()); 

    } else { 
     current_program_view.setText(String.format("%s -> %s", program, new_program)); 
     current_program_view.setBackgroundColor(mProgramBackgroundColor); 

    } 

} 

を編集:

でも奇妙、フラグメントであっても、それ自体の中にIDを変更します。

DetailActivityFragment: tbm 065; (0x06a9e492) (DetailActivityFragment{6a9e492 #0 id=0x7f0d0075}) in attach 
DetailActivityFragment: tbm 104; (0x06a9e492) (DetailActivityFragment{6a9e492 #0 id=0x7f0d0075}) in onCreateView 
DetailActivity: tbm 463; got fragment: (0x06a9e492) (DetailActivityFragment{6a9e492 #0 id=0x7f0d0075}) (invisible) 
DetailActivityFragment: tbm 162; (0x068d3e1a) (DetailActivityFragment{68d3e1a}) updating UI 

したがって、onAttachとonCreateViewの0x06a9e492です(アクティビティが受け取る参照)が、updateUI内の0x068d3e1aは頑固なものです。

+0

カスタムのupdateUI方法を投稿することができますか? – harshitpthk

答えて

0

多くの調査の結果、誤ったフラグメントを含むアクティビティ内のフィールドがそのアクティビティへの参照を保持していたことがわかりました。 現在のアクティビティインスタンスを渡すようにフィールドを変更すると(フィールドの外部アクティビティへの暗黙の参照を保持するため)、問題が修正されました。私は断片的なIDが「アクティブ」であってもどのように変化するかに関してはやや混乱していますが、少なくとも私は進歩を遂げることができます。

これは多くの役に立ちました:http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html。私は最初に一種の漏れであると問題を見つけませんでした。

が効果的に、これは(オリジナル、誤った)コードだった:

DetailActivity 
    ... 
    some_field = new Listener() { 
     // The outer activity is retained, causing its fragment to be (partially?) re-used. 
     onSomeEvent() { 
      Toast.makeText(DetailActivity.this, "Got Some Event", ...).show(); 
     } 
    }; 
    ... 

そして新しい、作業コードよりのようである:

DetailActivity 
    ... 
    some_field = ListenerWithActivity.getInstance(this); 
    ... 

ListenerWithActivity: 

    public static ListenerWithActivity getInstance(Activity activity) { 
     ListenerWithActivity existing = getExisting(); 
     if (existing == null) { 
      existing = new ListenerWithActivity(); 
     } 

     existing.setActivity(activity); 
     return existing; 
    } 

    public void onSomeEvent() { 
     Toast.makeText(getActivity(), "Got Some Event", ...).show(); 
    }