Как ввести анонимный внутренний класс с помощью кинжала?

Можно ли ввести анонимный класс? У меня следующая ошибка:

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 ответа

Решение

Вы должны ввести AsyncTask в MyFragment вместо того, чтобы использовать "новый 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. Это необходимо, чтобы избежать исключений, похожих на "Вы можете выполнить задачу только один раз", которые вы получили бы, если бы позвонили execute против одного и того же объекта AsyncTask более одного раза. Вы тогда регистрируетесь MyFragment под вашим модулем injects = { } аргументы аннотации.

Вы не можете ввести в анонимный класс. Но вы можете сделать инъекцию во Fragment, и он будет виден для анонимного класса, в данном случае 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!";
 }
}
Другие вопросы по тегам