2017-07-20 4 views
0

私は、TabLayoutといくつかのフラグメントでMainActivityを持っています。アプリケーションが作成されると、すべて正常に動作しますが、アプリケーションがバックグラウンドで実行されて戻り、nullpointer例外が発生します。フラグメントのOnCreateViewメソッドで作成したオブジェクトはnullです。私が申請に戻ると、なぜそれらのオブジェクトはnullですか?

これは私のFragmentPagerAdapterクラスです:私のMainActivityで

public class SectionsPagerAdapter extends FragmentPagerAdapter { 
    private FragmentStrobe fragmentStrobe = null; 
    private FragmentFlashLight fragmentFlashLight = null; 
    private FragmentDisco fragmentDiscoLight = null; 
    private FragmentShaking fragmentShaking = null; 
    private FragmentPoliceLights fragmentPoliceLights = null; 

    public SectionsPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     switch (position) { 
      case 0: 
       if(fragmentDiscoLight == null){ 
        fragmentDiscoLight = new FragmentDisco(); 
       } 
       return fragmentDiscoLight; 
      case 1: 
       if(fragmentStrobe == null){ 
        fragmentStrobe = new FragmentStrobe(); 
       } 
       return fragmentStrobe; 
      case 2: 
       if(fragmentFlashLight == null){ 
        fragmentFlashLight = new FragmentFlashLight(); 
       } 
       return fragmentFlashLight; 
      case 3: 
       if(fragmentShaking == null){ 
        fragmentShaking = new FragmentShaking(); 
       } 
       return fragmentShaking; 
      case 4: 
       if(fragmentPoliceLights == null){ 
        fragmentPoliceLights = new FragmentPoliceLights(); 
       } 
       return fragmentPoliceLights; 
      default: 
       return null; 
     } 
    } 

    @Override 
    public int getCount() { 
     return 5; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return null; 
    } 
} 

、私は破片の上にあるいくつかのボタンがあります。このボタンをクリックすると、フラグメント内のメソッドを呼び出しています。

private void initializeButtonStart(){ 
    buttonStart = (Button) findViewById(R.id.start); 

    buttonStart.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      myPreferences.setBoolPreferences(MyPreferences.MY_PREFS_START, 
        !myPreferences.getBoolPreferences(MyPreferences.MY_PREFS_START, MyPreferences.MY_PREFS_START_DEFAULT)); 

      setIcon(); 

      ((FragmentInterface) mSectionsPagerAdapter.getItem(tabLayout.getSelectedTabPosition())).onRunPermissionChanged(); 
     } 
    }); 
} 

ここには1つのフラグメントのコードがあります。

public class FragmentDisco extends Fragment implements FragmentInterface { 

private static final double IMAGE_RATIO = 1.08158; 

private View viewBackground; 

private View rootView; 

private ImageView imageViewDiscoBall; 

private Bitmap bitmap; 

private Disco disco; 

private MyPreferences myPreferences; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    rootView = inflater.inflate(R.layout.fragment_discolight, container, false); 

    disco = new Disco(getContext()); 

    myPreferences = new MyPreferences(getContext()); 

    bitmap = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.disco_start); 

    initializeView(); 
    initializeImageView(); 

    return rootView; 
} 

private void initializeView(){ 
    viewBackground = getActivity().findViewById(R.id.viewMain); 
} 

private void initializeImageView(){ 
    imageViewDiscoBall = (ImageView) rootView.findViewById(R.id.discoBall); 

    imageViewDiscoBall.setImageBitmap(bitmap); 

    imageViewDiscoBall.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
     @Override 
     public void onGlobalLayout() { 
      imageViewDiscoBall.getViewTreeObserver().removeOnGlobalLayoutListener(this); 

      int width = imageViewDiscoBall.getWidth(); 
      int resultHeight = (int)((float) width * IMAGE_RATIO); 

      ViewGroup.LayoutParams layoutParams = imageViewDiscoBall.getLayoutParams(); 
      layoutParams.height = resultHeight; 
      imageViewDiscoBall.setLayoutParams(layoutParams); 
     } 
    }); 
} 


@Override 
public void onResume() { 
    super.onResume(); 
} 

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

    stopDisco(); 
} 

