2017-06-20 14 views
8

Yeni Mimari Bileşenleri kullanmaya çalışıyorum ama aynı zamanda hantal olmak için hala yeni ve bazı şeyleri kaçırıyorum.Dagger2'yi yeni Android Architecture Bileşenleri ile düzgün bir şekilde nasıl kullanacaksınız?

Aşağıdaki kodla bir NullPointerException alıyorum, nereden bulamıyorum. Ayrıca düzeltmem veya iyileştirmem gereken başka bir şey varsa lütfen öneriniz.

KODU: ViewModel

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; 
    } 
} 

Depo

@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 Fabrikası

@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 MainActivity olarak O

@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); 
} 

:

@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

Etkinliğinizin onCreate in InjectorClass.inject (this) denen var mı? –

+0

@OrestSavchak, hayır ben havan't, ne 'InjectorClass' nedir – Relm

+0

ViewModelFactory örneğini nerede oluşturuyorsunuz? –

cevap

1

Sorun, NPE'nin önerdiği gibi MainActivity öğenizin içinde sıfır olan ViewModelFactory örneğinden kaynaklanır. Bu, büyük olasılıkla ViewModelFactory'un düzgün bir şekilde enjekte edilmemesi, dolayısıyla null olarak kalması gerçeğinden kaynaklanmaktadır.

MainActivity: Sen DI sınıflarının en bakmak olabilir

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; 
    } 
} 

kullanılıyor Orest yorumların içine anlaşılacağı gibi MainActivity düzgün AppModule gelen enjekte olduğundan, emin olmak gerekir İlgili bir soruda daha önce AndroidInjector<android.app.Activity> cannot be provided without an @Provides- or @Produces-annotated method adresinde yayınladım ve bu kurulumun size yardımcı olup olmadığını görün.

İlgili konular