首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Dagger 2 (NullPointerException)活动中传递应用程序上下文

在Dagger 2 (NullPointerException)活动中传递应用程序上下文
EN

Stack Overflow用户
提问于 2018-03-28 01:03:59
回答 2查看 915关注 0票数 1

我正在尝试通过Dagger 2中的应用程序上下文活动。任何帮助都是非常感谢的!最后,我提供了我的Logcat控制台。

格雷戈里·奎克的项目给了我同样的问题,如下面最后的错误部分所示。https://github.com/gk5885/dagger-android-sample

我也尝试在这个问题上进行改进:https://github.com/google/dagger/issues/832

什么都没用!我知道,实际上,在活动中不需要应用程序上下文,因为活动中有活动上下文。但我很想知道如何在任何类(例如,活动)中传递应用程序上下文?

代码语言:javascript
复制
apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    buildToolsVersion "27.0.3"

    testBuildType "staging"

    testOptions {
        reportDir "$rootDir/test-reports"
        resultsDir "$rootDir/test-results"
        unitTests {
            returnDefaultValues true
            all {
                // Sets JVM argument(s) for the test JVM(s).
                jvmArgs '-XX:MaxPermSize=256m'

                // You can also check the task name to apply options to only the tests you specify.
                if (it.name == 'testDebugUnitTest') {
                    systemProperty 'debug', 'true'
                }
            }
        }
    }
    defaultConfig {
        applicationId "com.nexuslab.forensics.grr.nanny"
        minSdkVersion 21
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        testHandleProfiling true
        testFunctionalTest true
    }
    signingConfigs {
        debugKey {
            keyAlias 'android'
            keyPassword 'android'
            storeFile file('keys/platform.jks')
            storePassword 'android'
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debugKey
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        staging {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    configurations.all {
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    compileOnly 'org.projectlombok:lombok:1.16.20'
    annotationProcessor 'org.projectlombok:lombok:1.16.20'
    //java vm based test
    testImplementation 'org.hamcrest:hamcrest-core:1.3'
    testImplementation 'junit:junit:4.12'
    testImplementation 'org.powermock:powermock-api-mockito:1.6.5'
    testImplementation 'org.powermock:powermock-module-junit4-rule-agent:1.6.5'
    testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.5'
    testImplementation 'org.powermock:powermock-module-junit4:1.6.5'
    testImplementation 'org.mockito:mockito-core:2.15.0'
    //instrumentation test
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    androidTestImplementation 'com.android.support:support-annotations:27.1.0'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test:rules:1.0.1'
    androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
    androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3'
    androidTestImplementation 'junit:junit:4.12'
    //dagger 2
    implementation 'com.google.dagger:dagger:2.14.1'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1'
    //to enable DaggerActivity, DaggerBroadcastReceiver, DaggerFragment etc classes
    implementation 'com.google.dagger:dagger-android:2.14.1'
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.14.1'
    //support libraries with dagger 2
    implementation 'com.google.dagger:dagger-android-support:2.14.1'
    implementation 'com.android.support:support-v4:27.1.0'
}

应用程序类(NannyApplication.java)

代码语言:javascript
复制
package com.nexuslab.forensics.grr.nanny;

import android.app.Application;

import com.nexuslab.forensics.grr.nanny.di.component.DaggerNannyApplicationComponent;
/**
 * Created by gaute on 3/25/18.
 */

public class NannyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        DaggerNannyApplicationComponent.builder().create(this);
    }
}

MainActivity.java (这里,我想从NannyApplication.java注入上下文)

代码语言:javascript
复制
package com.nexuslab.forensics.grr.nanny;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

import javax.inject.Inject;

/**
 * @author gaute
 */
public class MainActivity extends AppCompatActivity {

    @Inject
    NannyApplication nannyApplication;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Utils.schedule(nannyApplication, HeartbeatService.class, Constants.HEARTBEAT_CHECK_INTERVAL);
        finishAndRemoveTask();
    }

}

(NannyApplicationComponent.java) 匕首应用组件

代码语言:javascript
复制
package com.nexuslab.forensics.grr.nanny.di.component;


import com.nexuslab.forensics.grr.nanny.NannyApplication;
import com.nexuslab.forensics.grr.nanny.di.module.NannyApplicationModule;

import javax.inject.Singleton;

import dagger.Component;
import dagger.android.AndroidInjector;

/**
 * Created by gaute on 3/25/18.
 */

@Singleton
@Component(modules = NannyApplicationModule.class)
public interface NannyApplicationComponent extends AndroidInjector<NannyApplication> {

    @Component.Builder
    abstract class Builder extends AndroidInjector.Builder<NannyApplication> {
    }
}

(NannyApplicationModule.java) 应用模块

代码语言:javascript
复制
package com.nexuslab.forensics.grr.nanny.di.module;