@Override 
public void onTabSelected() { 
    if(myPreferences == null || imageViewDiscoBall == null || viewBackground == null || disco == null){ 
     return; 
    } 

    if(myPreferences.getBoolPreferences(MyPreferences.MY_PREFS_START, MyPreferences.MY_PREFS_START_DEFAULT) && 
      (myPreferences.getIntPreferences(MyPreferences.MY_PREFS_CURRENT_FRAGMENT, MyPreferences.MY_PREFS_CURRENT_FRAGMENT_DEFAULT) == MainActivity.FRAGMENT_DISCO)){ 
     disco.start(viewBackground, imageViewDiscoBall); 
    } 
} 

@Override 
public void onTabUnselected() { 
    stopDisco(); 
} 

@Override 
public void onRunPermissionChanged() { 
    if(myPreferences == null || imageViewDiscoBall == null || viewBackground == null || disco == null){ 
     System.out.println("NULLL !!!!!!"); 
     return; 
    } 

    if(myPreferences.getBoolPreferences(MyPreferences.MY_PREFS_START, MyPreferences.MY_PREFS_START_DEFAULT)){ 
     disco.start(viewBackground, imageViewDiscoBall); 
    } else { 
     stopDisco(); 
    } 
} 

private void stopDisco(){ 
    if(disco == null || imageViewDiscoBall == null || viewBackground == null){ 
     return; 
    } 

    disco.stop(); 

    viewBackground.setBackgroundColor(Color.TRANSPARENT); 
    imageViewDiscoBall.setImageBitmap(bitmap); 
} 
} 

ほとんどの場合、バックグラウンドから戻ったとき、フラグメントで呼び出されたメソッドは "NULL !!!"という文字を表示します。これをどうすれば解決できますか?

+0

「myPreferences」は何ですか?あなたはそれを宣言した方法を示していませんでした。また、デバッグを使用して、exactylがnullであるかどうかを判断することもできます。 –

+0

質問を編集しました。今度はFragmentクラス全体を追加しました。 – tomhogenkamp

答えて

0

アンドロイドはメモリ容量と消費電力を節約するためにメモリからデータを消去しています。これは、OSがバックグラウンドタスクをクリアしなければならない低メモリデバイス(バックグラウンドが設定 - >デベロッパー設定 - >あなたのデバイスのバックグラウンドプロセス限界に制限されている場合も参照してください)が正常に動作するためには、フォアグラウンドアプリケーションでは、メモリなどのリソースが十分に確保されていることを確認してください。彼らは、彼らが使用される画像オブジェクトをロードするように必要とされる場所

だからこれを防ぐために、

  • しかスコープに大きなオブジェクトを作成します。
  • savedInstancesを使用すると、アクティビティを以前の状態に戻すことができます。
  • savedInstancesを使用するには、オブジェクトをシリアライズ可能にする必要があります。
+0

答えをありがとう、私は保存されたインスタンスにフラグメントを保存する必要がありますか?多分あなたはそれを明確にすることができますか? – tomhogenkamp

+0

No. フラグメントのようなものは、アダプタのgetFragmentメソッドで作成する必要があります。それ以外はどこにもない。 これにより、より軽量なメモリアプリケーションを作成できます。 –

+0

ここにあなたがすべきことがあります。アプリケーションがどの部分で作業しているかなどの変数を識別する進捗状況を確認します。 OnPause()メソッドでは、この変数をsavedInstancesに保存します。 'OnResume()'メソッドでは、アンドロイドはこれらの変数を返します。したがって、アクティビティの状態を再開します。フラグメントにも同じことが起こり、現在の状態を保存して再開します。 たとえば、リストビューを含む第3のタブにあり、11番目のアイテムで何かをしていました。したがって、3,11、および作業識別子をsavedInstancesに保存し、再開すると、3番目のタブに移動し、11番目のアイテムに行くようにフラグメントを指示します。 –

0

機能をonCreate()からonResume()メソッドに移動することをお勧めします。 onCreate()メソッドはアクティビティの作成時にのみ呼び出され、onResume()はアクティビティに戻るときに常に呼び出されます(破棄された場合は除外されます)。詳細はこちらをご覧くださいhttps://developer.android.com/guide/components/activities/activity-lifecycle.html

関連する問題