如何使用匕首注入匿名内部类?

时间:2014-01-22 13:14:36

标签: java anonymous-inner-class dagger

它是否可以注入一个匿名类?我遇到以下错误:

  

java.lang.IllegalArgumentException:没有为members / com.acme.MyFragment $ 1注册注入。您必须将其显式添加到其中一个模块的“injects”选项中。

示例:

public class MyFragment extends Fragment {

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

        new MyTrask(getActivity()) {
            protected void onPostExecute(String result) {
                // Stuff
            }
        }.execute();
    }
}

public class MyTask extends AsyncTask<Void, Void, String> {

    @Inject
    UserApi userApi;

    public MyTask(Context context) {
        App.getInstance().inject(this);
    }

    @Override
    protected String doInBackground(Void... params) {
        return "Hello World!";
    }
}

2 个答案:

答案 0 :(得分:8)

您应该将AsyncTask注入MyFragment而不是使用“new MyTask(..)”。 MyTask构造函数应该使用UserApi实例和Context对象,该对象可以由模块提供,代码类似于;

  /**
   * The application module.
   *
   * @param context The context.
   */
  public MyModule(final Context context) {
    this.context = context.getApplicationContext();
  }

  /**
   * Provides context.
   *
   * @return the application context.
   */
  @Provides @Singleton Context provideContext() {
    return context;
  }

您的片段代码应该是这样的;

public class MyFragment extends Fragment {
    @Inject Provider<MyTask> myTaskProvider;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        inject(this);
        myTaskProvider.get().execute();
    }
}

你的AsyncTask API应该是;

@Inject 
public MyTask(Context context, UserApi userApi) { }

注意我使用了Provider来注入AsyncTask。这是必要的,以避免类似于“您只能执行一次任务”的异常,如果您多次针对同一个AsyncTask对象调用execute,则会遇到异常。然后,在模块MyFragment注释参数下注册injects = { }

答案 1 :(得分:0)

您无法注入匿名类。但你可以注入片段,它将在匿名类中可见,在这种情况下是AsyncTask。

public class MyFragment extends Fragment {

 @Inject
 UserApi userApi;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    App.getInstance().inject(this);

    new MyTrask() {
        protected void onPostExecute(String result) {
            // Stuff
        }
    }.execute();
  }
}

 public class MyTask extends AsyncTask<Void, Void, String> {

 @Override
 protected String doInBackground(Void... params) {
    userApi.callAnyMethod(); // use userApi here
    return "Hello World!";
 }
}