import com.nexuslab.forensics.grr.nanny.NannyApplication;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import dagger.android.AndroidInjectionModule;

@Module(includes = AndroidInjectionModule.class)
public class NannyApplicationModule {

    @Provides
    @Singleton
    NannyApplication getNannyApplication(NannyApplication nannyApplication) {
        return nannyApplication;
    }

}

错误,我得到了

代码语言:javascript
复制
03-27 19:08:37.107 10619-10619/com.nexuslab.forensics.grr.nanny E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.nexuslab.forensics.grr.nanny, PID: 10619
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nexuslab.forensics.grr.nanny/com.nexuslab.forensics.grr.nanny.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] com.nexuslab.forensics.grr.nanny.NannyApplication.databaseList()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3046)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1688)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6809)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] com.nexuslab.forensics.grr.nanny.NannyApplication.databaseList()' on a null object reference
        at com.nexuslab.forensics.grr.nanny.MainActivity.onStart(MainActivity.java:26)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1412)
        at android.app.Activity.performStart(Activity.java:7015)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2909)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3046) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1688) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6809) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

在下面的活动中,我不能使用任何类型的构造函数注入。

代码语言:javascript
复制
 private NannyApplication nannyApplication;

    @Inject
    public MainActivity() {
        this.nannyApplication = nannyApplication;
    }

所以我才用注射法:

代码语言:javascript
复制
@Inject NannyApplication nannyApplication; //Problem here
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-28 21:47:20

这是一个可行的解决办法。

Rule:对于任何服务组件T,我们必须将T的实例作为seedInstance提供到AndroidInjector.Builder<T>类中。这意味着如果在MainActivity的生命周期回调中执行AndroidInjector.inject(this),则在AndroidInjector.Builder<MainActivity>类中初始化seedInstance = mainActivity

这个AndroidInjector.Builder<MainActivity>,您将在DaggerNannyApplicationComponent's Builder内部类中看到,因为在NannyApplicationComponent中,您将编写

代码语言:javascript
复制
@Component.Builder /* Simply tells this Builder is DaggerNannyApplicationComponent’s inner Builder class */
    abstract class Builder extends AndroidInjector.Builder<NannyApplication> {
    } 

Github中的示例项目:https://github.com/uddhavgautam/Dagger2ApplicationContextToActivity

NannyApplicationComponent.java

代码语言:javascript
复制
@Singleton
@Component(modules = {
        AndroidSupportInjectionModule.class /* it makes Dagger generates DaggerNannyApplicationComponent */,
        ApplicationBindingModule.class /* it generats AndroidInjector.Builder<MainActivity>, which
        is used to inject requested dependencies by MainActivity */
})
public interface NannyApplicationComponent extends AndroidInjector<NannyApplication> {

    @Component.Builder /* Simply tells this Builder is DaggerNannyApplicationComponent’s inner Builder class */
    abstract class Builder extends AndroidInjector.Builder<NannyApplication> {
    }
}

ApplicationBindingModule.java

代码语言:javascript
复制
 @Module
    public interface ApplicationBindingModule {

/* These two lines, actually, makes Dagger generates ApplicationBindingModule_MainActivity class */
        @ContributesAndroidInjector
        MainActivity mainActivity();
    }

NannyApplicationModule.java

代码语言:javascript
复制
@Module
public class NannyApplicationModule {
}

MainActivity.java

代码语言:javascript
复制
//MainActivity is a consumer because it has requested nannyApplication using @Inject annotation
public class MainActivity extends DaggerAppCompatActivity {

    @Inject
    NannyApplication nannyApplication /* You got the ApplicationContext */;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // AndroidInjection.inject(this); 
/* if Consumers want MainActivity instance then uncomment AndroidInjection.inject(this) line. Doing this makes MainActivity Consumer as well as Service component. Because it consumed nannyApplication but it has also provided (serviced) it's instance to the external world */
    }

    @Override
    protected void onStart() {
        super.onStart();
        //check nannyApplication
        Log.i("Cls-loader: ", nannyApplication.getClassLoader() + "");
    }
}

NannyApplication.java

代码语言:javascript
复制
public class NannyApplication extends DaggerApplication {

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

    /**
     * applicationInjector() gets called inside onCreate()
     */
    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        return DaggerNannyApplicationComponent
                .builder()
                .create(this);
    }
}
票数 0
EN

Stack Overflow用户

发布于 2018-03-28 06:23:32

在应用程序类中做一些更改如下所示..。

代码语言:javascript
复制
public class NannyApplication extends Application {
private DaggerNannyApplicationComponent daggerNannyApplicationComponent;

@Override
public void onCreate() {
    super.onCreate();
    daggerNannyApplicationComponent.builder().create().build();
}

public DaggerNannyApplicationComponent getComponent() {
    return daggerNannyApplicationComponent;
}

}

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49524544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档