2017-06-20 37 views
8

我正在嘗試使用新的體系結構組件,但我對於匕首還是一個新東西,而且我錯過了一些東西。如何正確使用Dagger2與新的Android體系結構組件

用下面的代碼,我得到一個NullPointerException,無法找到位置。 如果還有其他需要修復或改進的地方,請提出建議。

CODE: 視圖模型

public class PostsVM extends ViewModel { 
    private LiveData<StoryPost> post; 
    private Repository   repository; 

    @Inject 
    public PostsVM(Repository repository) { 
     this.repository = repository; 
    } 

    public void init() { 
     if (this.post != null) { 
      return; 
     } 
     post = repository.getPosts(); 
    } 

    public LiveData<StoryPost> getPost() { 
     return post; 
    } 
} 

@Singleton 
public class Repository { 
    private final MutableLiveData<StoryPost> data = new MutableLiveData<>(); 

    public LiveData<StoryPost> getPosts() { 
     // 
     new GetUser(post.getUid()) { 
      @Override 
      public void onSuccess(@NonNull User user) { 
       // this is where I setValue// 
       data.setValue(post); 
     } 

     @Override 
     public void onError() { 

     } 

     @Override 
     public void userNotFound() { 

     } 
    }; 
    return data; 
    } 
} 

辛格爾頓廠

@Singleton 
public class ViewModelFactory implements ViewModelProvider.Factory { 
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators; 

@Inject 
public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) { 
    this.creators = creators; 
} 

@SuppressWarnings("unchecked") 
@Override 
public <T extends ViewModel> T create(Class<T> modelClass) { 
    Provider<? extends ViewModel> creator = creators.get(modelClass); 
    if (creator == null) { 
     for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) { 
      if (modelClass.isAssignableFrom(entry.getKey())) { 
       creator = entry.getValue(); 
       break; 
      } 
     } 
    } 
    if (creator == null) { 
     throw new IllegalArgumentException("unknown model class " + modelClass); 
    } 
    try { 
     return (T) creator.get(); 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 

}

DAO

@Dao 
public interface PostDao { 
    @Query("SELECT * FROM posts ORDER by time DESC") 
    LiveData<List<StoryPost>> getAll(); 

    @Query("SELECT * FROM posts WHERE id = :id") 
    LiveData<List<StoryPost>> getPost(String id); 

    @Insert(onConflict = OnConflictStrategy.REPLACE) 
    @NonNull 
    void insert(StoryPost... posts); 

    @Delete 
    void delete(StoryPost post); 

    @Update 
    void update(StoryPost post); 
} 

然後在MainActivity:

@Inject public ViewModelFactory factory; 
//... 
//*onCreate* 

PostsVM model = ViewModelProviders.of(this, factory).get(PostsVM.class); 
model.init(); 
final Observer<StoryPost> observer = post -> storyAdapter.insert(post); 
model.getPost().observe(this, observer); 

logcat的

... java.lang.NullPointerException: Attempt to invoke interface method 
'android.arch.lifecycle.ViewModel android.arch.lifecycle.ViewModelProvider 
$Factory.create(java.lang.Class)' on a null object reference 
                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2479) 
                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2539) 
                       at android.app.ActivityThread.access$900(ActivityThread.java:168) 
                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1378) 
                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                       at android.os.Looper.loop(Looper.java:150) 
                       at android.app.ActivityThread.main(ActivityThread.java:5665) 
                       at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:799) 
                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:689) 
                      Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.arch.lifecycle.ViewModel android.arch.lifecycle.ViewModelProvider$Factory.create(java.lang.Class)' on a null object reference 
                      at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:128) 
                       at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:96) 
                       at com.aollay.smartpaper.MainActivity.bindDatabase(MainActivity.java:238) 
                       at com.aollay.smartpaper.MainActivity.populateNews(MainActivity.java:233) 
                       at com.aollay.smartpaper.MainActivity.config(MainActivity.java:159) 
                       at com.aollay.smartpaper.MainActivity.onCreate(MainActivity.java:74) 
                       at android.app.Activity.performCreate(Activity.java:6372) 
                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110) 
                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2432) 
+0

你有沒有在你的活動的onCreate中調用InjectorClass.inject(this)? –

+0

@OrestSavchak,不,我不知道,什麼'InjectorClass' – Relm

+0

我的意思是你在哪裏創建ViewModelFactory實例? –

回答

1

問題是由於您的MainActivity內部的ViewModelFactory實例爲空造成的,如NPE所示。這本身很可能是由於ViewModelFactory未被正確注入而導致的,因此保持爲空。作爲奧列斯特提出的意見裏面,你需要確保的是,MainActivity被正確地從您的AppModule注入:

MainActivity:

public class MainActivity extends AppCompatActivity implements HasSupportFragmentInjector 
{ 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
      AndroidInjection.inject(activity); 
      super.onCreate(savedInstanceState); 
    } 

    // if your Activity also has Fragments which need to be injected 

    @Inject 
    DispatchingAndroidInjector<Fragment> androidInjector; 

    @Override 
    public DispatchingAndroidInjector<Fragment> supportFragmentInjector() 
    { 
     return androidInjector; 
    } 
} 

你可以看看大多數DI類的使用在我早些時候發佈在AndroidInjector<android.app.Activity> cannot be provided without an @Provides- or @Produces-annotated method的相關問題中,看看這個設置是否可以幫助你。

相關問題