2017-06-07 6 views
-1

注入フィールドにアクセスしようとすると、アクセスされたフィールドがnullであるため、アプリケーションがクラッシュすることはまれです。私はそれを再現する方法がなく、それはまず起こるはずではありません。 これがなぜ起こるのか、それを避ける方法はありますか?null注入フィールドのまれな発生

フィールドはフラグメント内に注入されている:

public class MyFragment extends Fragment { 
    @Inject StubManager mStubManager; 
    .... 
    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Application.getAppComponent().inject(this); 
    } 

    @Override 
    public void onPrepareOptionsMenu(Menu menu) { 
     super.onPrepareOptionsMenu(menu); 
     .... 
     menu.findItem(R.id.item_id) 
      .setEnabled(!mStubManager.isRunning()); 
    } 
} 

アプリのコンポーネントは以下のように見える、とアプリケーションクラスで初期化されます。

@Singleton 
@Component(modules = { 
     MyModule.class 
}) 
public interface AppComponent { 
    StubManager stubManager(); 

    void inject(MyFragment target); 
} 
+0

あなたのフィールドが '@ Nullable'でない場合、Daggerがそれを注入した後に' null'にならないでしょう。注入が完了する前にフィールドにアクセスした場合、これがヌルになる唯一の方法であるため、注入をいつ呼び出すのかを確認する必要があります。 –

+0

'@Inject StubManager mStubManager; – EpicPandaForce

+0

@EpicPandaForce私は質問を修正しましたので、今はもっと明確にすべきです。 –

答えて

2

はへごinjectコールを移動onAttachを呼び出してからsuperを呼び出してください。 Davidとして


あなたはダガーが正常にほとんどの時間を注入NULL可能フィールド@非を持っている場合、それはダガーのバグそうではなく、AndroidのライフサイクルやJavaマルチスレッドの1、in the commentsを述べました。私は前者がここで起こっていると推測しています。

私は断片が保証されていないことを示唆しているコードやドキュメント、anecdotally there seem to be cases where the options menu is prepared before onCreateでぶっきらぼう確かな理由、および(同様menu docsなど)FragmentManagerActivityのためのAndroidのオープンソースコードをチラッと見ていないけどアクションバーが表示されている限り、オプションメニューは開いていると見なされます。もしそうなら、これは注入されたフィールドからnullの値を読み取る場合です。これは、オプションボタン(ActionBarを使用していない場合)を開いたり、ホームボタンを使用したり、アクティビティからナビゲートするための通知をクリックしたり、アクティビティに戻ったりすることでテストできます。フラグメント化し、そのオプションメニューを再作成します。開発オプション「アクティビティを保持しない」を有効にすると、Activityが破棄されるメモリの負荷をシミュレートすることができます。これは、比較的ランダムで、ユーザーのデバイスではまれではありません。

私はあなたの注入があまりにも遅を起きても疑う:dagger.androidためのドキュメントはinjecting in onAttach before the call to super.onAttachを示唆するような、そのonAttach is called before onCreate is calledに注意してください。フラグメントが基本フラグメントクラスから継承されている場合は、これは最も初期の、最も一貫性のある、推奨された場所です。スーパークラスにはonCreateまたはで使用するフィールドがある場合は、nullinjectはどこにあるかを呼び出します。

+0

あなたは完全に正しいですが、唯一のことは、** onAttach **の前に** onPrepareOptionsMenu **が呼ばれることさえ、私たちが適用した特定のハックのためです。だから私はそこに注射するでしょう。ありがとう:) –

関連する問題